Touch Exploration of Charts on Mobile
Permalink to "Touch Exploration of Charts on Mobile"On a phone, charts are small and fingers are large. A line chart with 90 points gives each point a couple of pixels; tooltips appear on hover that never happens; pinch-zoom conflicts with page zoom. Mobile screen reader users face more: VoiceOver and TalkBack use swipes to move between elements, so charts must expose data points as swipeable elements or provide an alternative. The aim is that touch users can read any value, and screen reader users can step through data.
This guide belongs to canvas and SVG chart keyboard interaction.
Spec reference
Permalink to "Spec reference"- SC 2.5.8 Target Size (Minimum) (AA) — 24×24 pixel targets or spacing.
- SC 2.5.1 Pointer Gestures (A) — multipoint or path gestures need single-pointer alternatives.
- SC 1.4.13 (AA) — touch-revealed tooltips dismissible and persistent.
- SC 1.4.10 Reflow (AA) — charts usable at 320 px width.
When to use — and when not to
Permalink to "When to use — and when not to"Apply these techniques to any interactive chart that will be viewed on phones. For charts with many points, combine a scrubber with a summary and a data table.
Do not require pinch or two-finger gestures to reach data. The misapplication: a chart that only shows values on hover, which never happens on touch, leaving phone users with shapes but no numbers.
Annotated code example
Permalink to "Annotated code example"<figure>
<figcaption id="cap">Daily orders, last 30 days</figcaption>
<svg role="group" aria-labelledby="cap" viewBox="0 0 360 200" class="touch-chart">
<g class="points">
<circle role="img" aria-label="1 March: 120 orders" cx="10" cy="80" r="3"></circle>
<!-- invisible larger hit area for touch -->
<rect class="hit" x="0" y="0" width="12" height="200" aria-hidden="true"></rect>
</g>
</svg>
<details><summary>Show data table</summary><table>…</table></details>
</figure>
svg.addEventListener('pointerdown', e => { svg.setPointerCapture(e.pointerId); scrub(e); });
svg.addEventListener('pointermove', e => { if (e.buttons) scrub(e); });
function scrub(e) {
const i = nearestIndex(toChartX(e.clientX)); // snap; no precision needed
select(i); // ring + tooltip above finger
}
Keyboard & AT behaviour
Permalink to "Keyboard & AT behaviour"| Platform | Gesture | Result |
|---|---|---|
| iOS VoiceOver | Swipe right | Next point: “2 March: 134 orders” |
| iOS VoiceOver | Double-tap | Pins tooltip |
| Android TalkBack | Swipe right | Next point |
| Touch without screen reader | Drag across chart | Scrubber snaps to points |
| Any | “Show data table” | Compact table |
Step-by-step implementation
Permalink to "Step-by-step implementation"- Snap to data. Map touch position to the nearest data point along the x-axis so users never need to hit a tiny mark.
- Expose points. For charts with up to around 100 points, expose each as an element with a name so VoiceOver and TalkBack can swipe through them; for more, aggregate (weekly instead of daily) for the swipe path.
- Place tooltips above the finger. Fingers cover what is below them; show values above or in a fixed readout area.
- Avoid gesture conflicts. Do not intercept two-finger gestures; provide zoom buttons instead.
- Provide a table. A collapsible table sized for narrow screens, with key columns only.
Integration context
Permalink to "Integration context"Tooltip behaviour is covered in accessible tooltips for chart data points, and focus visibility in focus indicators for chart data points. Table toggles follow show-as-table toggles for charts. Mobile screen reader differences are in how TalkBack differs for data grid navigation.
Gotchas
Permalink to "Gotchas"Scroll versus scrub. Horizontal drags on a chart can conflict with page scrolling; use touch-action: pan-y so vertical scrolling still works.
VoiceOver direct touch. VoiceOver can pass gestures directly to an element with role="application", but most users do not expect it; prefer swipeable points.
Retina hit areas. Hit areas are in CSS pixels; test on real devices.
Edge cases
Permalink to "Edge cases"- Very dense data. Offer a range selector to narrow the period before exploring.
- Multiple series. Let users choose a series to scrub; announce all series values at a point when few.
- Landscape mode. Charts often become usable in landscape; do not lock orientation.
Worked example
Permalink to "Worked example"A fitness app showed heart-rate charts with hover tooltips. On phones, users saw only a line; VoiceOver users heard “image”. The team added snap-to-point scrubbing with a fixed readout above the chart, exposed per-minute averages as swipeable elements, added zoom buttons and a “Show data table” disclosure. Users could read exact values on phones, and VoiceOver users could step through a workout minute by minute.
Common mistakes
Permalink to "Common mistakes"- Hover-only values.
- Tiny targets with no snapping.
- Intercepting pinch and two-finger gestures.
- No table alternative on mobile.
Testing checklist
Permalink to "Testing checklist"Testing it with a screen reader
Permalink to "Testing it with a screen reader"On an iPhone with VoiceOver, swipe to the chart and keep swiping right; each point should be announced with its date and value. Double-tap one and confirm the readout pins. Use the rotor to jump to the data table toggle. On Android with TalkBack, repeat. Then turn off the screen reader and scrub across the chart with a finger, checking that values update smoothly and the page still scrolls vertically.
Small-screen chart design
Permalink to "Small-screen chart design"Simplify charts for narrow screens instead of shrinking them. Fewer axis ticks, shorter labels, direct labels instead of legends and a taller aspect ratio all make charts easier to read and touch. Consider showing a summary sentence above the chart on mobile — the takeaway first — so users who cannot explore easily still get the point. Test at 320 pixels wide and at 200% text size, where labels often collide.
Key points
Permalink to "Key points"- Snap touch input to the nearest data point; never ask for pixel precision on a phone.
- Show values above the finger or in a fixed readout area, and let users pin them.
- Expose points, or sensible aggregates, as swipeable elements for VoiceOver and TalkBack.
- Leave pinch and two-finger gestures to the browser and the screen reader; offer zoom buttons instead.
- Keep vertical page scrolling working over the chart with
touch-action: pan-y. - Always provide a compact data table sized for narrow screens.
Haptics and sound
Permalink to "Haptics and sound"Some mobile apps add a light haptic tick as the scrubber passes each data point, and a short tone whose pitch follows the value. Both can help users feel the shape of the data without looking, and both should be optional and off when the system’s reduce-motion or silent settings suggest the user does not want them. They complement, never replace, the spoken values and the table.
Design system notes
Permalink to "Design system notes"Give chart components a touch mode with snapping, fixed readouts and swipeable point exposure, enabled automatically on coarse pointers.
FAQ
Permalink to "FAQ"How big should touch targets be?
Snap to the nearest point, so the effective target is the full column.
Should every point be swipeable?
Up to around 100; aggregate beyond that.
Can I use pinch to zoom?
Only alongside buttons; never as the only way.
Where should tooltips appear?
Above the finger or in a fixed readout.
Is a table necessary?
Yes, for exact values and dense data.
Does role application help?
Rarely; it changes gesture handling in confusing ways.
Related
Permalink to "Related"- Focus indicators for chart data points — showing the current point
- Accessible tooltips for chart data points — tooltip rules
- Show-as-table toggles for charts — the table alternative