Command Palette

Search for a command to run...

Hectal
PHASE 15Advanced ~37 min· topic 6 of 7

Topic 15.6

Auditing a Chart

In one line

Run a short, repeatable audit on every chart: a handful of yes-or-no checks, an automated scan with its limits understood, and a session with a real screen reader user. Automation finds a missing name. Only a person finds a useless one.

Think of it like this

A building inspector with a short checklist. Is there a fire exit sign? Does the door open outwards? The checklist is short and the answers are yes or no. The inspector also walks the building, because a checklist cannot tell that a sign is hidden behind a plant.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

audit
A repeatable set of checks, each with a yes or no, run on a chart or a page.
Chartability
A free set of accessibility tests for data visualisations (CC BY-SA 3.0).
axe-core
An open-source engine that scans a page for accessibility rule violations.
violation
A check the scanner is sure a page fails.
incomplete
A check the scanner could not decide and leaves for a person.
false pass
A check that passes although the chart is still not usable, such as a name that says only chart.
keyboard trap
A widget that keeps focus: Tab cannot leave it (Topic 15.4).

Step by step

01Write each check as code

The first example's audit(section) returns six [label, ok] pairs. Each one is a question a person could answer by looking, so a failed check says exactly what to fix.

02Run it on three charts

A bare SVG passes 1 of 6 (the Tab stops). A chart labelled "Chart" passes 3: it has a role, a name and one Tab stop, and fails the name's quality, the description and the table. The full chart (built with the helpers from Topics 15.2 and 15.3) passes all six.

03Check for a keyboard trap

The second example presses ArrowRight, Tab and Escape on two widgets and reports which keys the widget took. A widget that takes Tab traps the keyboard.

04Run a scanner and read its limits

The measured block lists what axe said for six small cases and for the dashboard. It is a floor: no violation does not mean accessible.

05Sit with Meera

Pick one task, watch her do it, and write each stumble as a bug with the chart and the step. Fix, then repeat the task.

Try it yourself

  1. 1

    Say a little more than chart

    In the first example, change the second chart's label from "Chart" to "Chart of data". The Console prints Labelled 'chart': 4 of 6 pass: the check "name says more than 'chart'" now passes, and the failures left are the description and the table.

Code & diagrams

A six-check audit on three charts New tab

The checks are yes or no and can run in a test (Phase 16 puts them in tests/). They check that words exist, not that the words are right.

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

Bare svg: 1 of 6 pass
  FAIL has a role (img or group)
  FAIL has a name
  FAIL name says more than 'chart'
  FAIL has a description
  FAIL has a table twin
Labelled 'chart': 3 of 6 pass
  FAIL name says more than 'chart'
  FAIL has a description
  FAIL has a table twin
Full: 6 of 6 pass
Is the widget a keyboard trap? New tab

A dispatched Tab does not move focus by itself, so the test reads defaultPrevented: whether the widget would have stopped the browser from moving it.

Console

(nothing was printed)

Expected console output

handles arrows only  | ArrowRight taken, Tab left alone, Escape left alone
swallows every key   | ArrowRight taken, Tab taken, Escape taken
A Tab that is 'taken' means the browser will not move focus on: a person using the keyboard is stuck.
What axe-core 4.13.0 found (measured, not live)text

axe-core is not part of this course's live runtime. These results come from running axe 4.13.0 in Chromium with Playwright over six small pages, and over the dashboard. Violations use axe's rule names.

case                                         axe violations
bare <svg>, no role                          none
<svg role="img">, no name                    svg-img-alt
<svg role="img" aria-label="Chart">          none
<svg role="img" aria-label="Rides peaked at 4,380 on 18 Jul">   none
<svg role="img" aria-label="...9,999 on 1 Jan"> (false)         none
<canvas role="img">, no name                 role-img-alt

Dashboard, tags wcag2a, wcag2aa, wcag21aa, wcag22aa, best-practice:
  Phase 14, light and dark:   0 violations, 1 incomplete (color-contrast, 140 nodes)
  Phase 15, light and dark:   0 violations, 1 incomplete (color-contrast, 141 nodes)

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Pass the audit with a useless name

Leave the change from the try-it in place: the label is "Chart of data".

terminal
$ Console
── what you'll see ──
Labelled 'chart': 4 of 6 pass
FAIL has a description
FAIL has a table twin

