GardenGrid
React garden grid chart — many small states as a garden of cells in one glance. Tiny accessible SVG microchart; RSC-safe static or /interactive.
GardenGrid answers "what's the rhythm of activity over time?" the way ActivityGrid does — but with a single ink. Instead
of color, dot area carries a five-step ordinal, so the rhythm reads in grayscale and print where a color heatmap
would collapse. The radius is √-quantized so perceived area steps evenly. A zero cell is a hairline ring (present, but
quiet); a null cell is nothing at all, because "missing" is not "zero".
Install
import { GardenGrid } from "@microcharts/react/garden-grid";// weeks — real values under “Sample data” below<GardenGrid data={weeks} title="Activity" unit="weeks" />Sample data
// 12 weeks of activity, some quietconst weeks = [12, 20, 8, 0, 15, 28, 34, 5, 0, 22, 18, 9, 3, 0, 24, 30, 11, 6, 19, 0, 26];Try it
When to use it
- Good for — a contribution or activity rhythm you print or read in grayscale, a per-repo or per-team activity strip, or any calendar-shaped intensity where color isn't available.
- Avoid for — exact per-cell values (ActivityGrid with hover, or HeatStrip) or trends (Sparkline).
Sizing
Variants
Edge cases
Four homes
Why this default
Rings for zero are the default because print and grayscale lose the zero-versus-missing distinction that color grids get
for free — this chart exists for exactly that medium, so it makes "present but quiet" visible. The radius is √-quantized
so area carries the ordinal; a linear radius map would exaggerate the highs quadratically. The steps are ordinal,
not values — the interactive entry announces a cell's step rather than implying a precise read, and ActivityGrid is
the color twin when exact values matter.
Accessibility
The accessible name summarizes the rhythm — "12 periods; peak 34, 10 active." The interactive entry walks the grid in 2-D with the arrow keys (or hover), announcing each cell as its ordinal step — "3 of 21: 8, step 2 of 5." — never a false-precise value, since dot area reads to a step, not a number.
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 | null)[] | Binned values; null = missing. |
| rows | number | Grid rows (default 7); 1 = strip. |
| steps | 3 | 5 | Radius quantization steps (default 5). |
| empty | "outline" | "blank" | How zero cells render (default outline). |
| unit | string | Noun for the summary count (default "periods"). |
| 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.
Related charts
SproutRow
React sprout row chart — growth across items as sprouting marks from a shared baseline. Tiny accessible SVG microchart; RSC-safe static or /interactive.
BubbleRow
React bubble row chart — circle area for a few magnitudes — honest low-precision part-to-whole. Tiny accessible SVG microchart; RSC-safe static or /interactive.