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

405

Objects84
Managed SQL47
Backups31
Storage162
Instances102
Functions23
Compute125
Bandwidth39
Load balancers12
Network51
Plan seats58
Egress overage9
Support67

Revenue, 405

Revenue by product
PathValueShare of parentGrowth
Storage / Objects8451.9%22
Storage / Managed SQL4729%8
Storage / Backups3119.1%35
Storage16240%20.4
Compute / Instances10281.6%-12
Compute / Functions2318.4%64
Compute12530.9%2
Network / Bandwidth3976.5%18
Network / Load balancers1223.5%-5
Network5112.6%12.6
Support / Plan seats5886.6%41
Support / Egress overage913.4%76
Support6716.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

295

Objects84
Managed SQL47
Storage131
Instances102
Functions23
Compute125
Bandwidth39
Network39

Revenue, 295

Revenue by product
PathValueShare of parentGrowth
Storage / Objects8464.1%22
Storage / Managed SQL4735.9%8
Storage13144.4%17
Compute / Instances10281.6%-12
Compute / Functions2318.4%64
Compute12542.4%2
Network / Bandwidth39100%18
Network3913.2%18

Keyboard interactions

KeysAction
Arrow keysMove to the nearest top level tile in that direction.
Home / EndMove to the first or last tile.
Enter / SpaceZooms into the tile in focus.
Escape / BackspaceZooms 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.