Skip to content
microcharts
ReferenceExpressiveGardenGrid

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".

GardenGrid
interactive · 4.46 kB · static · 1.94 kB

Install

Import & usereact/garden-grid
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];
Needs package + stylesheetSet up with AI

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

strip mode + blank empties

Edge cases

empty data
all-zero (present, quiet — never missing)
nulls render nothing (missing ≠ zero)
single cell

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

PropTypeNotes
data*(number | null)[]Binned values; null = missing.
rowsnumberGrid rows (default 7); 1 = strip.
steps3 | 5Radius quantization steps (default 5).
empty"outline" | "blank"How zero cells render (default outline).
unitstringNoun for the summary count (default "periods").
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