HeatmapChart
Defined in: packages/pixi-charts/src/charts/HeatmapChart.ts:163
Heatmap chart — categorical × categorical grid, coloured by a quantitative value field.
Rendering: texture-from-buffer (one draw call)
Section titled “Rendering: texture-from-buffer (one draw call)”For an MxN grid of coloured cells, three options were considered:
Graphicsrectangles, one per cell — collapses past ~10⁴ cells; not viable as a default.- Custom WebGL shader — fastest possible, but adds a
shader-compilation/debugging surface not justified for v1. Same posture
ScatterCharttook toward shaders. - Texture-from-buffer — allocate a
Uint8ClampedArrayof(width * height * 4)RGBA bytes wherewidth/heightare the grid dimensions (not pixel dimensions), wrap it in a Texture via a BufferImageSource, render as a single Sprite stretched across the plot area. One draw call regardless of grid size, GPU- native scaling, and resize is free — only the sprite’s pixelwidth/heightchange, the texture itself is reused.
The choice is texture-from-buffer. Custom shaders remain a documented future optimisation.
Crisp cells via scaleMode: 'nearest'. When the (small) texture is
stretched across the (much larger) plot area, the default linear
interpolation produces fuzzy gradients across cell borders — wrong for
discrete heatmap cells. Nearest-neighbour sampling (the PIXI v8 string
literal 'nearest', set on the BufferImageSource’s scaleMode) gives
crisp cell edges.
Axis convention
Section titled “Axis convention”Both axes are band scales. This is the first chart in the library
with bandAdapter on x AND y simultaneously. Heatmaps in v1 do not
auto-bin continuous data; consumers pre-bin into discrete categories and
pass encoding.x.type / encoding.y.type as 'categorical' (enforced by
the validator — see spec/validate.ts:requireHeatmapEncoding). A
quantitative-pre-binned axis is treated as ordered categorical by simply
stringifying the values.
Y convention: index 0 at top of plot. The first y category in
insertion order renders at the top edge of the plot (screen-top). The
y-axis labels run top-to-bottom in the same order. This matches the
common heatmap convention (calendars, confusion matrices). The texture
buffer is laid out row-major with (yIdx * width + xIdx) * 4 — combined
with a band y-scale ranging [0, plotHeight], yIdx 0 ends up at the top.
Colour
Section titled “Colour”Always quantitative (validator-enforced); default scheme viridis
(perceptually uniform, colourblind-safe). Each cell’s normalised value
t = (value - min) / (max - min) is passed to getSequentialColor
to yield a PIXI 0xRRGGBB. A span of zero (every value identical) maps
everything to t = 0.5 so the heatmap still renders something meaningful
rather than NaN-coloured cells.
Sparse cells
Section titled “Sparse cells”If (x, y) pairs are missing from data, those buffer positions stay
(0, 0, 0, 0) — fully transparent. The container’s background shows
through. The hit-tester returns null for sparse positions so tooltips
don’t show stale data.
Legend
Section titled “Legend”Always a continuous gradient (Legend type: 'continuous') sized
to the value-field’s [min, max]. Positioned top-right of the plot, same
placement as ScatterChart’s continuous legend.
No enter animation
Section titled “No enter animation”Heatmaps don’t animate well in v1: a left-to-right reveal (Line/Area
style) doesn’t fit a grid, a per-cell cascade looks gimmicky at any
realistic size, and a whole-grid alpha fade adds little value over a
straight static render. Deliberately omitted. update({ animate: true })
is accepted but ignored — heatmap updates always snap.
Lifecycle
Section titled “Lifecycle”const chart = new HeatmapChart({ container, spec });await chart.init(); // creates the PIXI Application AND does the first renderchart.update(newRows); // reuses the sprite/texture when grid dims unchangedchart.destroy(); // idempotent; frees the GPU texture + primitivesResize keeps the sprite/texture and just changes the sprite’s pixel
dimensions. Chart.update reuses the same sprite. When the
grid dimensions match (same category sets), the existing buffer is
rewritten in place and uploaded via source.update() — no GPU
reallocation. When grid dimensions change, the old Texture +
BufferImageSource are destroyed before the new ones are
allocated, preventing GPU memory growth across many updates.
For most use cases, prefer the declarative render entry point — use this class directly only when you need fine-grained lifecycle control.
Extends
Section titled “Extends”Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new HeatmapChart(
opts):HeatmapChart
Defined in: packages/pixi-charts/src/charts/HeatmapChart.ts:218
Parameters
Section titled “Parameters”HeatmapChartOptions
Returns
Section titled “Returns”HeatmapChart
Overrides
Section titled “Overrides”Accessors
Section titled “Accessors”destroyed
Section titled “destroyed”Get Signature
Section titled “Get Signature”get destroyed():
boolean
Defined in: packages/pixi-charts/src/core/Chart.ts:155
true once destroy has run.
Returns
Section titled “Returns”boolean
Inherited from
Section titled “Inherited from”initialized
Section titled “initialized”Get Signature
Section titled “Get Signature”get initialized():
boolean
Defined in: packages/pixi-charts/src/core/Chart.ts:160
true once init has completed.
Returns
Section titled “Returns”boolean
Inherited from
Section titled “Inherited from”Methods
Section titled “Methods”destroy()
Section titled “destroy()”destroy():
void
Defined in: packages/pixi-charts/src/charts/HeatmapChart.ts:243
Destroy every owned primitive plus the GPU-backed texture, in addition to the base-class teardown. Idempotent.
Returns
Section titled “Returns”void
Overrides
Section titled “Overrides”init()
Section titled “init()”init():
Promise<void>
Defined in: packages/pixi-charts/src/charts/HeatmapChart.ts:232
Override of Chart.init: after the PIXI Application is ready, runs the first render so the spec dispatcher hands back a fully- rendered chart.
Returns
Section titled “Returns”Promise<void>
Overrides
Section titled “Overrides”off(
_event,handler):void
Defined in: packages/pixi-charts/src/core/Chart.ts:259
Remove a previously registered click handler. No-op if the handler wasn’t registered, or after destroy.
Parameters
Section titled “Parameters”_event
Section titled “_event”"click"
handler
Section titled “handler”Returns
Section titled “Returns”void
Inherited from
Section titled “Inherited from”on(
_event,handler): () =>void
Defined in: packages/pixi-charts/src/core/Chart.ts:248
Register a handler for a chart event. Returns an unsubscribe function; calling it (or off) removes the handler.
Currently only 'click' is supported. Handlers receive a
ChartClickEvent describing the clicked datum, its index, the
plot-area-local pixel position, and (for multi-series charts) the
series name. The library reports the click; what it means is up to
the consumer — pair with update to build drilldown.
Handlers are cleared automatically on destroy.
Parameters
Section titled “Parameters”_event
Section titled “_event”"click"
handler
Section titled “handler”Returns
Section titled “Returns”() => void
Example
Section titled “Example”const off = chart.on('click', (event) => { console.log('clicked', event.datum, 'at index', event.index);});// later: off(); // or: chart.off('click', handler);Inherited from
Section titled “Inherited from”update()
Section titled “update()”update(
newData,options?):void
Defined in: packages/pixi-charts/src/core/Chart.ts:218
Swap the chart’s data without recreating the WebGL context. Reuses the existing PixiJS application, scales infrastructure, axes, legend, and interaction layer; recomputes scales, geometry, and hit-testing from the new data.
update() cannot change the chart type, encoding, orientation, donut
inner radius, or color scheme — only the rows in data. To change any
of those, destroy() this chart and construct a fresh one.
Synchronous. The PixiJS application is already initialised; updating is just recompute + redraw.
Parameters
Section titled “Parameters”newData
Section titled “newData”readonly Record<string, unknown>[]
options?
Section titled “options?”Returns
Section titled “Returns”void
Throws
Section titled “Throws”If called before init has resolved.
If called after destroy, this is a silent no-op.