Treemap

Part-to-whole as nested rectangles sized by area, laid out with the squarify algorithm so tiles stay close to square instead of degenerating into slivers.

src/components/ui/treemap.tsx

About

From the component's own source, where it was written.

Part-to-whole as nested rectangles, sized by area.

**Squarified, not sliced.** The naive layout cuts the space into strips, which produces slivers — rectangles hundreds of times longer than they are wide. Slivers cannot be labelled, are almost impossible to compare, and are hard to hit with a pointer. This uses the squarify algorithm (Bruls, Huizing, van Wijk): it grows a row while the worst aspect ratio in that row improves, and closes it as soon as adding the next item would make it worse. The result is tiles close to square at every size.

**Area encodes the value, and area is read poorly.** People judge area far less accurately than length, so a treemap is the right choice for "what is big, roughly, and what is inside what" and the wrong one for "is A bigger than B" when A and B are close — for that, use a bar chart. The honest use is disk usage, bundle composition, spend by category: hierarchies where the nesting matters and precision does not.

**Labels are drawn only where they fit.** A label wider or taller than its tile is not truncated to an ellipsis that tells you nothing; it is dropped, and the tile keeps its tooltip. Everything about the value stays reachable through the title and the legend.

Install

npx astralyx-ui add treemap

Usage

import { Treemap } from '@/components/ui/treemap'

<Treemap nodes={nodes} depth={2} />

Composer

Change the props and the source below follows.

Treemap
Props
tsx
<Treemap
  nodes={nodes}
  depth={2}
/>

Examples

A bundle, by module

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

Treemap

Extends Omit<ComponentProps<'figure'>, 'height' | 'onSelect'>.

PropTypeDefaultDescription
nodesTreemapNode[]required{ id, label, value?, children?, color? }. Parents sum their children.
heightnumber320—
depthnumber21 flattens the hierarchy to its top level.
valueFormat(value: number) => stringDEFAULT_FORMAT—
onSelect(node: TreemapNode) => void——
gapnumber2Gap between tiles, in pixels.
emptyLabelstring'Nothing to show.'—
labelstring'Treemap'—

Types

TreemapNode

Part-to-whole as nested rectangles, sized by area.

FieldTypeDescription
idstring—
labelstring—
value?numberLeaf magnitude. Ignored when children is present — parents sum.
children?TreemapNode[]—
color?string—

Behaviour

TopicDetailDescription
squarifiednot slicedThe strip layout produces rectangles hundreds of times longer than they are wide — unlabellable, incomparable, hard to hit. Squarify keeps the worst aspect ratio in each row as low as it can.
arearead poorlyPeople judge area far less accurately than length. Right for "what is big, roughly, and what is inside what"; wrong for "is A bigger than B" when they are close.
labelsdropped, not truncatedA label that does not fit is removed rather than ellipsised into nothing. The value stays reachable through the tooltip.