Chart 5 of 15

Heatmap

Use it to spot patterns across two dimensions, such as category against month. Shade each row on its own scale when rows differ in size and you care about shape.

Live demo

Made-up data. Try the options, then switch to the empty and one-point states.

Tab to a cell to read its value; click or Enter to drill down. The grid scrolls sideways on a phone.

How to use it

JavaScript
const chart = heatmap({
  rows: ['Groceries', 'Housing', 'Eating out'],
  cols: months,                    // ['2025-10', '2025-11', ...]
  collabel: monthName,
  matrix: [
    [412, 389, 455, /* ... */],
    [1150, 1150, 1210, /* ... */],
    [188, null, 301, /* ... null = no data */]
  ],
  norm: 'row',                     // each row on its own scale
  showValues: true,
  fmt: v => '£' + Math.round(v),
  onClick: (r, c) => openCell(r, c),
  label: 'Spending by category and month'
});

Options

rows / cols
Arrays of labels. cols can be formatted with collabel.
matrix
matrix[row][col] numbers. null means no data (drawn as an empty cell, not zero).
norm
'row' scales each row to its own maximum; anything else uses one global scale.
showValues
Prints compact values inside dark cells when they are wide enough.
fmt / unit
Value formatter and the label used in the tooltip.
onClick
(rowIndex, colIndex) => void.