Treemap
A squarified treemap: click to drill and the tiles grow to fill the view, with a breadcrumb back and metrics that morph every tile.
datachartnew
Preview
Treemap preview
Live · keyboard ready
Objects84
Managed SQL47
Backups31
Storage162
Instances102
Functions23
Compute125
Bandwidth39
Load balancers12
Network51
Plan seats58
Egress overage9
Support67
Revenue, 405
| Path | Value | Share of parent | Growth |
|---|---|---|---|
| Storage / Objects | 84 | 51.9% | 22 |
| Storage / Managed SQL | 47 | 29% | 8 |
| Storage / Backups | 31 | 19.1% | 35 |
| Storage | 162 | 40% | 20.4 |
| Compute / Instances | 102 | 81.6% | -12 |
| Compute / Functions | 23 | 18.4% | 64 |
| Compute | 125 | 30.9% | 2 |
| Network / Bandwidth | 39 | 76.5% | 18 |
| Network / Load balancers | 12 | 23.5% | -5 |
| Network | 51 | 12.6% | 12.6 |
| Support / Plan seats | 58 | 86.6% | 41 |
| Support / Egress overage | 9 | 13.4% | 76 |
| Support | 67 | 16.5% | 45.7 |
When to use
- Many parts where the biggest ones matter and people drill for detail.
- Showing size and a second measure at once.
When not to use
- Use bar-chart when exact comparisons between similar values matter.
- Use sunburst when the depth of the hierarchy is the story.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "treemap",
"type": "registry:ui",
"title": "Treemap",
"description": "A squarified treemap: click to drill and the tiles grow to fill the view, with a breadcrumb back and metrics that morph every tile.",
"categories": [
"data"
],
"dependencies": [
"motion"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/treemap/treemap.tsx",
"type": "registry:component",
"target": "@components/manicat/treemap/treemap.tsx"
},
{
"path": "registry/components/treemap/treemap.module.css",
"type": "registry:component",
"target": "@components/manicat/treemap/treemap.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/treemap",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/treemap",
"markdown": "https://uiarc.dev/components/treemap/markdown",
"tags": [
"data",
"chart",
"new"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { Treemap } from "@/components/manicat/treemap/treemap";
import type { TreemapNode } from "@/components/manicat/treemap/treemap";
const treemapData: TreemapNode = {
id: "revenue",
label: "Revenue",
children: [
{
id: "storage",
label: "Storage",
children: [
{ id: "objects", label: "Objects", value: 84, color: 22 },
{ id: "sql", label: "Managed SQL", value: 47, color: 8 },
{ id: "backup", label: "Backups", value: 31, color: 35 },
],
},
{
id: "compute",
label: "Compute",
children: [
{ id: "instances", label: "Instances", value: 102, color: -12 },
{ id: "functions", label: "Functions", value: 23, color: 64 },
],
},
{
id: "network",
label: "Network",
children: [
{ id: "bandwidth", label: "Bandwidth", value: 39, color: 18 },
{ id: "load-balancers", label: "Load balancers", value: 12, color: -5 },
],
},
{
id: "support",
label: "Support",
children: [
{ id: "plan-seats", label: "Plan seats", value: 58, color: 41 },
{ id: "egress", label: "Egress overage", value: 9, color: 76 },
],
},
],
};
export function TreemapExample() {
return <Treemap data={treemapData} label="Revenue by product" colorLabel="Growth" />;
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Revenue by product Area is revenue and colour is growth; click a group to zoom in.
Revenue by product
Area is revenue and colour is growth; click a group to zoom in. preview
Live · keyboard ready
Objects84
Managed SQL47
Storage131
Instances102
Functions23
Compute125
Bandwidth39
Network39
Revenue, 295
| Path | Value | Share of parent | Growth |
|---|---|---|---|
| Storage / Objects | 84 | 64.1% | 22 |
| Storage / Managed SQL | 47 | 35.9% | 8 |
| Storage | 131 | 44.4% | 17 |
| Compute / Instances | 102 | 81.6% | -12 |
| Compute / Functions | 23 | 18.4% | 64 |
| Compute | 125 | 42.4% | 2 |
| Network / Bandwidth | 39 | 100% | 18 |
| Network | 39 | 13.2% | 18 |
revenue-by-product-area-is-revenue-and-colour-is-growth-click-a-group-to-zoom-in-.tsxtsx
"use client";
import { Treemap } from "@/components/manicat/treemap/treemap";
import type { TreemapNode } from "@/components/manicat/treemap/treemap";
const revenue: TreemapNode = {
id: "revenue",
label: "Revenue",
children: [
{
id: "storage",
label: "Storage",
children: [
{ id: "objects", label: "Objects", value: 84, color: 22 },
{ id: "sql", label: "Managed SQL", value: 47, color: 8 },
],
},
{
id: "compute",
label: "Compute",
children: [
{ id: "instances", label: "Instances", value: 102, color: -12 },
{ id: "functions", label: "Functions", value: 23, color: 64 },
],
},
{ id: "network", label: "Network", children: [{ id: "bandwidth", label: "Bandwidth", value: 39, color: 18 }] },
],
};
export function TreemapRevenueExample() {
return <Treemap data={revenue} label="Revenue by product" colorLabel="Growth" />;
}
Keyboard interactions
| Keys | Action |
|---|---|
| Arrow keys | Move to the nearest top level tile in that direction. |
| Home / End | Move to the first or last tile. |
| Enter / Space | Zooms into the tile in focus. |
| Escape / Backspace | Zooms out one level. |
Accessibility
- The tiles form a focusable group with a description of its keys; the breadcrumb is a nav with aria-current on the current level.
- The tile in focus is announced with its path, value, share of parent, and shading measure through a polite live region.
- A visually hidden table lists every node's path, value, share, and measure.
Motion
- Drilling in carries every tile through one affine zoom: the chosen tile grows to fill the view, its siblings fly outward, and its children open inside it.
- Zooming out reverses the same path, so each level shrinks back into the tile it came from.
- Changing a measure re-lays out the same ids, so tiles resize and recolor in place; totals roll and breadcrumbs slide.
- Text never scales: tiles are sized each frame and labels appear only where they fit. Reduced motion places tiles immediately.
Responsive behavior
- The layout squarifies to the measured width, so tiles stay close to square on any screen; headers and labels hide where they would not fit.
- Tap a tile to read it, tap a branch to drill in.
Performance
- Layouts are computed per focus; animation interpolates rects and writes transforms and sizes directly. Comfortable up to a few hundred nodes.
Notes for AI
- Choose it for part-to-whole across a hierarchy with many leaves, such as revenue by region, country, and plan.
- Give nodes stable ids so switching the size measure morphs rather than rebuilds.
- The shading measure should be a magnitude (growth, margin), not identity; identity comes from the top level hue.
- Colors come from the shared --series-1 to --series-4 tokens in foundation.css: series 1 is the accent itself and series 2 to 4 rotate its hue, validated all-pairs for color vision deficiency across every accent in light and dark. Override the tokens on any ancestor to rebrand.