Chart Type-Specific Patterns

Permalink to "Chart Type-Specific Patterns"

General chart accessibility advice — “add a text alternative, provide a table, support the keyboard” — is right but incomplete, because each chart type encodes information differently. A pie chart encodes parts of a whole by angle; a stacked bar encodes totals and composition at once; a heatmap encodes a value by colour intensity across two dimensions; a histogram encodes shape; a candlestick encodes four values and a direction in one mark; a gauge encodes a value against a range and thresholds. Each encoding needs its own summary, its own table shape, its own keyboard model and its own way of not depending on colour.

This topic collects those patterns. The users most affected are screen reader users (who need the encoding in words and tables), colour-blind users (pie slices, heatmap intensities and red-green candles are colour-heavy), keyboard users (hover-only details) and users with cognitive disabilities (dense encodings with no summary). The failure this topic prevents is a chart that technically has a text alternative — “Pie chart of tickets by status” — but conveys none of what the chart type was chosen to show.

This topic belongs to virtualization, charts & dynamic data displays.

WCAG criteria in scope

Permalink to "WCAG criteria in scope"
Criterion Level Relevance to chart types
1.1.1 Non-text Content A Summaries that convey each chart type’s message
1.3.1 Info and Relationships A Tables shaped to the encoding
1.4.1 Use of Color A Slices, segments, bins and candles not colour-only
1.4.3 Contrast (Minimum) AA Labels on coloured marks and cells
1.4.11 Non-text Contrast AA Marks, separators and arcs at 3:1
2.1.1 Keyboard A Details available on focus
4.1.2 Name, Role, Value A meter semantics for gauges

Prerequisites

Permalink to "Prerequisites"
What each chart type encodes and how to say it Matrix of chart types — pie, stacked bar, heatmap, histogram, candlestick, gauge — against what they encode, the summary to write and the table shape. What each chart type encodes and how to say itEncodesSummary saysTable shapePie / donutParts of a wholeLargest and notable sharesCategory, value, shareStacked barTotals and compositionTotals and main componentCategories × series + totalHeatmapIntensity over 2 dimensionsHot spots and patternsRows × columns with valuesHistogramDistribution shapeCentre, spread, skew, outliersBins with countsCandlestickRanges and directionChange, high, lowPeriods with OHLCGaugeValue in a rangeValue, target, statusNone: meter semantics
The summary and table follow the encoding, not the chart's appearance.

ARIA & HTML spec reference

Permalink to "ARIA & HTML spec reference"
Element / attribute Valid values When to apply Common misuse
figure + heading + aria-describedby — Every chart with its summary Summary unconnected to the chart
role="img" + aria-label — Focusable marks (slices, bars, bands) Unnamed focusable paths
role="application" — 2D keyboard models (stacked bars, candles) Large regions; undocumented keys
table with headers — Data equivalents Images of tables
meter / role="meter" value, min, max, low, high, optimum Gauges progress for measurements
aria-valuetext Text Units and status Bare numbers
role="status" — Announcements during keyboard exploration Hover-driven announcements

Step-by-step implementation

Permalink to "Step-by-step implementation"

Step 1 — Identify the encoding

Permalink to "Step 1 — Identify the encoding"

Decide which of the six encodings the chart uses; that decides everything else.

const encoding = { pie: 'part-whole', stackedBar: 'composition', heatmap: 'intensity', histogram: 'distribution', candlestick: 'range-direction', gauge: 'bounded' }[type];

Step 2 — Summarise the encoding (SC 1.1.1)

Permalink to "Step 2 — Summarise the encoding (SC 1.1.1)"
summary = encoding === 'distribution' ? `Median ${med}; ${shape}; ${outliers.length} outliers.` : …;

Step 3 — Shape the table (SC 1.3.1)

Permalink to "Step 3 — Shape the table (SC 1.3.1)"
<table><caption>Revenue by quarter and product line</caption>… <th scope="col">Total</th></table>

Step 4 — Choose the keyboard model (SC 2.1.1)

Permalink to "Step 4 — Choose the keyboard model (SC 2.1.1)"

One-dimensional for pies, histograms and candles; two-dimensional for stacked bars and heatmaps; none for gauges.

const model = { 'part-whole': '1d', composition: '2d', intensity: '2d', distribution: '1d', 'range-direction': '1d', bounded: 'none' }[encoding];

Step 5 — Remove colour dependence (SC 1.4.1)

Permalink to "Step 5 — Remove colour dependence (SC 1.4.1)"

Direct labels for slices, separators and patterns for segments, values in heatmap cells, hollow and filled candles, status words for gauges.