Myth vs fact

Myth

If axe reports zero violations, the chart is accessible.

Fact

In the measurement above, a chart with a name that says "Chart", and one with a false finding, both passed.

Myth

An audit is a one-off before launch.

Fact

Charts change. Put the six checks into tests (Phase 16) so a new chart that fails them is caught the day it is written.

Myth

Accessibility testing needs an expert.

Fact

The checklist needs a keyboard and ten minutes. The screen reader session needs a screen reader user, and their time is worth paying for.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Scanners do not run in a canvas: they see the canvas element and its label, not what was drawn. For canvas charts, the table twin and the description are your tests.

  • ▸

    Run the scan on every state: loading, error, empty, filtered. An error box with no role="alert" is a bug that only appears when something fails (Topic 16.4).

  • ▸

    Keep a record of each audit with the date and the tool versions. An audit from six months ago says little about today's chart.

Remember this

  1. 1

    The problem this solves: accessibility work is easy to skip and hard to see. Without a checklist, each chart gets whatever care its author remembered. A short audit makes the care the same for every chart, and shows what is left.

  2. 2

    A short checklist you can repeat. Chartability is a free set of tests for data visualisation accessibility, under a Creative Commons licence (CC BY-SA 3.0): it groups 50 heuristics under seven principles (perceivable, operable, understandable, robust, and three more for the data experience), and 14 of them are marked critical. Its own advice for newcomers is to test the critical ones first. A trained auditor can pass over one chart in as little as 30 minutes, and a newcomer's full pass can take 2 to 8 hours (chartability.github.io). The W3C's "Complex images" tutorial has the short and long description advice. Link to them and read them: this topic's checks are our own short list in their spirit, not a copy.

  3. 3

    Six checks every chart gets. Has a role. Has a name. The name says more than "chart". Has a description. Has a table twin. At most one Tab stop. The first example runs these six as code on three charts and prints which pass. Add checks as the chart needs them: the day reader moves with the arrow keys, contrast of marks is 3 to 1 in both themes, nothing is lost at 320 pixels.

  4. 4

    Automated scanners find a missing name, not a wrong one. axe-core, a widely used engine behind many browser tools, reports rule violations. In our measurement, a role="img" SVG with no name is a violation (svg-img-alt), and so is a canvas with role="img" and no name (role-img-alt). A chart labelled just "Chart" passes. So does a label that gives a finding that is false. A scanner cannot know your data. A scanner only finds problems it has a rule for, so treat a clean scan as the start.

  5. 5

    The axe results on this course's own dashboard. On the Phase 14 and Phase 15 dashboards, in light and dark, axe reported 0 violations and 1 item it could not decide (color-contrast, 140 nodes in Phase 14 and 141 in Phase 15: it cannot compute the colour of text over an SVG). The Phase 14 dashboard already passed because its charts had names. Even so, only one of its charts had a table, none had a description joined with aria-describedby, and each finding was packed into one long label: a clean scan is not a usable chart.

  6. 6

    Test the way she works. Ask a screen reader user to do a real task: "which station was busiest in July?" Watch where she goes: the heading first, then the charts. Note each place she is stuck, silent or told something untrue. Ask, thank, and treat what you hear as bugs. A short session finds what no scanner does, and it is the only test that counts people's time.

  7. 7

    Know the limits of this audit. Six checks cannot say a description is good. A checklist says nothing about a chart's colour palette, its misleading baseline (Topic 2.5) or the density of an overplotted canvas. Use the audit as a floor under the chart, not a certificate.

Explain it without notes

01

What does an automated scan find, and what does it miss?

02

Why a short checklist instead of a long standard?

03

What would you ask a screen reader user to do in a test session?

04

Where do you put the audit so it keeps running?

Practice

01

Add a seventh check to audit: the chart's description is not longer than 600 characters.

02

Write the one-line axe call that returns the list of violation ids for the whole page (with axe-core loaded).

Trade-offs

  • ↔

    A short audit is cheap and shallow. A session with a screen reader user is deep and costs an hour of a person's time. Do both, in that order of frequency.

Done when you can

  • I can run the six checks on a chart and fix what fails.

  • I know what axe finds and what it cannot know.

  • I check for keyboard traps by pressing Tab.

  • I have a real person try a real task, and I fix what they find.