Heatmap Grid

Weekday12a6a12p6p
Mon
Tue
Wed
Thu
Fri
Sat
Sun
Busiest: Saturday, 9 PM (61 sessions)
About this component

Heatmap Grid

A heatmap by two axes, weekday by hour out of the box: one shaded square per slot on the heatmap family's scale, with thresholds from the data's quantiles or your own. Weekday names and hours come from Intl in any locale, the week starts on Sunday or Monday, hours read in 12 or 24 hour style, and hour labels thin out as the grid narrows. Hovering or focusing a slot lifts it, dims everything outside its row and column into a soft crosshair and shows a tooltip; the grid is one tab stop with arrow keys, the busiest slot is named beside a Less to More legend, and slots can be made selectable. Custom row and column labels turn it into any two-axis grid. Cells share the width and never shrink below their size; a narrow frame scrolls sideways.

Usage

The import and the props worth knowing about, in one place.

import { HeatmapGrid } from "@/components/beste/component/heatmap-grid";

// data[weekday][hour], with data[0] as Sunday
<HeatmapGrid
  data={sessions}
  weekStartsOn={1}              // 0 Sunday (default) | 1 Monday
  unit={["session", "sessions"]}
  label="Listening sessions by weekday and hour"
/>

// Any two axes
<HeatmapGrid
  data={[[4, 9, 2], [7, 1, 5]]}
  rows={["Paris", "Lisbon"]}
  columns={["Q1", "Q2", "Q3"]}
  color="#10b981"               // any CSS color; defaults to the primary token
  onSelectedChange={(cell, value) => console.log(cell, value)}
  tone="outline"                // "muted" (default) | "outline" | "ghost"
  size="lg"                     // "sm" | "default" | "lg"
/>

Keyboard and gestures

Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.

Arrow keysMove between slots; the grid is one tab stop.
Home / EndThe first or last slot of the row.
Cmd or Ctrl + Home / EndThe first or last slot of the grid.
Page Up / Page DownThe top or bottom of the column.
Enter / SpaceSelect the slot, when slots are selectable.

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
datanumber[][]—Values by row, then column. With the default axes, `data[0]` is Sunday and each row holds 24 hours; with `rows` and `columns` it is laid out as given.
rowsstring[]—Custom row labels. Replaces the weekdays and turns off `weekStartsOn`.
columnsstring[]—Custom column labels. Replaces the hours.
weekStartsOn0 | 1—0 starts the week on Sunday, 1 on Monday. Weekday rows only.
localestring—Locale for weekday names, hours and numbers.
hourCycle"auto" | "12" | "24"—12 or 24 hour labels. "auto" follows the locale.
colorstring—The scale's strongest color, any CSS color. Lighter levels are mixed from it.
levelsnumber—Number of shades including the empty one, 3 to 9.
thresholdsnumber[]—Lowest value of each non-empty level, ascending. Computed from quantiles when left out.
unit[string, string]—Singular and plural word for the value, used in labels, the tooltip and the peak.
formatValue(value: number, cell: HeatmapGridCell) => string—Custom text for a cell's value.
labelstring—Accessible name of the grid.
showLegendboolean—
showPeakboolean—Names the busiest cell beside the legend.
selectedHeatmapGridCell | null—Selected cell, controlled. Cells become selectable when this or `onSelectedChange` is set.
defaultSelectedHeatmapGridCell | null—
onSelectedChange(cell: HeatmapGridCell, value: number) => void—
size"sm" | "default" | "lg"—
tone"muted" | "outline" | "ghost"—
classNamestring—

More Heatmap components

View all Heatmap
1,198 commits in the last 53 weeks