Vesture

Charts

HeatmapNew in 0.7.0

A rows × columns matrix colored by value — activity by hour, correlation tables, cohort retention. Single-hue by default, or bring any color scale.

Heatmap

Preview

9a11a1p3p5p7pMonTueWedThuFriMon / 11a: 2828Mon / 1p: 6565Mon / 3p: 7878Mon / 5p: 3737Tue / 9a: 6565Tue / 11a: 3737Tue / 1p: 7979Tue / 3p: 5353Tue / 7p: 7979Wed / 9a: 3737Wed / 11a: 4545Wed / 1p: 5252Wed / 5p: 6565Wed / 7p: 7070Thu / 9a: 7979Thu / 11a: 5252Thu / 3p: 7575Thu / 5p: 7474Thu / 7p: 3636Fri / 9a: 5353Fri / 1p: 7575Fri / 3p: 2828Fri / 5p: 7979Fri / 7p: 4646

Click a cell.

Usage

tsx
import { Heatmap } from "@vesture/react";

<Heatmap
  rows={["Mon", "Tue", "Wed"]}
  columns={["9a", "1p", "5p"]}
  values={[[12, 40, 25], [30, null, 18], [44, 51, 9]]}
  width={520}
  height={240}
  domain={[0, 60]}
  emptyColor="#eee"
  colorScale={(t) => `hsl(210 70% ${95 - t * 55}%)`}
  onCellClick={({ row, column, value }) => inspect(row, column, value)}
/>

Behavior

  • By default cell opacity encodes value within the matrix's own min–max in one color. domain pins that range so two heatmaps are comparable, and values outside it clamp.
  • colorScale maps a normalized 0–1 intensity (and the raw value) to any CSS color — use it for diverging scales (blue ↔ red around zero) or multi-hue ramps.
  • null cells are left empty, or painted with emptyColor. Values print inside cells when they fit, switching text color for contrast; renderCell replaces that content.
  • onCellClick receives row/column names and indexes, including for empty cells, so a drill-down can explain a gap.

Props

PropTypeDefaultDescription
rows / columnsstring[]—Required. Axis labels.
values(number | null)[][]—Required. values[row][column].
width / heightnumber—Required.
colorstringchart series 1High-end color for the default opacity scale.
colorScale(t: number, value: number) => string—Overrides color; cells render fully opaque.
domain[number, number]—Pins the min/max mapped to 0 and 1.
emptyColorstring—Fill for null cells.
gap / cellRadiusnumber2 / 0
rowLabelWidth / columnLabelHeightnumber72 / 28Gutters for axis labels.
showValuesbooleantruePrint values in cells that are big enough.
formatValue(value: number) => stringString
renderCell({ row, column, value, t, width, height }) => ReactNode—Custom SVG inside a cell.
onCellClick({ row, column, value, rowIndex, columnIndex }) => void—