.candle.up rect { fill: #ffffff; stroke: #155c38; } .candle.down rect { fill: #8a6000; }

Step 6 — Use native semantics (SC 4.1.2)

Permalink to "Step 6 — Use native semantics (SC 4.1.2)"
<meter min="0" max="10" low="7" high="9" optimum="0" value="8.4" aria-valuetext="8.4 of 10 GB, near limit"></meter>
From chart type to accessible chart Flow: identify the encoding, write a summary in its terms, build the table in its shape, choose the keyboard model, then remove colour dependence and apply native semantics. From chart type to accessible chartIdentify encodingpart-whole, composition, intensity, distribution, range, boundeddecides the restSummarythe chart's message in wordsbefore the chartTableshaped to the encodingcomplete equivalentKeyboard model1D, 2D or nonedetails on focusColour independencelabels, patterns, fill styles, wordsSC 1.4.1Native semanticsmeter for gaugesSC 4.1.2

Keyboard interaction contract

Permalink to "Keyboard interaction contract"
Chart Key Action Expected announcement Failure indicator
Pie Arrows Next / previous slice “Open: 412 tickets, 34 percent” Hover-only values
Stacked bar Left / Right Next / previous category Category, series, value, share, total Series missing
Stacked bar Up / Down Next / previous series Same Moves opposite to the stack
Heatmap Arrows Cell to cell Row, column, value, bin Colour only
Histogram Arrows Bin to bin Range, count, share Index labels
Candlestick Arrows, Page keys Period to period OHLC and direction Red or green only
Gauge — Read in browse mode Name, value, status “Graphic”

Screen reader compatibility matrix

Permalink to "Screen reader compatibility matrix"
AT + browser Focusable SVG marks role=application charts meter Notes
NVDA + Chrome Names read Keys passed “meter” Reliable
NVDA + Firefox Names read Keys passed “meter” —
JAWS + Chrome Names read Keys passed “meter” or “progress bar” aria-valuetext helps
VoiceOver + Safari Usually read With interaction “level indicator” Test SVG path focus
TalkBack + Chrome Swipe to marks Limited Read Tables are the main route

Edge cases & failure modes

Permalink to "Edge cases & failure modes"

1. Pies with many slices

Permalink to "1. Pies with many slices"

Diagnosis: twelve slices in similar hues. Fix: “Other” grouping, labels, or switch to bars.

2. Stacked segments without totals

Permalink to "2. Stacked segments without totals"

Diagnosis: announcements give values but not share or total. Fix: include both.

3. Rainbow heatmaps

Permalink to "3. Rainbow heatmaps"

Diagnosis: hue-based palette, hover values. Fix: sequential palette, values in cells.

4. Histogram alt text that names the chart

Permalink to "4. Histogram alt text that names the chart"

Diagnosis: “Histogram of response times”. Fix: statistics and shape.

5. Gauges as decorative SVGs

Permalink to "5. Gauges as decorative SVGs"

Diagnosis: no role or value. Fix: meter semantics with value text.

Accessible pie and donut charts

Permalink to "Accessible pie and donut charts"

Six slices or fewer, direct labels with percentages, focusable slices with full names, separators, a centre total as text, a summary and a table. See accessible pie and donut charts.

<path tabindex="0" role="img" aria-label="Open: 412 tickets, 34 percent"/>

Accessible stacked bar charts

Permalink to "Accessible stacked bar charts"

Two-dimensional navigation with value, share and total, separators and patterns between segments, and a table with a total column. See accessible stacked bar charts.

`${cat}, ${series}: ${fmt(v)}, ${pct(v / total)} of ${fmt(total)}`

Accessible heatmaps

Permalink to "Accessible heatmaps"

A table at heart: headers, values in cells, sequential palettes with named bins and summaries of hot spots. See accessible heatmaps.

<td class="bin-3">3.1% <span class="flag">over budget</span></td>

Accessible histograms and distributions

Permalink to "Accessible histograms and distributions"

Lead with centre, spread, shape and outliers; bins with ranges; statistics computed from data. See accessible histograms and distributions.

const shape = skew > 0.3 ? 'right-skewed' : skew < -0.3 ? 'left-skewed' : 'roughly symmetric';

Accessible candlestick and financial charts

Permalink to "Accessible candlestick and financial charts"

OHLC and direction in words on focus, hollow and filled candles, range summaries, period tables and pausable live views. See accessible candlestick and financial charts.

`${date}: open ${o}, high ${h}, low ${l}, close ${c}, ${c >= o ? 'up' : 'down'}`

Accessible gauges and the meter element

Permalink to "Accessible gauges and the meter element"

Native meter or role meter with names, value text with units and status, visible values and progress reserved for tasks. See accessible gauges and the meter element.

<div role="meter" aria-valuenow="99.2" aria-valuetext="99.2 percent, below 99.5 percent target"></div>

Cross-cutting concerns

Permalink to "Cross-cutting concerns"

Choosing a better chart. Many accessibility problems vanish when the chart type changes: twelve-slice pies become bar charts, unbounded gauges become KPI cards, intraday candlesticks for general users become line charts. Accessibility review is a good moment to ask whether the chart type serves anyone well.

Consistency across a dashboard. When a dashboard mixes chart types, keep the keyboard models consistent where possible (arrows always move between marks; Home and End always go to the ends) and the summary position consistent (always above the chart).

Library defaults. Most chart libraries default to hover tooltips, legends and colour palettes that fail several of the criteria above. Configure accessibility modules where they exist (Highcharts, ECharts aria) and wrap others with your own summaries and tables.

Dark mode. Each chart type’s colours — slices, bins, candles, gauge zones — need verification in both themes. See dark mode chart palettes.

Reviewing one chart for accessibility Chain of review steps: name the encoding; check the summary says it; check the table matches it; try the keyboard; view in greyscale and forced colours. Reviewing one chart for accessibilityEncodingwhat is this chartfor?Summarysays it in words?Tableshaped to match?Keyboarddetails on focus?summarytablekeyboardGreyscalestill readable?
Five checks that catch most chart-type problems.

Worked example: a dashboard with six chart types

Permalink to "Worked example: a dashboard with six chart types"

An operations dashboard contained a donut (tickets by status), a stacked bar (tickets by week and priority), a heatmap (errors by hour and service), a histogram (resolution times), a candlestick-style range chart (daily response time ranges) and three gauges (SLA, backlog, on-call coverage). The accessibility review applied the patterns in this topic one by one: the donut gained labels and a table; the stacked bar got 2D navigation and a total column; the heatmap became an HTML table with values and five named bins; the histogram’s alt text was replaced with statistics and shape; the range chart switched to hollow and filled marks with OHLC-style announcements; and the gauges became meters with status words. The dashboard’s summary region at the top now reads each widget’s headline in one sentence, which sighted managers ended up using as their morning briefing.

Who is affected, and how

Permalink to "Who is affected, and how"
User group Typical failure Fix
Screen reader users Alt text names the chart type only Encoding-specific summaries and tables
Colour-blind users Slices, bins and candles by hue Labels, patterns, fill styles
Keyboard users Hover-only details Focus models per chart type
Low-vision users Small labels on coloured marks Contrast and direct labels
Users with cognitive disabilities Dense encodings with no message A headline summary per chart

Common mistakes across chart types

Permalink to "Common mistakes across chart types"
  • Type-only alt text. “Bar chart”, “Pie chart”, “Heatmap” tell users nothing about the data.
  • Legend-keyed colour. Every chart type that matches colour swatches to labels fails colour-blind users and slows everyone.
  • Hover-only values. The default tooltip behaviour of most libraries; focus must reveal the same details.
  • The wrong chart for the data. Many pies should be bars; many gauges should be KPI numbers; many candlesticks should be lines.
  • Hand-written alternatives. Summaries and tables typed by hand drift from the data within weeks; generate them.

Design system integration

Permalink to "Design system integration"

Ship chart components by encoding rather than by appearance — PartToWholeChart, CompositionChart, IntensityGrid, DistributionChart, RangeChart, Meter — each with its summary generator, table shape and keyboard model built in. Each component should switch to a more readable form when data exceeds its limits (too many slices, too many series), and every colour token used should be verified for contrast in both themes and in forced colours.

Measuring chart accessibility by type

Permalink to "Measuring chart accessibility by type"

For each chart on a page, record three facts: does the summary state the chart’s message (not just its type), does a table exist with the right shape, and can details be reached by keyboard? A simple spreadsheet of charts and these three checks gives a coverage percentage that teams can improve release by release.

Testing checklist

Permalink to "Testing checklist"

Automated

Permalink to "Automated"

Visual

Permalink to "Visual"

Keyboard and screen reader

Permalink to "Keyboard and screen reader"

FAQ

Permalink to "FAQ"
Do all charts need keyboard navigation?

Interactive charts do. Static charts with a good summary and table do not need focusable marks.

Which chart types are easiest to make accessible?

Bar and line charts, gauges with meter, and heatmaps built as tables. Pies, Sankeys and candlesticks need more care.

Should I avoid pie charts?

Not necessarily — for two to six parts with labels they work. Above that, use bars.

How long should chart summaries be?

One to three sentences: the chart’s main message and anything notable.

Are accessibility modules in chart libraries enough?

They are a strong start (Highcharts, ECharts); configure descriptions for each chart type and still provide summaries and tables.

How do I test a chart type I have not seen before?

Ask what it encodes, then check the summary, table, keyboard and colour independence against that encoding.

Should chart tables be visible by default?

For data-heavy audiences, often yes. Otherwise behind a clearly labelled toggle.

How do I handle chart types not covered here?

Apply the same method: identify the encoding, then summarise, tabulate and navigate in its terms.

Should every chart have a visible summary?

Yes, ideally. Visible summaries help everyone, not only screen reader users, and they keep authors honest about what the chart shows.

How many chart types should a design system support?

Fewer than most do. A small set of encodings done well — with summaries, tables and keyboard models — serves users better than a large gallery of partially accessible types.

What if a stakeholder insists on a hard-to-access chart type?

Keep it, and make the alternatives excellent: a strong summary, a complete table and keyboard details. Then offer a simpler chart as an alternative view and let usage decide.

Permalink to "Related"

← Back to Virtualization, Charts & Dynamic Data Displays