Chart accessibility.
Build charts that convey meaning beyond color and pointer interaction.
Chart meaning and alternative data
#Include the measurement and unit in the chart title, and explain key findings in the body. You can also provide numbers through an external HTML table or the shared facade's data table.
<figure aria-labelledby="trend-title" aria-describedby="trend-description">
<figcaption id="trend-title">Monthly visitors · Thousands</figcaption>
<p id="trend-description">Increased from 24 in January to 35 in March.</p>
<sy-chart id="trend" type="line" aria-label="Monthly visitor trend"></sy-chart>
<button id="show-data" type="button">Open data table</button>
</figure>
<script type="module">
await customElements.whenDefined('sy-chart');
const chart = document.querySelector('#trend');
chart.series = [{ name: 'Visitors', values: [24, 29, 35] }];
chart.xAxis = { kind: 'category', categories: ['Jan', 'Feb', 'Mar'] };
document.querySelector('#show-data').addEventListener('click', () => chart.showDataTable());
</script>Focus and interaction
#- Alternative input If clicking a point triggers an important app action, offer the same action through a button or table.
- Range selection Test controls such as Data Zoom and Navigator with the keyboard, and communicate the current range as text.
- Documentation navigation Example and option controls use native select and input elements. Navigate code tabs with arrow keys, Home, and End. From an API name, press Tab to reach the tooltip's copy button.
- Logo The brand mark is decorative. It is excluded from reading and tab order and does not block chart pointer input.
Color, contrast, and motion
#- Distinguish beyond color Combine series names, legends, marker shapes, and direct labels. Do not convey success or failure through color alone.
- Contrast Inspect text, axes, lines, and focus rings on light and dark backgrounds. Use custom logo assets that remain readable on both.
- Reduced motion Control animated using the operating system's prefers-reduced-motion setting.
const media = matchMedia('(prefers-reduced-motion: reduce)');
const chart = document.querySelector('#trend');
const syncMotion = () => { chart.animated = !media.matches; };
media.addEventListener('change', syncMotion);
syncMotion();
// On disposal: media.removeEventListener('change', syncMotion);