Treemap Chart

Pro

Squarified treemap with 4 visual variants: corporate solid, mosaic card grid, dark blueprint and hierarchy explorer. Supports nested data. Pure SVG.

</>sv-treemap-chart charttreemaphierarchy
import { SvTreemapChartComponent } from '@styloviz-pro/charts';

Demo & usage

Basic usage

Pro

Usage example — open the gallery for the full interactive demo.

Pro

An interactive demo for this component lives in the gallery.

Open live demo

More examples

Variant + title

Pro

Tile interactions

Pro

A layout that does not move

Pro

When to use

  • Showing part-to-whole for many items where size encodes magnitude.
  • Hierarchical breakdowns: disk usage, portfolio weights, category sales.
  • For a handful of segments, a Donut/Pie is clearer.

Async states

  • loading
  • empty
  • error
  • retry

Inputs

NameTypeDefaultDescription
loadingbooleanfalseTrue while the series is being fetched.
errorSvDataError | string | nullnullLoad failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`.
emptyMessagestring'No data to plot'Copy for the no-data state.
filteredbooleanfalseTrue when the emptiness is caused by a filter rather than an empty set.
nodesreadonly TreemapNode[][]Tiles: { label, value, color, optional children } — value sets tile area.
valuePolicySvValuePolicy'omit'What to do with a tile this chart cannot plot — a negative value, `NaN`, `Infinity`. Area is the encoding, and there is no negative area; worse, the tile's own subtree sum is the denominator for its children, so one bad weight makes a whole level's tiles overlap rather than merely misdraw. - `omit` (default) — drop it wherever it appears in the tree, and disclose the count. Percentages are then of the tiles that remain. - `reject` — refuse the tree and show the error state. `clamp` is not available: a zero-value tile has zero area, so there is no rectangle left to mark. Asking for it warns in dev and omits instead.
widthnumber480Chart width in pixels.
heightnumber300Chart height in pixels.
gapnumber2Gap between tiles in pixels.
titlestring''Chart title.
variantTreemapVariant'flat'Visual variant: flat, mosaic, blueprint or explorer.
tileOrderTreemapTileOrder'value'Tile order within each parent rectangle. `'value'` sorts largest first, which is what keeps a squarified tile close to square. `'input'` follows the `nodes` array, trading some of that shape for a layout that does not move: a treemap is navigated by position, and a dashboard that re-sorts on every poll puts the tile the reader is reaching for somewhere else. Pick `'input'` for anything that refreshes on a timer.
ariaLabelstring''Accessible name override for the chart. Falls back to a generated summary.
customClassstring''Extra CSS classes applied to the root wrapper.

Outputs

EventPayload typeDescription
retryvoidThe host should re-run the failed load.
tileHoverTreemapTileEventEmitted when a tile is hovered or keyboard-focused.
tileSelectTreemapTileEventEmitted when a tile is clicked or activated via keyboard (Enter/Space).

Wire it to your API

This component is headless about transport: it renders what you give it and reports what the user asks for. Nothing below requires @styloviz/data — drive it from whatever you already use.

Template

Pro

Bound to the names this component actually exposes.

Host class

Pro

Drive the three async inputs from your own fetch.

  • This component does not emit a query, so it renders what you give it. Fetch on your own trigger and bind `nodes`, `loading` and `error`.
  • Set `filtered` when a search or filter is active. It is the difference between "you have no orders" and "no orders match this filter" — telling a customer with 4,000 orders the first one reads as a bug.
  • Normalize failures with `toSvDataError()` from `@styloviz/core`. It derives `retryable` from the status, so a 404 does not get a "Try again" button that can only fail again.

Full walkthrough: Connecting to a backend.

Customization & theming

  • Four visual variants.
  • Nested / hierarchical data support.
  • Custom color mapping per node.
  • `tileOrder` chooses between largest-first packing (`value`, the default, which keeps tiles closest to square) and the order of the `nodes` array (`input`, which keeps a tile where the reader last saw it).
  • A branch that contains itself is cut before anything walks the tree, and the cut is named under the plot with the path that reaches the loop.
  • `valuePolicy` decides what happens to a node this chart cannot lay out — a negative, `NaN` or `Infinity`. Tile area is `value / total`, so an unplottable node distorts the area of every sibling. `omit` (default) drops it and discloses the count; `reject` refuses the dataset. `clamp` is not offered: a tile clamped to 0 has zero area, which is a tile that is not there — an invisible outcome cannot be a disclosure.

Best practices

  • Do: Label only tiles large enough to fit text; rely on tooltips for small ones.
  • Do: Keep nesting shallow so the hierarchy stays legible.
  • Do: Set tileOrder="input" on anything that refreshes on a timer. A treemap is navigated by position, and the default largest-first packing re-shuffles the whole picture whenever a value crosses a neighbour's — so the tile someone is reaching for is somewhere else by the time they get there. Order the nodes array the way you want the tiles laid out.
  • Don't: Build `children` from a flat `parentId` list without checking that no parent is its own descendant. Both the value pass and the layout walk `children` recursively, so a loop would end the stack rather than misdraw a tile. The chart cuts the branch and says so, but the cut is a symptom: the payload is wrong.
  • Tip: Map color to a second dimension (e.g. growth) for extra insight.

Accessibility

  • The SVG is a `role="group"` with a generated summary (override via `ariaLabel`) — `group`, not `img`, because every tile is a tab stop.
  • Tile AREA is the value, and the small tiles are exactly the ones whose labels do not fit — so the alternative is the only place their numbers exist at all. `sv-data-summary-table` gives every tile its value and share, and adds a "Share of" column for nested data so a child's share of its own parent is not mistaken for its share of the whole.
  • Every tile is keyboard-focusable with a label/value `aria-label`; hover/focus highlights the tile and Enter/Space emits `tileSelect`. Adequate contrast for tile labels.
  • A cut branch is named under the plot too, with the path down to the loop, so a truncated hierarchy is never mistaken for a shallow one.
  • A dropped node is named in the rendered output under the plot — how many, and their real values — not only in `console.warn`. A tile that is simply absent is indistinguishable from a tile that was never in the data, so the count is the only thing that tells a reader the map is of a subset.

Feedback on Treemap Chart

Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.

Loads giscus.app and GitHub — nothing is fetched until you click.