# TreemapChart

Part of a whole, when the whole has too many parts for a pie — and the parts nest.

- Group: Charts
- Import: `import { TreemapChart } from '@misoto22/folio/charts'`
- Page: https://ui.misoto22.com/components/treemap-chart/
- Related: pie-chart, bar-chart

## When to reach for it

Fifty items where a pie fails at six. Under a dozen items with a ranking to read, a BarChart’s length is the more precise encoding.

## Anatomy

- **Figure frame** (required) — ChartFigure’s <figure>, named by title, wrapping one ChartContainer.
- **Tiles** (required) — The root’s own tile renderer. The gap between tiles is a 2px --chart-surface STROKE rather than a smaller rect, so the tiles still tile — a treemap whose parts do not touch stops reading as a partition of one whole.
- **Tile labels** — showLabels, on by default, but a tile is only labelled when it is wider than 56px and taller than 26px. Below that the name is dropped rather than clipped, so the long tail is unlabelled by design.
- **Tooltip** — <TreemapChart.Tooltip>, keyed on the tile name. It is doing more work here than elsewhere: it is the only way to name a tile too small to carry its own label.
- **Hidden data table** (required) — The sr-only table lists the LEAVES, each with the path that names it. A nested tree read row by row is not something anyone can follow, so the hierarchy is flattened into the row header instead.
- **Paint** — variant="ramp" walks --series-1 to --series-8 by tile INDEX; variant="nested" steps by DEPTH instead, which is the right encoding once the question is what is inside what.

## Best practices

### Do

- Feed it non-negative values that sum to something the reader recognises as the whole. Area is the encoding, an area cannot be negative, and a leaf at zero or below is laid out at zero width and dropped from the picture — the hidden table prints it as “not drawn” rather than letting the two views disagree about how many leaves there are.
- Compose <TreemapChart.Tooltip> whenever there is a tail. Anything under 56 by 26 pixels carries no label at all, and on a fifty-item treemap that is most of it.
- Switch to variant="nested" once the tree has a second level. ramp keys the fill off the tile index, so it separates siblings and says nothing at all about depth.

### Don’t

- Do not read the ramp as a key. The slot is index modulo eight, so tile one and tile nine are painted identically — the fill here is separation, not identity, and the picture will not correct a reader who assumes otherwise.
- Do not reach for it to rank a dozen items. A bar’s length is read far more precisely than a rectangle’s area, and the squarify layout deliberately does not order tiles by value alone, so a reader cannot even scan them in order.

## Accessibility

- title is required. The table view lists the LEAVES with the path that names them: a nested tree read row by row is not something anyone can follow.
- Area is the encoding, so the data must be non-negative and must sum to something the reader recognises as the whole.
- The gap between tiles is a surface-coloured stroke rather than a smaller rect — a treemap whose parts do not touch stops reading as a partition.

## TreemapChart

Part of a whole, when the whole has too many parts for a pie — and the parts nest. A treemap encodes value as AREA, which the eye reads worse than length but far better than angle, and it is the only form here that stays readable at fifty items. Two rules make it honest: no negative values (an area cannot be negative), and the tiles have to sum to something a reader recognises as the whole. Reach for `<BarChart>` when there are under a dozen items and the ranking matters — a bar's length is the more precise encoding, and a treemap's layout deliberately does not order its tiles by value alone.

### Props

- `config` — `ChartConfig` default `{}`. Tile names → their label and paint. Optional: the ramp covers unnamed tiles.
- `data` (required) — `TreemapNode[]`. The tree. One level is a flat set of tiles; two is a nested treemap.
- `title` (required) — `string`. What the chart shows, in a sentence a reader could act on. Required, and announced to a screen reader even when it is not printed.
- `showTitle` — `boolean`. Prints the title above the plot instead of hiding it from sight.
- `description` — `ReactNode`. A line under the title — the unit, the window, the caveat.
- `className` — `string`. Merged onto the figure, last, so a call site can size or space it.
- `variant` — `TreemapVariant` default `'ramp'`.
- `dataKey` — `string` default `'size'`. The leaf field holding each tile's number.
- `aspectRatio` — `number` default `4 / 3`. How square the tiles are pushed to be. Recharts' own squarify parameter.
- `showLabels` — `boolean` default `true`. Prints each tile's name on it, where the tile is big enough to hold it.
- `children` — `ReactNode`. The hover panel.
- `chartProps` — `TreemapExtras`.
- `hideDataTable` — `boolean` default `false`. Drops the hidden table view. Only correct when the page prints the data itself.
- `empty` — `ChartEmptyProps | false`. What the chart shows when it has nothing to draw. `false` keeps the empty plot, for a chart whose emptiness is itself the reading.

## Example — default

```tsx
import { TreemapChart } from '@misoto22/folio/charts'

<TreemapChart title="Bundle size by package" data={packages} showLabels>
  <TreemapChart.Tooltip />
</TreemapChart>
```

## Example — nested

```tsx
import { ToggleGroup, ToggleGroupItem } from '@misoto22/folio'
import { TreemapChart, type TreemapVariant } from '@misoto22/folio/charts'

<div className="flex w-full flex-col gap-4">
  <ToggleGroup
    type="single"
    value={variant}
    onValueChange={(next) => next && setVariant(next as TreemapVariant)}
    aria-label="Tile fill"
  >
    {VARIANTS.map((option) => (
      <ToggleGroupItem key={option} value={option}>
        {option}
      </ToggleGroupItem>
    ))}
  </ToggleGroup>

  <TreemapChart
    title={`Bundle size by group — ${variant}`}
    data={tree}
    variant={variant}
    showLabels
  >
    <TreemapChart.Tooltip />
  </TreemapChart>
</div>
```

## Example — many small tiles

```tsx
import { TreemapChart, type TreemapNode } from '@misoto22/folio/charts'

<TreemapChart
  title="Route payload by file"
  showTitle
  description="Kilobytes, gzipped"
  data={files}
  dataKey="bytes"
  showLabels
>
  <TreemapChart.Tooltip />
</TreemapChart>
```
