Charts

Heatmap and CohortChart

A matrix of cells colored by value, and cohort retention grids

A heatmap places rows of data in a grid: one field picks the column, one picks the row, and a third sets the color. Use it for patterns over two dimensions, such as visits by weekday and hour.

Weekday and hour

Columns and rows follow the order in which values first appear in data. Pass x-domain and y-domain to set the order yourself or to show columns that have no data. Rows with the same column and row are added up. Column labels thin out on narrow screens so they never overlap.

Cohort retention

CohortChart is a heatmap for retention. Each row is a cohort, for example everyone who signed up in January. values[0] is the cohort's size and values[n] is how many were still active n periods later. Each cell shows the share of the cohort. Periods a cohort has not reached yet stay blank, so the grid forms a triangle.

Set mode="count" to show the counts instead of percentages.

Heatmap props

PropTypeDefaultDescription
dataRow[]requiredRows with a column, a row and a value
x-key / y-key / data-keyrow path or accessor'x' / 'y' / 'value'Fields for column, row and value
x-domain / y-domain(string | number)[]order of appearanceColumn and row order
color / empty-colorstringseries 1 token / var(--v-charts-muted)Full and empty color
levelsnumber00 mixes colors continuously; a number gives that many steps
colorsstring[]—Explicit fill per level, from empty to full
maxnumberlargest valueValue that reaches full color
fill-missingbooleantrueDraw pairs without data as empty cells
show-valuesbooleanfalseDraw each value on its cell when it fits
value-formatter(value, cell) => stringlocale number format (1,234)Value text in cells, the tooltip and accessible names. String keeps raw numbers
localestring'en-US'Number format of the default value text
x-tick-formatter / y-tick-formatter(key) => stringStringText for column and row labels
x-labels / y-labelsbooleantrueShow the labels
gap / radiusnumber2 / 2Space between cells and corner radius
active-indexnumber | null—Rendered cell position, for v-model:active-index
width / height / aspectnumberfull width, 28 px per rowSize

CohortChart props

PropTypeDefaultDescription
dataRow[]requiredOne row per cohort, oldest first
cohort-key / values-keyrow path or accessor'cohort' / 'values'Fields for the cohort name and its counts
mode'percent' | 'count''percent'Share of the cohort size, or raw counts
period-formatter(period) => stringStringColumn heading per period
color / empty-colorstringas HeatmapColors
active-indexnumber | null—Rendered cell position, for v-model:active-index
value-formatter(value, cell) => stringrounded percent (42%) or locale countValue text in the tooltip and accessible names; value is the percent or the count, by mode
localestring'en-US'Number format of counts and cohort sizes

Both share the Tracker's events, #cell slot and keyboard navigation. Heatmap events and the cell slot receive HeatmapCell<Row> with { x, y, value, rows }; missing cells have no contributing rows. CohortChart receives CohortCell<Row> with row, rows and period; row is the first contributing source row.

Bind v-model:active-index to control selection; null clears it. Pointer and keyboard changes request an update. See Events and v-model for control precedence.

The row type Row is inferred from data. Key props accept typed row paths or accessors.

Copyright © 2026