Skip to content

Treemap

Compare parts of a whole as cells sized by value, with tooltips and keyboard access.

import { Treemap, TreemapItem } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use a treemap when the question is "where does it all go": a bundle by package, a disk by table, spend by line item. Each part is a cell whose area is its value, laid out squarified so cells stay close to square and compare by eye, largest first from the top-start corner. For one part's share in a row, use a Share Bar; for exact values people compare or sort, a table.

import { Treemap } from '@youj/react'

const kb = new Intl.NumberFormat('en-US', { style: 'unit', unit: 'kilobyte' }).format

<Treemap
  label="Bundle by package"
  items={[
    { id: 'app', name: 'app code', value: 164 },
    { id: 'react-dom', name: 'react-dom', value: 131 },
    { id: 'recharts', name: 'recharts', value: 96 },
  ]}
  highlight="recharts"
  formatValue={kb}
/>

It's a wide strip by default (aspect 3.5, width to height); pass another aspect, or a height class, which wins. Cells show the name and value where they have room, the name alone when smaller and nothing in a sliver, and every cell keeps its tooltip with the name, the value and its share of the total. Items at zero or below are left out, and with nothing to show it says so.

Reference

Propsitems, highlight, formatValue… (6)

Props

Treemap props
PropType
itemsRequiredreadonly TreemapItem[]–
highlightstring | readonly string[]

Ids of the items to highlight.

–
formatValue(value: number) => string

Formats values in cells, the tooltip and the spoken text. Default: the locale's number format.

–
labelstring

Accessible name of the map. Default: the labels' "Treemap".

–
gapnumber

Space between cells, in px.

default 4

4
aspectnumber

Width to height. Default 3.5, a wide strip; a height class wins over it.

–
Other props pass through: extends ComponentProps<'div'>.
MotionReveal, new data, parts come and go… · reduced motion

Motion

Motion tokens
MomentTokens
Revealcells fade in largest first when a third of the map scrolls into view
duration.baseease.enter

220ms · cubic-bezier(0.16, 1, 0.3, 1)

220mscubic-bezier(0.16, 1, 0.3, 1)
New datathe map re-lays itself with a FLIP, so only transforms move; labels keep their size
spring.smooth

0.36s, bounce 0

0.36s, bounce 0
Parts come and goa part that leaves fades out where it was; a new one fades in
duration.baseease.enter

220ms · cubic-bezier(0.16, 1, 0.3, 1)

220mscubic-bezier(0.16, 1, 0.3, 1)
Highlightfill, border and text change color
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

Drawn in place; new data and highlights land at once.

Reduced motion

Cells are drawn in place, and new data and highlights land at once.

AccessibilityKeyboard, focus

Accessibility

  • A named group (your label, or the labels' "Treemap") holding a list, largest first. Each item is named with its value, its share and whether it's highlighted ("recharts: 96 kB, 17% of total, highlighted").
  • A summary describes the group: how many parts, their total and the largest.
  • One tab stop. The arrow keys move to the nearest cell in that direction as laid out, in either text direction; Home and End go to the largest and the smallest. Focus shows the tooltip, as hover does.
  • Its built-in text comes from the labels, so <YoujProvider labels> translates it.