Build a component
A component is the smallest explorable: one idea, one interaction. Master these and dashboards and essays are just compositions of them. Here is the recipe, and a prompt you can hand straight to an AI.
Anatomy
- Pick the representation from the data's shape — comparison becomes bars, part-to-whole becomes a stack, a trend becomes a cumulative line, a distribution becomes a curve, a relationship becomes a scatter with a fit, a network becomes a graph, a trade-off becomes a Pareto scatter, and composition-over-time becomes a stacked area you can paint.
- Make the marks themselves the handles, so the reader drags the bar, node, point or curve directly rather than a hidden grip, and every number written in the prose is scrubbable too.
- Match the verb to the data: for model data let the reader edit the inputs, but for recorded or historical data give only analytical verbs — pivot, brush, normalise, counterfactual-replay — and never let them edit a fact.
- Make it reason: a caption recomputes live, running backward to the cause and forward to the consequence, with the words changing as the reader drags.
- Auto-scale every axis to fit the dragged values so nothing clips, never pinning a fixed axis.
- Use no flashing or opacity-pulse — that risks headaches and seizures — only steady directional motion, gated behind prefers-reduced-motion.
- Stay honest: never fabricate data to fill a chart — derive it, elicit it, or drop to a humbler representation — and show clearly what is real versus modelled.
- Ship a self-contained single file, mapping pointer coordinates with svg.createSVGPoint() and getScreenCTM().inverse(), using setPointerCapture, and setting touch-action:none.
The build prompt
Copy this into your agent:
You are building a single-file explorable COMPONENT — one idea, one interaction — from {DATA OR CONCEPT}.
Non-negotiable rules:
1. The MARKS are the handles. The reader manipulates the representation directly — drag the bar, node, point or curve itself. AND every number in the prose is scrubbable (drag a number in a sentence to change it).
2. Match the verb to the data: model/forecast data -> edit the inputs; historical/recorded data -> analytical verbs (pivot, brush, normalise, counterfactual-replay) — never let the reader edit a recorded fact.
3. It reasons. A caption recomputes live, backward to the cause and forward to the consequence; the words change as the reader drags.
4. Honest. Never fabricate data to fill a chart — derive it, elicit it, or drop to a humbler representation. Mark real vs modelled (solid vs ghost/hatch).
5. Auto-scale every axis to fit dragged values — never a fixed axis that clips.
6. NO flashing / opacity-pulse. Steady directional motion only, gated behind @media (prefers-reduced-motion: reduce).
7. Self-contained: one HTML file, inline CSS, no libraries, works offline. Map pointer coords with svg.createSVGPoint() + getScreenCTM().inverse(); call el.setPointerCapture; set touch-action:none.
8. Scale-by-factor handles need a zero-recovery guard (if the base series is all zero, spread the dragged target evenly) and gentle sensitivity.
Pick the representation from the data's shape: comparison -> bars; part-to-whole -> stacked; trend -> cumulative line; distribution -> a curve (not a dot-plot); relationship -> scatter + fit; network/dependency -> a graph (marks are nodes you drag/scrub); trade-off -> a Pareto scatter; composition-over-time -> a stacked area you can smoothly paint.
Kill it if: the point only lands via the caption (it must land from manipulation alone); a number is fabricated; an axis clips; anything flashes; or the manipulation verb fights the data's nature.
Kill-criteria
- The insight only lands if you read the caption — it must land from manipulation alone.
- Any number is fabricated.
- An axis clips instead of auto-scaling.
- Anything flashes or pulses.
- The verb fights the data (e.g. edit a historical fact).
See it in the wild
- The living budget — document
- The critical path — network
- How long, really? — uncertainty
- Fifteen more, in miniature