caliper uidocs

Heatmap matrix

Free

Two categories against each other, coloured by value. The row and column follow the pointer or arrow keys, and choosing a step of the scale isolates its cells.

Installs components/ui/heatmap-matrix.tsxDepends on d3-shapeMotion none in component source
pnpm dlx shadcn@latest add https://caliperui.site/r/heatmap-matrix.json
Support tickets by weekday and hour (UTC)
000204060810121416182022
Mon
Tue
Wed
Thu
Fri
Sat
Sun
1 tickets
47 tickets

When to use #

Use it for

  • Weekday by hour, feature by plan, error by service.
  • Spotting the busy or broken corner of a grid.

Skip it when

  • Calendar days over a year; use the activity heatmap.
  • Exact comparisons; colour is approximate, so keep the table.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/heatmap-matrix.json

Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

This is the code behind the preview above. It is built from bucketOf and HeatmapMatrix.

example.tsx
import { HeatmapMatrix } from "@/components/ui/heatmap-matrix"

const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

const hours = Array.from({ length: 12 }, (_, i) => `${String(i * 2).padStart(2, "0")}`);

const busy = days.map((_, d) => hours.map((_, h) => (d === 2 && h === 7 ? undefined : Math.round((d < 5 ? 40 : 12) * Math.max(0.1, Math.sin(((h - 2) / 11) * Math.PI)) + ((d * 7 + h * 3) % 9)))));

export function HeatmapMatrixDemo() {
  return <HeatmapMatrix label="Support tickets by weekday and hour (UTC)" rows={days} columns={hours} values={busy} unit=" tickets" className="w-full" />;
}

API reference #

bucketOf

component

No props of its own; it accepts the native props of its root element.

HeatmapMatrix

component
PropTypeDefaultDescription
label *string—
rows *readonly string[]—
columns *readonly string[]—
values *readonly (readonly (number | undefined)[])[]—values[row][column]; undefined means no reading.
unitstring""
formatValue((value: number) => string)numberText
stepsnumber5
loadingboolean—
errorstring—
classNamestring—

Accessibility #

It exposes grid, row, columnheader, rowheader, gridcell and group semantics, with aria-label, aria-busy and aria-pressed kept in step with state.

KeyBehaviour
→Moves to the next item or value.
←Moves to the previous item or value.
↓Moves to the next item or value.
↑Moves to the previous item or value.
HomeJumps to the first item or the minimum.
EndJumps to the last item or the maximum.
EscapeCloses or cancels, then returns focus to where it came from.

Motion #

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.