Skip to main content
196

Search Lumen

Find components, APIs, guides, and recipes.

GitHub
Web docs
Data display

Heatmap

Encodes a labelled matrix with a sequential visualization scale.

FrameworksAstro · React · Elements

Registry commandlumen add Heatmap

InteractionEnhanced runtime

← All chart guides · Framework setup · Native counterparts

01

See it and copy it

Framework example

Explore the live chart, then open its code for Astro, React, or Elements.

AstroCode target · live preview uses Astro

When teams do their best work

Active sessions · 21–27 September 2026 · UTC

55 available heatmap cells.

0124× Not available
View chart data
ColumnRowValue
06:00Monday8
08:00Monday32
10:00Monday78
12:00Monday56
14:00Monday84
16:00Monday62
18:00Monday28
20:00Monday12
06:00Tuesday12
08:00Tuesday46
10:00Tuesday92
12:00Tuesday64
14:00Tuesday110
16:00Tuesday86
18:00Tuesday34
20:00Tuesday16
06:00Wednesday10
08:00Wednesday42
10:00Wednesday86
12:00Wednesday72
14:00Wednesday124
16:00Wednesday94
18:00Wednesday42
20:00Wednesday18
06:00Thursday14
08:00Thursday38
10:00Thursday82
12:00Thursday68
14:00Thursday102
16:00Thursday78
18:00Thursday36
20:00Thursday14
06:00Friday6
08:00Friday28
10:00Friday64
12:00Friday48
14:00Friday72
16:00Friday46
18:00Friday20
20:00Friday8
06:00Saturday0
08:00Saturday4
10:00Saturday18
12:00Saturday26
14:00Saturday22
16:00Saturday14
18:00Saturday8
20:00Saturday2
06:00Sunday2
08:00Sunday6
10:00Sunday14
12:00Sunday20
14:00Sunday18
16:00Sunday12
18:00Sunday6
20:00SundayNot available
Activity peaks on Wednesday at 14:00. Darker cells mean more sessions; × marks a missing observation. Illustrative data.
View Heatmap code

Framework usage

Switch targets to compare the adapter code. This live preview runs the Astro example. React and Elements use their own behavior APIs; complete the matching framework setup before copying an example.
astro
---
import { Heatmap } from '@santi020k/lumen-astro'

const hours = ['06:00', '08:00', '10:00', '12:00', '14:00', '16:00', '18:00', '20:00']

const activity = [
  { day: 'Monday', sessions: [8, 32, 78, 56, 84, 62, 28, 12] },
  { day: 'Tuesday', sessions: [12, 46, 92, 64, 110, 86, 34, 16] },
  { day: 'Wednesday', sessions: [10, 42, 86, 72, 124, 94, 42, 18] },
  { day: 'Thursday', sessions: [14, 38, 82, 68, 102, 78, 36, 14] },
  { day: 'Friday', sessions: [6, 28, 64, 48, 72, 46, 20, 8] },
  { day: 'Saturday', sessions: [0, 4, 18, 26, 22, 14, 8, 2] },
  { day: 'Sunday', sessions: [2, 6, 14, 20, 18, 12, 6, null] }
]

const data = activity.flatMap(({ day, sessions }) => hours.map((hour, index) => ({
  x: hour,
  y: day,
  value: sessions[index] ?? null
})))
---

<Heatmap
  aria-label="Active sessions by weekday and time of day"
  heading="When teams do their best work"
  description="Active sessions · 21–27 September 2026 · UTC"
  caption="Activity peaks on Wednesday at 14:00. Darker cells mean more sessions; × marks a missing observation. Illustrative data."
  {data}
/>
Edit Heatmap in browser

Framework differences

Elements: Pass data as a JSON attribute. The Elements example serializes the sample data with JSON.stringify; Astro expression bindings are not HTML attributes.

When to use Heatmap

