QuadrantDot
QuadrantDot shows which quadrant of a 2×2 an item falls in, plotted against the field of peers around it.
- encodes
- 2-D position vs a quadrant split
- precision
- medium
- nodes
- ≤ 5 + 1 per ghost (cap 30)
QuadrantDot places a focal dot by its 2-D position, marks the split with a hairline cross, and draws the peers as tiny
muted ghosts. The split defaults to the domain midpoints and takes an override, but it is never hidden: it renders
wherever the split truly is. The first read is which quadrant the item sits in against the field; exact position is the
second read, which is what keeps the chart legible at 24×24. At that size the axes carry no labels, so pass xLabel,
yLabel, and a title — the accessible name is doing the naming.
Install
import { QuadrantDot } from "@microcharts/react/quadrant-dot";// item, backlog — real values under “Sample data” below<QuadrantDot data={item} field={backlog} xLabel="effort" yLabel="impact" title="Effort vs impact" />Sample data
// a prioritization backlog — effort (x) vs impact (y)const item = { x: 3, y: 9 };const backlog = [ { x: 2, y: 8 }, { x: 8, y: 9 }, { x: 3, y: 7 }, { x: 9, y: 2 }, { x: 7, y: 3 }, { x: 1, y: 1 }, { x: 5, y: 6 }, { x: 6, y: 8 }, { x: 4, y: 3 }, { x: 8, y: 5 }, { x: 2, y: 4 }, { x: 7, y: 7 }, { x: 3, y: 2 }, { x: 6, y: 1 },];Try it
When to use it
Use it for the classic prioritization 2×2 (one cell per initiative in a table), an effort-vs-impact read in a KPI card, and any "which quadrant, against the field" decision. For a full scatter plot use MicroScatter; for a single ranked list use MiniBar.
Sizing
Variants
Edge cases
When every field value on one axis equals the focal's, that axis's domain collapses to a point. The split line on that axis is dropped rather than drawn at an arbitrary spot, while the other axis's split still renders. A peer exactly on top of the focal is still counted (distance 0) and sorts first in the interactive entry's nearest-first order. A non-finite focal position draws no marks at all: no cross, no tint, no peers. It carries the "No data." summary, the same degenerate path an empty series takes elsewhere in the library.
Four homes
Accessibility
The accessible name states the focal position and the axis-relative quadrant: "Impact 9, effort 3 — in the
high-impact, low-effort quadrant." With a field it adds how crowded that quadrant is, and
quadrants={["quick win", …]} replaces the generated quadrant names with your own. The interactive entry starts on the
focal, then cycles the peers nearest-first, announcing each one's coordinates and quadrant.
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* | { x; y } | The focal item's 2-D position. |
| field | { x; y }[] | The peer set — omit for a lone glyph. |
| xDomain | [number, number] | The x-axis range (default: derived from the data); domain stays the y-axis. |
| domain | [number, number] | The y-axis range (default: derived from the data). |
| split | [number, number] | The quadrant boundary (default domain midpoints) — never hidden. |
| quadrants | [TL, TR, BL, BR] | Names in reading order — summaries only, never rendered. |
| xLabel / yLabel | string | Axis nouns for the summary — pass them, the axes are unlabeled at glyph size. |
| region | boolean | Faint tint on the focal's quadrant (default true; false for dense grids). |
| 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.