QuantileDots
QuantileDots draws a sample or posterior as countable quantile dots and reports the odds past a threshold as a frequency.
- encodes
- countable dot frequency past a threshold
- precision
- high for the count, medium for shape
- nodes
- 1 per dot + 3
QuantileDots draws a sample or a posterior as 20 dots, each one an equal-probability quantile. A dot is therefore about
a 1-in-N chance, not a raw observation. Add a threshold and the dots past the line are re-inked and ringed, and
the summary reports the answer as a frequency ("10 in 20") rather than a percentage. Two cues carry the count, so it
survives grayscale, print, and forced-colors.
Install
import { QuantileDots } from "@microcharts/react/quantile-dots";// waits — real values under “Sample data” below<QuantileDots data={waits} threshold={15} format={(n) => `${n} min`} title="Bus wait" />Sample data
// bus-wait times (minutes): right-skewed, a long tail past the 15-min SLAconst waits = Array.from({ length: 200 }, (_, i) => Math.round(4 + (i % 30) * 0.35 + ((i * 7) % 13) * 1.1 + (i % 50 === 0 ? 20 : 0)),);Try it
When to use it
Use it for a "will we miss the SLA?" read in a sentence, countable odds in a KPI card, and a posterior communicated as a frequency rather than a percent. For a precise distribution shape use HistogramStrip; for one estimate's interval use GradedBand.
Sizing
Variants
format also takes Intl.NumberFormatOptions — with a locale, the announced threshold follows that locale's own
grouping and decimal marks.
Edge cases
Empty data draws nothing and the summary says so. An all-equal sample collapses every dot into one column: that is certainty in the sample, not a rendering glitch. A threshold outside the observed range reads as 0 in N (or N in N), so the count always reports the fraction of the field it catches.
Use count to change how many dots the sample is quantized into; 20 is the default because a reader subitizes a handful
of highlighted dots faster than they parse "48%".
Four homes
Accessibility
The accessible name states the odds as a frequency: "8 in 15 chances above 15 min." Without a threshold it reads
"Most likely …; range …" instead. In the interactive entry, hovering or arrowing moves a live threshold and the count
past it recomputes as you go.
The interactive entry follows the shared interaction contract:
arrow keys rove between units on both axes, Home and End jump to the ends, and a click, tap, Enter or
Space selects a unit — pinning its readout so it survives blur, until you select it again or press Escape.
On touch, a tap pins and a drag scrubs.
Props
| Prop | Type | Notes |
|---|---|---|
| data* | number[] | Raw sample or posterior draws — the component derives the quantile dots. |
| count | number | Number of quantile dots (default 20; 15–20 recommended; capped at 25). |
| threshold | number | The decision line — turns the plot from shape into odds. |
| side | "above" | "below" | Which side of the threshold is the event being counted. |
| animate | boolean | interactiveOpt-in entrance motion when the chart mounts client-side — add import "@microcharts/react/motion" once. Inert on the server, on hydrated server HTML, and under prefers-reduced-motion. |
Plus the shared grammar — data, domain, color, title, summary, format — and the layout props (width, height, className, style) that every chart accepts. Interactive entries also share animate and live, and — wherever a chart has more than one navigable unit — onActive, onSelect, selectedIndex and defaultSelectedIndex; and — wherever the chart shows a hover value — readout. See the shared grammar.