Interactive

Interactive charts respond to the reader, with legends, cursors, brushes and handles that select, filter or move what the chart shows.

LLMs

Accessibility

What each TanStack Charts control does for keyboard and screen reader users, and what you add so every gesture has another way in.

What you get

  • interactiveColorLegend: a named group of real buttons, each with aria-pressed and a target of at least 44 pixels. Focus stays on the button after the chart redraws, and a status message says when every series is hidden.
  • brushX with values: two sliders, one per handle. The arrow keys move one value, Home and End go to the ends of the range.
  • handleX: one slider. Left or Down moves to the previous value, Right or Up to the next, Home and End to the ends. Its pointer target is 44 pixels high.
  • zoomX: one focusable zoom surface. Plus and minus zoom, the arrow keys pan, Home resets.
  • keyedSelection: Enter or Space selects the focused point, the same as a click.
  • The kit's focus outline on the chart, the handles and the legend buttons, shown for keyboard focus only.

What you add

  • A name for each control that says what it changes.
  • The current state in text: the selected range, the zoomed dates, the selected item.
  • A Reset or Clear button for every gesture.
  • Your own controls where the chart has none: sliders beside a free cursor, Play and Pause beside a scrubber.
  • A second signal besides color for a selected point.

Name the controls

Each control has a default name, such as "Range start" or "Horizontal value". Replace it with one that names your data, and give format a value a person would say, since a screen reader reads it as the slider moves.
brushX({
range,
values: dates,
ariaLabel: "Month range",
startAriaLabel: "First month",
endAriaLabel: "Last month",
format: (date) => date.toLocaleDateString("en-US", { month: "long", year: "numeric", timeZone: "UTC" }),
})
interactiveColorLegend({
visible,
ariaLabel: "Industries shown",
itemAriaLabel: (industry, { visible }) => `${visible ? "Hide" : "Show"} ${industry}`,
})

Say what changed

Show the result of each gesture in text near the chart, like "March to June selected". For changes the reader commits, put that text in an element with role="status" so a screen reader announces it. Announce the commit, not every step of a drag.

Escape cancels

  • During a drag, Escape puts a brush or a handle back where the drag started.
  • Escape cancels a zoom gesture in progress.
  • Escape clears a pinned free cursor.
  • Your change handler gets a cancel or clear reason. Restore your state from it, so the text and the chart match.

Do not trap the scroll wheel

By default, zoomX takes the wheel only once its surface has focus, so the page keeps scrolling past the chart. On a scrolling page, wheelActivation: "modifier" zooms only while Control or Command is held. "always" captures every wheel over the plot and stops the page under the pointer, so keep it for full-screen charts.

Gestures with no keyboard path

continuousCursor is drawn for the pointer only. A brush without values has no sliders. Pair each with controls that write to the same state:
<Slider
ariaLabelForHandle="Horsepower"
min={50}
max={190}
value={position.x}
onChange={(x) => setPinned({ x, y: position.y })}
/>
A scrubber that plays on a timer needs a Pause button, and should stop on its own at the last value.

Selection

  • Mark the selected point with more than a color: a larger size, an outline or a label.
  • A linked table gives every item a keyboard path and the exact values. Let its rows set the same selected key.
  • A click on empty space clears the selection. Keyboard users need a Clear button for the same thing.

Legends

A hidden series keeps its button, so the reader can bring it back, and the button reports whether its series is shown. If you build your own legend from plain badges, make each item a toggle button with aria-pressed, or use a Checkbox group.

Check it

  • Do every task with the keyboard only: toggle a series, move a range, zoom and reset, select and clear.
  • Press Escape in the middle of a drag.
  • Scroll the page with the pointer over the chart.
  • Listen to each control's name and value with a screen reader.
  • Drag each handle on a phone.
The Keyboard guideline has the rules that apply to every chart.