GuidesAccessible Interactive Graphs

Accessible Interactive Graphs

Interactive, draggable graphs are at the heart of Doenet — students move points, vectors, and curves and watch what happens. But dragging is a mouse gesture. A student working by keyboard or screen reader can’t drag, and may not be able to see the result either. Making an interactive graph accessible means giving those students two things: a way to perceive the graph’s current state, and a way to change it without a mouse.

⚠️

This is an area Doenet is still building out. The techniques below are real and usable today, but fully accessible interactive graphics is an unsolved problem — see the frontier discussion. Expect this guide to grow.

Every graph still needs the basics from the other guides first: a <shortDescription> so it isn’t flagged as a violation, and labelled controls. This guide is about what to add beyond that for graphs students manipulate.


Describe a graph whose state changes

A <shortDescription> is static, but an interactive graph changes as the student works. Pair the short description (what the graph is) with a <description> that reports the graph’s current state — and let that description update by building it from the graph’s live values. Here, the description names the point’s coordinates and which quadrant it is in, and both update as the point moves:

Drag the point: the description re-reads its coordinates and quadrant. A screen-reader user who revisits the description hears the up-to-date state instead of a frozen sentence. This is the single most useful technique on the page — a description built from live values turns an opaque figure into something a non-visual reader can follow.


Let keyboard users operate the graph with addControls

A description lets a student perceive the graph; addControls lets them change it. Add it to a <graph> and Doenet renders a panel of on-screen controls for the movable objects in the graph. Each control can be reached and operated from the keyboard — so a point can be moved by typing coordinates or operating sliders, with no dragging required.

addControls="all" gives both input boxes (type a value) and sliders (nudge with arrow keys). Use addControls="inputsOnly" or addControls="slidersOnly" to offer just one, and controlsPosition (left, the default, or bottom) to place the panel. The controls work for the movable objects Doenet knows how to manipulate — points, line segments, vectors, circles, polygons, and more — and a point can even restrict which axes it exposes.

The payoff: a task that previously required dragging now has a keyboard path. A sighted student can still drag the point directly; a keyboard user changes the same coordinates through the controls.


A description conveys a graph as one block of text. For a graph with several parts, the PreFigure renderer lets a reader explore it from the keyboard instead — moving through the pieces one at a time, with a screen reader announcing each one and the graph highlighting and zooming to the piece in focus.

⚠️

Switching a graph to the PreFigure renderer currently disables mouse dragging of its graphical objects — for now, that interactivity is given up in exchange for the navigation below. Reach for PreFigure on a graph the reader needs to read, not one they need to move.

Switch a graph to it with renderer="prefigure", then attach annotations to the objects you want navigable. An <annotations> block holds the annotation tree; each <annotation> carries a text phrase to announce and, usually, a ref pointing at the object it describes.

The annotation tree needs a single root

This is the part people get wrong. PreFigure reads only the first <annotation> directly inside <annotations> — so if you list your objects as siblings there, only one of them is reachable. The first annotation has to be a single root that stands for the whole graph: give it a text describing the graph and no ref, then nest every per-object annotation inside it.

⚠️

Symptom of the most common mistake: if navigating the graph reaches only the first object and no others, your annotations are siblings directly inside <annotations>. Wrap them all in one outer <annotation> that has a text for the whole graph and no ref, as above.

Try it without a screen reader

You don’t need assistive technology to check that the navigation works. Click the graph (or Tab to it and press Enter), then:

  • ↓ (down arrow) moves down the tree — from the root into its children.
  • ← and → (left and right arrows) move between objects at the same level.

Walk the tree this way and confirm you can reach every object you annotated — not just the first.

A few more details:

  • text is the brief label announced for a piece; speech (optional) is a longer description for when a reader asks for more detail.
  • Nest annotations further to group related pieces — the two points could sit inside the line’s annotation, so a reader moves “into” the line to reach them.
  • If an annotation’s ref doesn’t resolve to an object in the graph, that annotation is dropped and the accessibility report notes it — so check the report after wiring annotations up.

Pair the graph with a check-work answer

Many Doenet problems ask the student to arrange a graph to satisfy some condition, then press a button to check it. The check itself is an <answer> whose <award> tests the configuration with a <when> condition. Because this answer creates no input of its own, it needs no label — keep the prompt as ordinary text beside it, and the Check Work button it renders is reachable by keyboard like any button.

Putting the pieces together gives a fully keyboard- and screen-reader-operable version of the classic “drag until it’s right, then check” problem — perceive the state through the description, change it with addControls, and check it with the button:

The same activity now works three ways at once: drag the point with a mouse, move it with the keyboard controls, or read its position from the description — and any of them can finish by pressing Check Work.


A work in progress

These techniques cover a lot, but not everything. Some interactions still have no good non-visual equivalent, and matching the fluidity of dragging for every kind of object is exactly the open problem Doenet is working on. When you build an interactive graph, the test to apply is simple: can a student who cannot use a mouse, and a student who cannot see the screen, each complete the task? If not, a description that updates, addControls, and PreFigure annotations are the tools to reach for — and where they fall short, that gap is one we are actively trying to close. If you hit a wall these tools can’t get you past, tell us about it at community.doenet.org — the obstacles authors run into are what steer where Doenet’s accessibility tools go next. For the bigger picture, see Accessibility in Doenet.

Where to go next