Data
Heatmap
Magnitude across two dimensions — a publishing calendar, an hour × weekday grid, a cohort table.
Heatmap
import { Heatmap } from '@anomalia/ui'; Notes
- Sequential means one hue, light to dark, never a rainbow: the whole point of the form is that "darker" reads as "more" without a lookup. The ramp is achromatic here, which is the most literal reading of the encoding and keeps the grid inside a monochrome palette.
- **Empty is not zero.** A cell with no data gets the surface and a hairline; a real zero gets the first ramp step. Painting both the same turns "we did not measure this" into "this was nothing" — the single most common heatmap lie.
- Values are binned into six classes rather than mapped continuously. Past about seven classes adjacent bins stop being distinguishable, so more resolution would be precision the eye cannot read.
- A scale legend is not optional. Colour on a continuous scale with no key is a puzzle, and two labelled ends plus the swatches answer it in a glance.
- Cells stay square and the grid scrolls sideways inside its own box. A calendar stretched to fit a card reads as a bug; a calendar that widens the page is worse.
Examples
Calendar
Sequential, so one hue light→dark and never a rainbow. Empty is not zero: a cell with no data gets the surface and a hairline, a real zero gets the first ramp step — painting both alike turns "not measured" into "nothing happened".
| W20 | W21 | W22 | W23 | W24 | W25 | W26 | W27 | W28 | W29 | W30 | W31 | W32 | W33 | W34 | W35 | W36 | W37 | W38 | W39 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Mon | 3 posts | 2 posts | 0 posts | 3 posts | 1 posts | 2 posts | 2 posts | 1 posts | 2 posts | 2 posts | 3 posts | 3 posts | 2 posts | 1 posts | 1 posts | 0 posts | 2 posts | 2 posts | no data | no data |
| Tue | 1 posts | 2 posts | 1 posts | 1 posts | 0 posts | 1 posts | 0 posts | 0 posts | 3 posts | 3 posts | 0 posts | 2 posts | 2 posts | 2 posts | 1 posts | 2 posts | 0 posts | 0 posts | no data | no data |
| Wed | 4 posts | 3 posts | 5 posts | 4 posts | 3 posts | 4 posts | 5 posts | 5 posts | 4 posts | 3 posts | 3 posts | 3 posts | 2 posts | 2 posts | 2 posts | 3 posts | 3 posts | 3 posts | no data | no data |
| Thu | 3 posts | 0 posts | 2 posts | 3 posts | 1 posts | 2 posts | 0 posts | 2 posts | 3 posts | 2 posts | 1 posts | 1 posts | 1 posts | 2 posts | 3 posts | 2 posts | 3 posts | 2 posts | no data | no data |
| Fri | 1 posts | 2 posts | 3 posts | 1 posts | 2 posts | 2 posts | 1 posts | 1 posts | 1 posts | 2 posts | 2 posts | 2 posts | 2 posts | 0 posts | 1 posts | 1 posts | 2 posts | 2 posts | no data | no data |
| Sat | 1 posts | 1 posts | 1 posts | 0 posts | 0 posts | 1 posts | 0 posts | 1 posts | 1 posts | 1 posts | 1 posts | 1 posts | 0 posts | 0 posts | 0 posts | 1 posts | 0 posts | 1 posts | no data | no data |
| Sun | 0 posts | 0 posts | 1 posts | 0 posts | 1 posts | 0 posts | 1 posts | 0 posts | 1 posts | 1 posts | 1 posts | 1 posts | 1 posts | 1 posts | 1 posts | 0 posts | 1 posts | 1 posts | no data | no data |
0 5 posts
API
| Prop | Type | Default | Description |
|---|---|---|---|
cells | HeatCell[] | — | `{ x, y, value }`, where `value: null` means not measured. |
columns / rows | string[] | — | Explicit order. Omit to take first-seen order from the cells. |
size | number | 14 | Cell edge in px. Cells stay square. |
max | number | — | Fixed ceiling for the scale. |
unit | string | — | What one unit is — shown in the legend and in each cell’s title. |
Every component also forwards the native attributes of its root element, plus class, so anything not listed here still works.