Skip to content
microcharts
ReferenceDecisionQuantileDots

QuantileDots

React quantile dots chart — sample or posterior as quantile dots against a decision threshold. Tiny accessible SVG microchart; RSC-safe static or /interactive.

QuantileDots answers "what are the odds?" — in countable form. It's a quantile dotplot: each dot is an equal-probability quantile, so a dot is roughly a 1-in-N chance, not a raw observation. Add a threshold and the plot turns from shape into odds: the dots past the line are re-inked and ringed, and the summary reads "N in 20" — because odds you can count beat odds you must trust, and a frequency reads truer than a bare percentage.

QuantileDots
interactive · 5.4 kB · static · 2.74 kB

Install

Import & usereact/quantile-dots
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)),);
Needs package + stylesheetSet up with AI

Try it

When to use it

  • Good for — a "will we miss the SLA?" read in a sentence, odds you can count in a KPI card, a posterior communicated as frequency rather than percent.
  • Avoid for — a precise distribution shape (HistogramStrip) or one estimate's interval (GradedBand).

Sizing

Variants

fewer dots + count below

format also takes Intl.NumberFormatOptions — with a locale, the announced threshold follows that locale's own grouping and decimal marks.

locale

Edge cases

empty
all-equal sample (certainty)
threshold outside the data range

Empty data draws nothing and the summary says so plainly. An all-equal sample collapses every dot into one column — genuine certainty, not a rendering glitch. A threshold outside the observed range reads as 0 in N (or N in N) — the count is always honest about what fraction of the field it's actually catching.

Four homes

Why this default

20 dots, because odds you can count beat odds you must trust — a reader subitizes a handful of highlighted dots faster than they parse "48%". Each dot is an equal-probability quantile, not a raw observation, and the summary always frames the answer as a frequency ("10 in 20"), never a bare percentage. Dots past the threshold are re-inked and ringed, so the count survives grayscale, print, and forced-colors.

Accessibility

The accessible name states the odds in frequency form — "8 in 15 chances above 15 min." — or, without a threshold, "Most likely …; range …". The interactive entry is a probe: 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

PropTypeNotes
data*number[]Raw sample or posterior draws — the component derives the quantile dots.
countnumberNumber of quantile dots (default 20; 15–20 recommended; capped at 25).
thresholdnumberThe decision line — turns the plot from shape into odds.
side"above" | "below"Which side of the threshold is the event being counted.
animatebooleaninteractiveOpt-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.

Related charts