Skip to documentation content

Heatmap

A composable heatmap for finding patterns across two categorical dimensions.

Basic Heatmap

Overview

Use a heatmap to reveal clusters, quiet periods, and outliers across two categorical dimensions. The default variant uses a continuous color scale; choose the blocks variant when discrete intensity bands are easier to scan.

Anatomy

Heatmap owns the flat cell data, category axes, value range, loading state, and color scale. Add XAxis and YAxis for context, Cells for the rendered matrix, and optional Grid, Legend, and Tooltip parts.

Accessibility

Color is not enough when exact values matter. Provide a clear ariaLabel and pair the canvas with a data table or text summary in reporting workflows. The tooltip and calculable legend are pointer-operated, so they cannot be the only path to required values or filtering. Use labels or a sufficiently distinct multi-stop palette for discrete levels.

Installation

npm install honestui

Usage

The data is a flat array with one row per cell. xDataKey and yDataKey define the categories, while valueDataKey selects the numeric intensity and matching chart config entry.

import { Heatmap, type ChartConfig } from "honestui/charts";
<Heatmap
  data={data}
  config={chartConfig}
  xDataKey="day"
  yDataKey="hour"
  valueDataKey="requests"
>
  <Heatmap.Grid />
  <Heatmap.XAxis />
  <Heatmap.YAxis />
  <Heatmap.Legend minLabel="Quiet" maxLabel="Busy" />
  <Heatmap.Tooltip />
  <Heatmap.Cells variant="default" />
</Heatmap>

ECharts renders to a <canvas>, so the compound children are declarative configuration rather than live DOM nodes. Colors come from the same theme-aware ChartConfig used by every Honest UI chart.

Blocks Variant

variant='blocks'

The blocks variant divides the value range into discrete buckets and gives each cell more separation. Use levels to control how many intensity steps are shown.

Dense Field

Dense continuous field

Dense matrices can read like a continuous field by removing cell gaps, using a multi-stop diverging palette, disabling intro animation, and enabling progressive rendering. The vertical calculable legend keeps the full value range visible without competing with the x-axis. This example leaves out per-cell hover interaction so the canvas remains responsive while rendering thousands of cells.

Loading State

isLoading='true'

Pass isLoading to reserve the chart layout with a neutral cell matrix and the same loading treatment as the other Honest UI charts.

API Reference

Heatmap
PropTypeDefaultDescription
data*TData[]

A flat array of cell objects (TData extends Record<string, unknown>).

config*ChartConfig

Defines the label and theme colors for valueDataKey.

xDataKey*keyof TData & string

The categorical data key shown on the horizontal axis.

yDataKey*keyof TData & string

The categorical data key shown on the vertical axis.

valueDataKey*keyof TData & string

The numeric cell value. The same key should exist in config.

childrenReactNode

The composed Grid, XAxis, YAxis, Legend, Tooltip, and Cells parts.

classNamestring

Additional CSS classes for the chart container. Give the chart an explicit height.

minnumber

Lower bound of the color scale. Defaults to the smallest value in data.

maxnumber

Upper bound of the color scale. Defaults to the largest value in data.

animationbooleantrue

Enables the intro animation. Reduced-motion preferences disable it automatically.

isLoadingbooleanfalse

Replaces the data with a neutral loading matrix and progress label.

loadingColumnsnumber7

Number of placeholder columns in the loading matrix.

loadingRowsnumber5

Number of placeholder rows in the loading matrix.

ariaLabelstring

Accessible name for the canvas chart. A descriptive label is generated when omitted.

onCellClick(cell: HeatmapCell<TData>) => void

Fires when a cell with isClickable enabled is selected.

chartOptionsRecord<string, unknown>

Escape hatch merged over the generated ECharts option object.

Cells
PropTypeDefaultDescription
variantdefault|blocks"default"

Uses a continuous value ramp or discrete intensity buckets.

radiusnumber2

Cell corner radius in pixels. Blocks default to 1.

gapnumber2

Space between cells in pixels. Blocks default to 4.

levelsnumber5

Number of discrete buckets used by the blocks variant.

isClickablebooleanfalse

Enables the pointer cursor and onCellClick callback.

showValuesbooleanfalse

Displays each numeric value inside its cell.

valueFormatter(value: number) => string

Formats labels rendered inside cells.

progressivenumber

Number of cells rendered per progressive chunk. Useful for dense matrices.

progressiveThresholdnumber

Cell count above which progressive rendering begins.

XAxis / YAxis
PropTypeDefaultDescription
tickFormatter(value: string, index: number) => string

Formats category labels without changing the underlying values.

labelstring

Axis title.

hidebooleanfalse

Hides the axis labels while preserving the categories.

inversebooleantrue

YAxis only. Places the first category at the top of the matrix.

Tooltip
PropTypeDefaultDescription
variantdefault|frosted-glass"default"

Tooltip surface treatment.

roundnesssm|md|lg|xl"lg"

Tooltip corner radius.

positionfixed|variable"variable"

Pins the tooltip to the top or lets it follow the active cell.

valueFormatter(value: number) => string

Formats the value shown in the tooltip.

defaultIndexnumber

Opens the tooltip on a specific cell after mount.

Legend
PropTypeDefaultDescription
alignleft|center|right"center"

Horizontal alignment of the value scale.

orienthorizontal|vertical"horizontal"

Lays the value scale below the chart or beside the matrix.

verticalAligntop|middle|bottom"middle"

Vertical placement of a vertical legend.

calculablebooleanfalse

Adds draggable range handles to a continuous legend.

realtimebooleanfalse

Updates the matrix while a calculable handle moves. Keep this disabled for dense fields to apply the range after dragging.

minLabelstring

Custom low-end label for the continuous legend.

maxLabelstring

Custom high-end label for the continuous legend.

valueFormatter(value: number) => string

Formats numeric legend labels.