Use for a matrix such as weekday by hour, region by product, or another pair of categorical dimensions.

  • The scale legend shows domain endpoints and the diverging midpoint when applicable. Missing observations use a separate × marker.
  • Keep the exact-data disclosure available: readers should not have to estimate values from color. Share the same domain across comparable matrices.

Prepare the data

ts
import type { LumenHeatmapDatum } from '@santi020k/lumen-core'

const data = [
  { x: 'Morning', y: 'Monday', value: 18 },
  { x: 'Afternoon', y: 'Monday', value: 42 },
  { x: 'Morning', y: 'Tuesday', value: null },
  { x: 'Afternoon', y: 'Tuesday', value: 64 }
] satisfies readonly LumenHeatmapDatum[]
  • Each datum identifies a column with x, a row with y, and a finite value or null. Aggregate duplicate row/column pairs before plotting.
  • Use xLabel and yLabel when readable labels differ from the stored identities. Keep numeric source values separate from formatValue output.
  • Use a sequential colorScale for magnitude. Use "diverging" with an explicit meaningful midpoint for differences around a reference.

Shared data and formatting guidance →

Avoid misleading comparisons

  • Do not treat missing cells as zero activity. Supply explicit null observations where absence needs to remain visible.
  • A heatmap is best for patterns, not small numerical differences. Use a table or bars when precise comparisons are the primary task.

Chart accessibility and keyboard guidance →

02

Choose your target

Add this component

Choose the package for your runtime. All adapters share the Lumen stylesheet. Use the matching registry command when you want a local wrapper for that framework.

bash@santi020k/lumen-astro
pnpm add @santi020k/lumen-astro
pnpm add @santi020k/lumen-astro
bashAstro wrapper
lumen add Heatmap
lumen add Heatmap

API reference

Lumen-specific props and runtime attributes for the Astro primitive. Use the framework differences above and the copyable examples for React composition and Elements attributes; the public adapter types define their supported contracts.

AttributeValuesDefaultDescription
colorScale, midpoint"sequential" | "diverging", number"sequential", 0Uses semantic color scales with an explicit midpoint for diverging values.
showLegendbooleantrueShows scale endpoints and the distinct missing-data marker.
drilldownboolean (Astro / Elements attribute)falseEnables plotted datum actions and an equivalent native button disclosure, including with hidden tables. Astro requires UIPrimitives; Elements owns its lifecycle.
onDatumActivate(detail: LumenChartDatumActivationDetail) => void (React)-Enables React datum actions and receives validated values with raw identities. Navigation and filtering remain application owned.
explore-data-label, datum-action-prefix, datumActionFormatterstring attributes, (context: string) => string property (Elements)English labelsLocalizes the Elements disclosure and datum actions.
labels.exploreData, labels.formatDatumActionstring, (context: string) => stringEnglish labelsLocalizes the actions disclosure and each contextual datum button.
dataLumenHeatmapDatum[][]Provides labelled row, column, and intensity values for the heatmap cells.
formatValue(value: number) => stringStringFormats finite cell values in titles and the accessible data table.
showTablebooleantrueProvides a revealable semantic table for every heatmap cell.
class, classNamestring""Merges custom classes with the generated ui-* root classes.
...native attributesHTML attributes-Forwards standard attributes to the root element unless the component consumes them.

Keyboard interactions

Keyboard behavior provided by the Astro UIPrimitives runtime for this component.

KeyAction
TabFocus the actions disclosure and its native buttons in document order.
Enter, SpaceToggle the disclosure or activate the focused datum button. Actions remain available when the data table is hidden.

Runtime events

CustomEvents dispatched by the Astro UIPrimitives runtime for this component.

EventTargetDetailWhen
ui:chart-datum-activateAstro chart figure or Elements data chart hostLumenChartDatumActivationDetail: series { seriesId, x, y, datumId? }, heatmap { x, y, value, datumId? }, range { x, low, high, datumId? }Fires once after a plotted datum or its native action button is activated. Requires drilldown. Astro uses UIPrimitives, Elements owns its lifecycle, and React uses onDatumActivate instead.

Web docsFull catalog