Problem/Motivation
Government and enterprise users require data visualization tools to meet strict accessibility standards (Section 508 and WCAG 2.1 AA/AAA). Currently, the Charts module generates visual-only charts (SVG or Canvas) that can be "black boxes" to screen reader users. There is no standardized way to provide a text-based data alternative (like an HTML table) or to attach essential descriptive metadata (visible captions and screen-reader summaries) directly to the chart element.
Steps to reproduce
- Create a chart using any supported library (e.g., Highcharts*, Chart.js) via Views or the Charts API.
- Inspect the output: the chart is rendered without a semantic container linking it to a description.
- Attempt to add a visible caption or a hidden summary for AT users; there are no configuration options for this.
- Attempt to view the underlying data as a screen reader user; the data is only available within the visual graphic, making it inaccessible.
Proposed resolution
We should implement a comprehensive accessibility suite that works across all charting libraries by handling accessibility at the Drupal render layer, rather than relying on library-specific plugins.
- Semantic Wrapper: Charts should be wrapped in a
<div role="figure">witharia-labelledbyandaria-describedbyattributes to strictly associate descriptions with the graphic. - Data Table Alternative: A new service (ChartTableBuilder) should automatically transform chart data into an accessible HTML table. This will ensure all users can access the precise data points.
- User Control: Site builders should be able to toggle the data table's visibility (Collapsible, Always Visible, Screen Reader Only, or Disabled).
- Descriptive Fields: Need to add "Figure Caption" (visible) and "Chart Summary" (visually hidden) fields to the configuration.
- Token Support: Captions and summaries should support global, entity, and Views tokens, allowing for dynamic descriptions (e.g., "Monthly Sales for [node:title]").
Remaining tasks
- Verify that the ChartTableBuilder service correctly parses and formats data structures across all supported libraries (Highcharts, Google, Chart.js, etc.) and complex types (scatter, heatmap, candlestick).
- Verify that existing sites remain unaffected (no visual regressions) unless they explicitly opt-in by configuring the new features.
- Update the module documentation and charts.api.php to reflect the new render element properties.
- Conduct a formal accessibility review against the latest ADA/508 standards to ensure the new markup meets compliance targets.
User interface changes
- Chart Configuration (Views/Blocks/Element): Added a "Figure caption" textarea (supports HTML) and a "Chart summary" textarea.
- Display Settings: Added a "Show data table below chart" checkbox.
- Table Configuration: When the table is enabled, new options appear to control its visibility state ("Collapsible details", "Always visible", "Screen reader only") and to assign custom CSS classes to the toggle button.
- Frontend: Charts now appear inside a semantic container. If enabled, a "View data table" button (or the table itself) appears below the chart.
API changes
- New Service: charts.table_builder (Drupal\charts\Service\ChartTableBuilder) is available for generating tables from chart render elements programmatically.
- Render Element: The chart element accepts new properties:
-
- #figure_caption: String or render array.
- #chart_summary: String.
- #display_data_table: Boolean.
- #accessible_table: String ('collapsible', 'visible', 'invisible', 'disabled').
- #accessible_table_button_class: String.
Data model changes
- Updated charts.schema.yml to include the new display settings fields (display_data_table, accessible_table, accessible_table_button_class, figure_caption, chart_summary).
- Existing configurations will need to be updated (via save) or handled via post-update hooks to pick up default values, though the code ensures backward compatibility by defaulting to disabled/empty if keys are missing.
| Comment | File | Size | Author |
|---|
Issue fork charts-3550972
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
mutasim al-shoura commentedComment #3
andileco commented@mutasim al-shoura - thank you for creating this ticket. If you are using Highcharts, here are my recommendations that don't require a patch:
*If you scroll to the bottom of https://www.highcharts.com/docs/accessibility/accessibility-module, you'll see that using the caption is a great option for the description, and the nice thing is that it gets included in the Chart export, too.
However, the above is really Highcharts-specific. Would you be interested in making a more generic solution, which would apply to all the libraries? You have a start to that in your patch.
By the way, if you could create a merge request, I would appreciate that over a patch, as it runs code checks and tests.
Comment #4
andileco commentedAdding the a11y tag.
Comment #6
andileco commentedComment #7
andileco commentedComment #8
andileco commentedComment #9
andileco commentedComment #10
andrewozoneI worked with @andileco today at the DrupalCon contribution day. We used Drupal Forge to spin up a Drupal CMS site, installed the Charts module, and tested the latest patch.
Critical Issue: Drupal CMS Compatibility
While testing with Drupal CMS and the Byte 1.0.2 theme, we encountered an error indicating a missing Twig template. This issue should be addressed to ensure the Charts module is fully compatible with the Drupal CMS ecosystem. @andileco has taken detailed notes on this bug.
Recommendation 1: Documentation & Authoring Guidelines
We recommend updating the module documentation to provide clear guidance and examples for new fields. Without this, content authors may provide duplicative or overly verbose descriptions.
Proposed Standards for Authors:
Additional Resources:
Recommendation 2: UI Description Updates
Update the description language for the new fields within the module interface to lead content authors directly to the updated documentation.
Recommendation 3: ARIA Attribute Usage
We suggest removing aria-labelledby in favor of aria-describedby. Using both can be too verbose for site visitors using assistive technology. Following HTML specs, aria-describedby is the more appropriate choice for these detailed descriptions.
Additional Feature Requests
Accessibility Enhancements
General UI
Captions: An optional field for data attribution and sources.
Comment #11
andileco commentedOK, some follow-ups:
I'm going to create the documentation page and a link from within the code as a separate, follow-on issue.
Going to follow up to this ticket with a Change Record, as the Twig template is changing.
Comment #12
andileco commentedI'm going to commit, but I wanted to list a few changes since the last review.
1) I added an aria label, as the element needs a name. The element comes from the chart title, but it's not grabbed from the rendered chart, it's grabbed from the settings.
2) I added tabindex=0 on the chart container to make it focusable so that the screen reader announces the "summary" text before moving to the table.
3) I added column and row scopes on the already semantic table.
4) I ensured that the caption in the table contains the chart title or a placeholder if no title has been set - otherwise it was ending abruptly.
5) I also returned to the original Twig template and moved the logic I had added into the .module file - this reduces the likelihood that something a user had done within Twig will break. That said, the next release will bump a minor version.
Comment #13
andileco commented