Accessible Network & Graph Diagrams
Permalink to "Accessible Network & Graph Diagrams"Network and graph diagrams show relationships: services that call each other, accounts that share devices, money flowing between budget lines, people reporting to managers, concepts linked in a knowledge base. They are some of the most information-dense visualisations in data products, and some of the least accessible. A bar chart has axes and values that translate naturally into a table; a graph’s meaning is in its topology — hubs, clusters, bridges, paths — which a single alt text cannot carry and which a mouse-only, pan-and-zoom canvas hides from keyboard and screen reader users entirely.
The approach that works combines three representations, all generated from the same data: a summary that gives the shape at a glance, a table (or tree, for hierarchies) that is complete and filterable, and keyboard exploration that lets users move from node to neighbour the way sighted users follow lines. The users most affected are screen reader users, keyboard users, colour-blind users (edge and node types are often colour-coded), and magnifier users (large graphs need constant panning). The failure this topic prevents is a relationship diagram that only sighted mouse users can read.
This topic belongs to virtualization, charts & dynamic data displays.
WCAG criteria in scope
Permalink to "WCAG criteria in scope"| Criterion | Level | Relevance to graph diagrams |
|---|---|---|
| 1.1.1 Non-text Content | A | Summary plus complete equivalent |
| 1.3.1 Info and Relationships | A | Edges, flows and hierarchy available as data |
| 1.4.1 Use of Color | A | Node and edge types in words or patterns |
| 1.4.10 Reflow | AA | Tree and table equivalents reflow at 400% |
| 1.4.11 Non-text Contrast | AA | Nodes, edges and focus rings at 3:1 |
| 2.1.1 Keyboard | A | Exploration and inspection without a pointer |
| 2.4.7 Focus Visible | AA | Focused node highlighted in the drawing |
| 4.1.3 Status Messages | AA | Traversal and filter updates announced |
Prerequisites
Permalink to "Prerequisites"- Data visualization & chart alternatives, the general principles behind summaries and table equivalents.
- Tree views & hierarchical navigation, for hierarchies.
- Canvas & SVG chart keyboard interaction, for focus in drawings.
- Chart colour & contrast, for distinguishing categories without colour.
ARIA & HTML spec reference
Permalink to "ARIA & HTML spec reference"| Element / attribute | Valid values | When to apply | Common misuse |
|---|---|---|---|
figure + heading + aria-describedby |
— | Wrap the graph, title and summary | Unrelated paragraphs nearby |
role="application" |
— | Graph regions with a custom key model | Large regions or undocumented keys |
role="img" + aria-label |
— | Focusable bands or nodes with full names | Unnamed focusable shapes |
role="tree" / treeitem |
— | Hierarchy equivalents | Edge tables for strict hierarchies |
table with th scope |
— | Edge and flow tables | Adjacency matrices for large graphs |
role="status" |
— | Traversal and filter messages | Announcing every hover |
aria-hidden="true" |
— | Decorative canvas when a full equivalent is present | Hiding the only representation |
Step-by-step implementation
Permalink to "Step-by-step implementation"Step 1 — Summarise (SC 1.1.1)
Permalink to "Step 1 — Summarise (SC 1.1.1)"const s = summarise(graph); // headline + bullets: counts, hubs, groups, bridges, isolated nodes
See announcing graph structure summaries.
Step 2 — Provide the complete equivalent (SC 1.3.1)
Permalink to "Step 2 — Provide the complete equivalent (SC 1.3.1)"<table><caption>Service connections: 96 directed edges</caption>…</table>
See adjacency tables as network graph alternatives and, for hierarchies, accessible org charts and hierarchy diagrams.
Step 3 — Explore by keyboard (SC 2.1.1)
Permalink to "Step 3 — Explore by keyboard (SC 2.1.1)"if (e.key === 'ArrowRight') openNeighbourMenu(current.neighbours);
See keyboard traversal of node-link graphs.
Step 4 — Words for types and directions (SC 1.4.1)
Permalink to "Step 4 — Words for types and directions (SC 1.4.1)"`${nb.node.name}, ${nb.relation}` // "Ledger DB, writes to"
Step 5 — Flows with values (SC 1.3.1)
Permalink to "Step 5 — Flows with values (SC 1.3.1)"`${l.source.name} to ${l.target.name}: ${fmt(l.value)}, ${pct} of ${l.source.name}`
See accessible Sankey diagrams.
Step 6 — Visible, stable focus (SC 2.4.7)
Permalink to "Step 6 — Visible, stable focus (SC 2.4.7)"simulation.stop(); highlight(current); centerOn(current); // freeze layout before exploration
Keyboard interaction contract
Permalink to "Keyboard interaction contract"| Context | Key | Action | Expected announcement | Failure indicator |
|---|---|---|---|---|
| Graph | Tab | Focus graph at current node | Graph name, node name, type, degree | Many tab stops |
| Graph | Right | List neighbours | “Ledger DB, writes to, 1 of 4” | Arrow pans the canvas only |
| Graph | Enter (in list) | Move to neighbour | Node and relation | Nothing |
| Graph | Backspace | Back along path | “Back to …” | Lost position |
| Graph | / | Search | Search field | — |
| Sankey | Tab or arrows | Next band | Full flow name with value | Hover-only values |
| Org tree | Arrows | Tree navigation | Name, role, team size, level | Indentation only |
Screen reader compatibility matrix
Permalink to "Screen reader compatibility matrix"| AT + browser | role=application graphs | Focusable SVG paths | Trees | Notes |
|---|---|---|---|---|
| NVDA + Chrome | Keys passed; status read | Names read | Levels read | Document keys in the description |
| NVDA + Firefox | Same | Names read | Levels read | — |
| JAWS + Chrome | Keys passed | Names read | Levels read | Application mode announced |
| VoiceOver + Safari | Keys passed with interaction | Names read in most cases | Levels on change | Test path focus in Safari |
| TalkBack + Chrome | Limited custom keys | Swipe to elements | Partial | Tables are the primary route |
Edge cases & failure modes
Permalink to "Edge cases & failure modes"1. Hundreds of tab stops
Permalink to "1. Hundreds of tab stops"Diagnosis: every node focusable in layout order. Fix: one tab stop and traversal.
2. Colour-only relation types
Permalink to "2. Colour-only relation types"Diagnosis: red edges for “fraud signal”, blue for “payment”. Fix: a Relation column and relation names in traversal.
3. Moving layouts
Permalink to "3. Moving layouts"Diagnosis: force simulation keeps nudging nodes during exploration. Fix: stop the simulation before interaction.
4. Matrix tables for large graphs
Permalink to "4. Matrix tables for large graphs"Diagnosis: a 200 × 200 adjacency matrix. Fix: edge table with filters.
5. Org charts as images
Permalink to "5. Org charts as images"Diagnosis: canvas chart with a one-line alt. Fix: a tree equivalent with search.
Keyboard traversal of node-link graphs
Permalink to "Keyboard traversal of node-link graphs"Explore from a node to its neighbours, hear relations and degrees, step back with Backspace and jump with search — one tab stop for the whole graph. See keyboard traversal of node-link graphs.
say(`${describe(node)}. Reached via ${relation}.`);
Adjacency tables as network graph alternatives
Permalink to "Adjacency tables as network graph alternatives"Edge tables with From, Relation and To columns, filters on either end and attributes as columns are complete and practical. See adjacency tables as network graph alternatives.
<tr><th scope="row">Checkout</th><td>calls</td><td>Auth service</td></tr>
Announcing graph structure summaries
Permalink to "Announcing graph structure summaries"Counts, hubs, named groups, bridges and isolated nodes, generated from the model and placed before the graph. See announcing graph structure summaries.
`${g.nodes.length} services with ${g.edges.length} connections, in ${groups.length} groups.`
Accessible Sankey diagrams
Permalink to "Accessible Sankey diagrams"Flow tables with shares, summaries of the largest flows, labelled nodes and focusable bands with full names. See accessible Sankey diagrams.
<path tabindex="0" role="img" aria-label="Engineering to Salaries: 4.2 million EUR, 70 percent of Engineering"/>
Accessible org charts and hierarchy diagrams
Permalink to "Accessible org charts and hierarchy diagrams"A tree equivalent with roles and team sizes, described dotted lines, search and focus synchronised with the visual chart. See accessible org charts and hierarchy diagrams.
tree.addEventListener('focusin', e => chart.centerOn(idOf(e.target)));
Cross-cutting concerns
Permalink to "Cross-cutting concerns"One model, many views. Summaries, tables, trees, traversal and drawings must come from one data model. Hand-maintained alternatives drift within weeks.
Scale. Graphs with thousands of nodes cannot be drawn usefully for anyone. Filter first (by team, time range, relation type), then draw; the summary and table should state what is filtered out.
Performance. Focusable SVG elements for every node and edge add to the accessibility tree. For large graphs, keep one focusable region and manage virtual focus, as discussed in DOM size limits and accessible performance tradeoffs.
Motion. Animated layouts and physics simulations should stop, and respect prefers-reduced-motion.
Worked example: an incident service map
Permalink to "Worked example: an incident service map"During incidents, an operations team relies on a service map. Before the redesign, it was a canvas with coloured nodes and hover tooltips; an on-call engineer who uses NVDA could not use it at all and depended on colleagues reading it to her. After the redesign: the map’s caption summarises the graph and currently failing services (“3 services failing: Payments API, Ledger DB, Queue; Payments API is called by 6 services”); an edge table below can be filtered to any service; and the map itself is one tab stop with neighbour traversal, Backspace and search. Failing state is a word in every announcement and a pattern in the drawing, not only a red fill. She now leads incident calls with the same information as everyone else.
Who is affected, and how
Permalink to "Who is affected, and how"| User group | Typical failure | Fix |
|---|---|---|
| Screen reader users | Graph is an image or anonymous shapes | Summary, table and traversal |
| Keyboard users | Pan, zoom and hover only | One tab stop with traversal and search |
| Colour-blind users | Node and edge types by colour | Words, patterns and labels |
| Magnifier users | Constant panning of large graphs | Tables and trees that reflow |
| Users with cognitive disabilities | Dense, moving layouts | Summaries; stable layouts |
Common mistakes in graph libraries
Permalink to "Common mistakes in graph libraries"Graph libraries focus on layout and rendering and leave accessibility almost entirely to the application:
- Canvas renderers with no DOM. Sigma.js and some Cytoscape configurations draw to canvas; nothing is exposed to assistive technology unless you add a parallel structure.
- Hover-only tooltips. Node details appear on hover and never on focus.
- Colour-coded categories. Default styles map categories to hues with no labels or patterns.
- Physics that never stops. Force layouts keep running, moving nodes under the user’s focus.
- Zoom and pan as the only navigation. No way to jump to a node by name.
All five are fixed in the application layer: a parallel model-driven structure, focus-triggered details, labels and patterns, a stopped simulation and search.
Design system integration
Permalink to "Design system integration"Build a graph accessibility layer independent of the renderer: a model adapter (nodes, edges, relations, hierarchy), a GraphSummary, a GraphTable or HierarchyView, and a GraphNavigator for traversal with message templates. Renderers (D3, Cytoscape, Sigma, ECharts) only need to draw a focus highlight and accept “center on node” commands. Tokens for focus halos, highlighted edges and pattern fills must meet 3:1 in light, dark and forced-colours modes.
Measuring graph accessibility
Permalink to "Measuring graph accessibility"Ask three questions of every graph and time the answers with a screen reader: “How many nodes and connections are there?” (should be immediate from the summary), “What connects to X?” (under a minute via table filter or traversal) and “What is the path from A to B?” (possible via traversal or a path-finding command). If any question cannot be answered, one of the three representations is missing.
Testing checklist
Permalink to "Testing checklist"Automated
Permalink to "Automated"Keyboard
Permalink to "Keyboard"Screen reader
Permalink to "Screen reader"FAQ
Permalink to "FAQ"Is a table enough to make a graph accessible?
A good edge or flow table is a complete equivalent. A summary and traversal make it much easier to understand the graph’s shape and local structure.
Should I use role="application" for graphs?
For a small region with a documented custom key model, it is reasonable. Keep it limited to the graph itself.
How do I handle very large graphs?
Filter before drawing, summarise what is shown and hidden, and rely on tables and search for completeness.
Are Sankey diagrams accessible?
With a flow table, a summary and focusable bands, yes. Without them, no.
Should org charts be graphs or trees?
Trees, with secondary relationships described in text.
Do I need to describe the visual layout?
No. Describe structure in domain terms — hubs, groups, flows — not positions and colours.
Can screen reader users find paths between nodes?
Offer a “path from A to B” command that lists the steps; it is often more useful than manual traversal for everyone.
What is the first fix for an inaccessible graph?
Add a generated summary and an edge or flow table. They are quick to build and provide a complete equivalent while you work on traversal.
How do I make graph filters accessible?
Treat them like any data filter: labelled controls, a status message with the resulting counts (“Showing 14 services, 31 connections”), and an updated summary. Filters are often the most effective way to make a large graph usable for everyone.
Should edges have their own focus stops?
Usually not. Edges are reached through their nodes as relations. If edges carry important attributes, list them in the neighbour menu and the edge table.
Related
Permalink to "Related"- Data visualization & chart alternatives — principles for all charts
- Tree views & hierarchical navigation — hierarchies
- Chart type-specific patterns — other chart types
- Canvas & SVG chart keyboard interaction — focus in drawings
- Accessible data dashboards — graphs among other widgets