Heatmap
A color-mapped matrix. In continuous mode values interpolate across a gradient
ramp — server-room temperatures, signal strength, an activity calendar. In
discrete mode each value is an index into a palette. Flip on editable and the
same grid becomes an input surface: tap cycles a cell, drag paints — a weekly
schedule programmer, an LED-matrix pixel editor, or a step sequencer, straight from
one flag.
Type
"heatmap"
Recommended Size
Wide: [2, 4] for a dashboard strip; taller for schedule grids (one row per day).
Relevant Fields
Inherits all shared fields. Key fields:
| Field | Type | Default | Description |
|---|---|---|---|
label |
string | — | Header label |
heatmapConfig |
HeatmapConfig | — | Full configuration object (all optional) |
tint |
string | "#667eea" |
Default ramp top / palette accent |
formatValue |
string | — | Formatter for the scale legend and cell values |
HeatmapConfig
Color Mapping
| Field | Type | Default | Description |
|---|---|---|---|
colors |
string[] | tint ramp | Continuous: 2+ gradient stops. Discrete: the palette (value = index) |
discrete |
bool | false |
Treat values as palette indices instead of a continuous range |
vMin / vMax |
number | data range | Continuous color-scale bounds |
Cells
| Field | Type | Default | Description |
|---|---|---|---|
cellCorner |
number | 3 |
Cell corner rounding |
cellGap |
number | 2 |
Gap between cells |
cellShape |
string | "square" |
square or circle (circle reads as dot-matrix/LED) |
Labels & Legend
| Field | Type | Default | Description |
|---|---|---|---|
showRowLabels |
bool | true |
Row labels down the leading edge (when rows present) |
showColLabels |
bool | true |
Column labels along the top (when cols present; auto-thinned) |
showScale |
bool | false |
Gradient scale legend under the grid (continuous only) |
showValues |
bool | false |
Numeric value inside each cell (when cells are large enough) |
Editing
| Field | Type | Default | Description |
|---|---|---|---|
editable |
bool | false |
Tap cycles a cell (discrete: next palette index; continuous: 0 ↔ vMax toggle) |
drag |
bool | true |
Drag paints the first-touched cell's new value across cells |
cellAction |
ActionDefinition | — | Fired per edit; {{value}} = {"row", "col", "value"} JSON |
sendMode |
string | "cell" |
cell fires per change; matrix fires the whole dataset once an edit burst settles (~0.4s) |
If cellAction is omitted, edits fall back to the control's own action.
Sync Payload Structure
A dense matrix plus optional axis labels — natural JSON or an encoded string.
{"values": <span class="wikibroken" title="unresolved: …">…</span>} with labels, or a bare <span class="wikibroken" title="unresolved: …">…</span> array of rows:
{
"rows": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
"cols": ["00", "03", "06", "09", "12", "15", "18", "21"],
"values": [
[0, 0, 1, 3, 3, 2, 1, 0],
[0, 0, 1, 3, 3, 2, 1, 0],
[0, 0, 2, 3, 3, 3, 2, 1],
[0, 0, 1, 3, 3, 2, 1, 0],
[0, 0, 1, 2, 3, 3, 3, 2],
[1, 0, 0, 1, 2, 3, 3, 2],
[1, 0, 0, 1, 2, 2, 1, 0]
]
}
Examples
Continuous telemetry heatmap
{
"type": "heatmap",
"id": "rack-temps",
"defaultValue": "{\"rows\":[\"Mon\",\"Tue\",\"Wed\"],\"cols\":[\"00\",\"06\",\"12\",\"18\"],\"values\":[[24,31,62,45],[28,55,81,49],[22,38,74,68]]}",
"position": [0, 0],
"span": [2, 4],
"label": "Rack temperatures",
"formatValue": "suffix:°C",
"heatmapConfig": { "colors": ["#1B2845", "#667eea", "#FF9500", "#FF6B6B"], "showScale": true, "vMin": 20, "vMax": 90 },
"sync": [{ "method": "meshsocket", "type": "listen", "event": "broadcast", "filter": { "msg_type": "rack_temps" }, "valuePath": "grid" }]
}
Weekly schedule programmer (editable, discrete)
{
"type": "heatmap",
"id": "thermostat-schedule",
"position": [0, 0],
"span": [3, 4],
"label": "Heating schedule",
"heatmapConfig": {
"discrete": true,
"colors": ["#FFFFFF14", "#667eea", "#FF9500"],
"editable": true,
"sendMode": "matrix",
"cellAction": { "method": "meshsocket", "mode": "broadcast", "event": "broadcast", "payload": { "msg_type": "schedule_set", "schedule": "{{value}}" } }
},
"defaultValue": "{\"rows\":[\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\",\"Sun\"],\"cols\":[\"6\",\"9\",\"12\",\"15\",\"18\",\"21\"],\"values\":[[0,1,0,0,1,1],[0,1,0,0,1,1],[0,1,0,0,1,1],[0,1,0,0,1,1],[0,1,0,0,1,2],[1,1,1,1,1,2],[1,1,1,1,1,0]]}"
}
LED matrix pixel editor
{
"type": "heatmap",
"id": "led-editor",
"position": [0, 0],
"span": [4, 4],
"label": "LED panel",
"heatmapConfig": {
"discrete": true,
"colors": ["#1A1A1A", "#FF3B30", "#34C759", "#007AFF", "#FFCC00"],
"cellShape": "circle",
"cellGap": 3,
"editable": true,
"cellAction": { "method": "meshsocket", "mode": "broadcast", "event": "broadcast", "payload": { "msg_type": "led_set", "pixel": "{{value}}" } }
},
"defaultValue": "[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]]"
}
Behavior
- Dataset pushes animate cell colors; edits render instantly (a local draft holds until the next push)
- Tap cycles: discrete
(value + 1) % palette.count, continuous0 ↔ vMax - Dragging paints the brush value chosen by the first cell touched — fill a row in one stroke
- Every cell change ticks a selection haptic and updates the control's stored dataset, so state readback returns the edited grid
sendMode: "matrix"batches an edit burst into a single dataset-sized action — ideal for schedule saves
Notes
- Ragged rows render (short rows read as 0) and are padded rectangular on first edit
- A GitHub-style activity calendar is a 7-row continuous heatmap with week columns
- A step sequencer is an editable discrete grid where the server plays column-by-column
Related
- Chart — cartesian series
- List — tabular rows
- Color Picker — free-form color input
- Actions — how
cellActionfires - Sync — how the matrix arrives