Treemap

Hierarchy as space: squarified rectangles sized by value — disk usage, budget splits, portfolio weights. The hidden edge is drill-down: tap an item with children and the map zooms into it (a back chip replaces the label, Files-app style); tap a leaf and itemAction fires with the item and its drill path, so a storage map doubles as a category picker.

Type

"treemap"

Wide: [3, 4]. In a flow grid it auto-sizes to a ~3:2 landscape cell.

Relevant Fields

Inherits all shared fields. Key fields:

Field Type Default Description
label string Header label (becomes a back chip while drilled in)
treemapConfig TreemapConfig Full configuration object (all optional)
tint string "#667eea" First-item color / palette seed
formatValue string Formatter for value readouts
action ActionDefinition Fallback for itemAction

TreemapConfig

Field Type Default Description
showLabels bool true Item labels inside cells that have room
showValues bool false Value under the label (taller cells only)
drillDown bool true Tap a parent to zoom into its children
cellGap number 2 Gap between cells
cellCornerRadius number 5 Cell corner rounding
colors string[] built-in palette Item color cycle (per-item color wins)
itemAction ActionDefinition Fired on leaf tap; {{value}} = {"label", "value", "path"}
scrub bool false Drag highlights the cell under the finger with a live readout (no drilling/actions until a tap)

Sync Payload Structure

A tree of weighted items — natural JSON or an encoded string. A bare array is shorthand for {"items": …}. A parent's value defaults to the sum of its children:

{
  "items": [
    { "label": "Media", "color": "#667eea", "children": [
      { "label": "Video", "value": 41.5 },
      { "label": "Photos", "value": 12.2 }
    ]},
    { "label": "Apps", "value": 23.0 },
    { "label": "System", "value": 14.8 }
  ]
}

Item Fields

Field Type Required Description
label string yes Cell label
value number no* Weight (*optional when children supply it)
color string no Cell color (hex)
children item[] no Nested items (drill-down target)

Examples

Storage map with drill-down

{
  "type": "treemap",
  "id": "storage",
  "position": [0, 0],
  "span": [3, 4],
  "label": "Storage",
  "formatValue": "suffix: GB",
  "treemapConfig": { "showValues": true },
  "sync": [{ "method": "meshsocket", "type": "listen", "event": "broadcast", "filter": { "msg_type": "disk_usage" }, "valuePath": "tree" }]
}

Flat category picker (no drill)

{
  "type": "treemap",
  "id": "budget",
  "position": [0, 0],
  "span": [3, 4],
  "label": "Budget",
  "treemapConfig": {
    "drillDown": false,
    "itemAction": { "method": "meshsocket", "mode": "broadcast", "event": "broadcast", "payload": { "msg_type": "pick_category", "item": "{{value}}" } }
  },
  "defaultValue": "[{\"label\":\"Rent\",\"value\":1800},{\"label\":\"Food\",\"value\":600},{\"label\":\"Fun\",\"value\":250},{\"label\":\"Save\",\"value\":900}]"
}

Behavior

  • Layout is the squarified algorithm (Bruls et al.) — rectangles stay as close to square as the weights allow
  • Parents show a hint; drilling cross-fades levels; the back chip walks one level up
  • A fresh dataset push resets the drill path (the old path may not exist anymore)
  • Labels only render where they fit — small slivers stay clean
  • scrub: true lets a drag glide the highlight across cells — drilling and actions stay on deliberate taps

Notes

  • The control's value is the dataset JSON — selection/drill state never overwrites it
  • Zero/negative values collapse to invisible slivers by design
  • For part-of-whole with few slices, Pie Chart reads faster; treemap earns its space at ~6+ items or with hierarchy
  • Pie Chart — radial part-of-whole
  • Sankey — flows between stages
  • List — the same data as rows
  • Sync — how trees arrive
  • Actions — how itemAction fires