Preview Updated 2026-05-10

Treemap

Hierarchical rectangle area chart, single-level slice-and-dice layout.

Basic usage

Data comes in via props; rendered as pure SVG with no third-party charting dependency. Colors come from the --viz-1..8 tokens, colorblind-friendly.

背景 视口
react-dom1,200react720lodash540moment480rxjs380d3three
src/App.vue
<script setup lang="ts">
import { CfTreemap } from '@chufix-design/vue';
const nodes = [
  { name: 'react-dom', value: 1200 },
  { name: 'react', value: 720 },
  { name: 'lodash', value: 540 },
  { name: 'moment', value: 480 },
  { name: 'rxjs', value: 380 },
  { name: 'd3', value: 320 },
  { name: 'three', value: 280 },
  { name: 'others', value: 200 },
];
</script>
<template>
  <CfTreemap :nodes="nodes" />
</template>
<script setup>
import { CfTreemap } from '@chufix-design/vue';
const nodes = [
  { name: 'react-dom', value: 1200 },
  { name: 'react', value: 720 },
  { name: 'lodash', value: 540 },
  { name: 'moment', value: 480 },
  { name: 'rxjs', value: 380 },
  { name: 'd3', value: 320 },
  { name: 'three', value: 280 },
  { name: 'others', value: 200 },
];
</script>
<template>
  <CfTreemap :nodes="nodes" />
</template>
import { CfTreemap } from '@chufix-design/react';

export default function Demo() {
  const nodes = [
    { name: 'react-dom', value: 1200 },
    { name: 'react', value: 720 },
    { name: 'lodash', value: 540 },
    { name: 'moment', value: 480 },
    { name: 'rxjs', value: 380 },
    { name: 'd3', value: 320 },
    { name: 'three', value: 280 },
    { name: 'others', value: 200 },
  ];
  return (
    <>
      <CfTreemap nodes={nodes} />
    </>
  );
}
import { CfTreemap } from '@chufix-design/react';

export default function Demo() {
  const nodes = [
    { name: 'react-dom', value: 1200 },
    { name: 'react', value: 720 },
    { name: 'lodash', value: 540 },
    { name: 'moment', value: 480 },
    { name: 'rxjs', value: 380 },
    { name: 'd3', value: 320 },
    { name: 'three', value: 280 },
    { name: 'others', value: 200 },
  ];
  return (
    <>
      <CfTreemap nodes={nodes} />
    </>
  );
}

Label visibility

showLabels=false shows only color blocks — useful for thumbnail layouts. Text only appears when a rectangle is large enough (w>50, h>20).

背景 视口
5 个节点(label 显示)
依赖 A280依赖 B220依赖 C180依赖 D120其他80
label 隐藏
src/App.vue
<script setup lang="ts">
import { CfTreemap } from '@chufix-design/vue';
const small = [
  { name: '依赖 A', value: 280 },
  { name: '依赖 B', value: 220 },
  { name: '依赖 C', value: 180 },
  { name: '依赖 D', value: 120 },
  { name: '其他', value: 80 },
];
</script>
<template>
  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
    <div>
      <div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">5 个节点(label 显示)</div>
      <CfTreemap :nodes="small" :height="180" />
    </div>
    <div>
      <div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">label 隐藏</div>
      <CfTreemap :nodes="small" :height="180" :show-labels="false" />
    </div>
  </div>
</template>
<script setup>
import { CfTreemap } from '@chufix-design/vue';
const small = [
  { name: '依赖 A', value: 280 },
  { name: '依赖 B', value: 220 },
  { name: '依赖 C', value: 180 },
  { name: '依赖 D', value: 120 },
  { name: '其他', value: 80 },
];
</script>
<template>
  <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
    <div>
      <div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">5 个节点(label 显示)</div>
      <CfTreemap :nodes="small" :height="180" />
    </div>
    <div>
      <div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">label 隐藏</div>
      <CfTreemap :nodes="small" :height="180" :show-labels="false" />
    </div>
  </div>
</template>
import { CfTreemap } from '@chufix-design/react';

export default function Demo() {
  const small = [
    { name: '依赖 A', value: 280 },
    { name: '依赖 B', value: 220 },
    { name: '依赖 C', value: 180 },
    { name: '依赖 D', value: 120 },
    { name: '其他', value: 80 },
  ];
  return (
    <>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          <div>
            <div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>5 个节点(label 显示)</div>
            <CfTreemap nodes={small} height={180} />
          </div>
          <div>
            <div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>label 隐藏</div>
            <CfTreemap nodes={small} height={180} showLabels={false} />
          </div>
        </div>
    </>
  );
}
import { CfTreemap } from '@chufix-design/react';

export default function Demo() {
  const small = [
    { name: '依赖 A', value: 280 },
    { name: '依赖 B', value: 220 },
    { name: '依赖 C', value: 180 },
    { name: '依赖 D', value: 120 },
    { name: '其他', value: 80 },
  ];
  return (
    <>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
          <div>
            <div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>5 个节点(label 显示)</div>
            <CfTreemap nodes={small} height={180} />
          </div>
          <div>
            <div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>label 隐藏</div>
            <CfTreemap nodes={small} height={180} showLabels={false} />
          </div>
        </div>
    </>
  );
}

Nested hierarchy + drill-down

Attach children to any node and the layout recurses with slice-and-dice; parent rectangles reserve headerHeight pixels at the top for their label. Click a top-level rectangle with children to drill in: the subtree becomes the new focus, with a breadcrumb, an ↑ Up button, and a footer tracking the current focus. Pass drillable={false} for a static nested view.

背景 视口

顶层方块直接展示子分类的嵌套排版;单击有子项的方块即可下钻聚焦到该子树。

亚太中国4,280日本1,820东南亚1,240澳洲760北美美国3,920加拿大1,080欧洲英国1,420德国1,380法国980北欧820其他南美中东

焦点 全部

src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfTag, CfTreemap } from '@chufix-design/vue';

const nodes = [
  {
    name: '亚太',
    children: [
      { name: '中国', value: 4280 },
      { name: '日本', value: 1820 },
      { name: '东南亚', value: 1240 },
      { name: '澳洲', value: 760 },
    ],
  },
  {
    name: '欧洲',
    children: [
      { name: '英国', value: 1420 },
      { name: '德国', value: 1380 },
      { name: '法国', value: 980 },
      { name: '北欧', value: 820 },
    ],
  },
  {
    name: '北美',
    children: [
      { name: '美国', value: 3920 },
      { name: '加拿大', value: 1080 },
    ],
  },
  {
    name: '其他',
    children: [
      { name: '南美', value: 620 },
      { name: '中东', value: 540 },
      { name: '非洲', value: 380 },
    ],
  },
];

const focus = ref<string[]>([]);
</script>
<template>
  <p style="margin: 0 0 8px; color: var(--fg-3); font-size: 12px;">
    顶层方块直接展示子分类的嵌套排版;单击有子项的方块即可下钻聚焦到该子树。
  </p>
  <CfTreemap
    :nodes="nodes"
    :width="640"
    :height="320"
    @drill="(p: { pathNames: string[] }) => focus = p.pathNames"
  />
  <p style="margin-top: 8px; font-size: 12px;">
    <CfTag tone="info" size="sm">焦点</CfTag>
    {{ focus.length ? focus.join(' / ') : '全部' }}
  </p>
</template>
<script setup>
import { ref } from 'vue';
import { CfTag, CfTreemap } from '@chufix-design/vue';

const nodes = [
  {
    name: '亚太',
    children: [
      { name: '中国', value: 4280 },
      { name: '日本', value: 1820 },
      { name: '东南亚', value: 1240 },
      { name: '澳洲', value: 760 },
    ],
  },
  {
    name: '欧洲',
    children: [
      { name: '英国', value: 1420 },
      { name: '德国', value: 1380 },
      { name: '法国', value: 980 },
      { name: '北欧', value: 820 },
    ],
  },
  {
    name: '北美',
    children: [
      { name: '美国', value: 3920 },
      { name: '加拿大', value: 1080 },
    ],
  },
  {
    name: '其他',
    children: [
      { name: '南美', value: 620 },
      { name: '中东', value: 540 },
      { name: '非洲', value: 380 },
    ],
  },
];

const focus = ref<string[]>([]);
</script>
<template>
  <p style="margin: 0 0 8px; color: var(--fg-3); font-size: 12px;">
    顶层方块直接展示子分类的嵌套排版;单击有子项的方块即可下钻聚焦到该子树。
  </p>
  <CfTreemap
    :nodes="nodes"
    :width="640"
    :height="320"
    @drill="(p: { pathNames: string[] }) => focus = p.pathNames"
  />
  <p style="margin-top: 8px; font-size: 12px;">
    <CfTag tone="info" size="sm">焦点</CfTag>
    {{ focus.length ? focus.join(' / ') : '全部' }}
  </p>
</template>
import { useState } from 'react';
import { CfTag, CfTreemap } from '@chufix-design/react';

export default function Demo() {
  const nodes = [
    {
      name: '亚太',
      children: [
        { name: '中国', value: 4280 },
        { name: '日本', value: 1820 },
        { name: '东南亚', value: 1240 },
        { name: '澳洲', value: 760 },
      ],
    },
    {
      name: '欧洲',
      children: [
        { name: '英国', value: 1420 },
        { name: '德国', value: 1380 },
        { name: '法国', value: 980 },
        { name: '北欧', value: 820 },
      ],
    },
    {
      name: '北美',
      children: [
        { name: '美国', value: 3920 },
        { name: '加拿大', value: 1080 },
      ],
    },
    {
      name: '其他',
      children: [
        { name: '南美', value: 620 },
        { name: '中东', value: 540 },
        { name: '非洲', value: 380 },
      ],
    },
  ];

  const [focus, setFocus] = useState<string[]>([]);
  return (
    <>
      <p style={{ margin: "0 0 8px", color: "var(--fg-3)", fontSize: 12 }}>
          顶层方块直接展示子分类的嵌套排版;单击有子项的方块即可下钻聚焦到该子树。
        </p>
        <CfTreemap nodes={nodes} width={640} height={320} onDrill={(p: { pathNames: string[] }) => setFocus(p.pathNames)}
        />
        <p style={{ marginTop: 8, fontSize: 12 }}>
          <CfTag tone="info" size="sm">焦点</CfTag>
          {focus.length ? focus.join(' / ') : '全部'}
        </p>
    </>
  );
}
import { useState } from 'react';
import { CfTag, CfTreemap } from '@chufix-design/react';

export default function Demo() {
  const nodes = [
    {
      name: '亚太',
      children: [
        { name: '中国', value: 4280 },
        { name: '日本', value: 1820 },
        { name: '东南亚', value: 1240 },
        { name: '澳洲', value: 760 },
      ],
    },
    {
      name: '欧洲',
      children: [
        { name: '英国', value: 1420 },
        { name: '德国', value: 1380 },
        { name: '法国', value: 980 },
        { name: '北欧', value: 820 },
      ],
    },
    {
      name: '北美',
      children: [
        { name: '美国', value: 3920 },
        { name: '加拿大', value: 1080 },
      ],
    },
    {
      name: '其他',
      children: [
        { name: '南美', value: 620 },
        { name: '中东', value: 540 },
        { name: '非洲', value: 380 },
      ],
    },
  ];

  const [focus, setFocus] = useState<string[]>([]);
  return (
    <>
      <p style={{ margin: "0 0 8px", color: "var(--fg-3)", fontSize: 12 }}>
          顶层方块直接展示子分类的嵌套排版;单击有子项的方块即可下钻聚焦到该子树。
        </p>
        <CfTreemap nodes={nodes} width={640} height={320} onDrill={(p: { pathNames: string[] }) => setFocus(p.pathNames)}
        />
        <p style={{ marginTop: 8, fontSize: 12 }}>
          <CfTag tone="info" size="sm">焦点</CfTag>
          {focus.length ? focus.join(' / ') : '全部'}
        </p>
    </>
  );
}

API

PropTypeDefaultDescription
nodesTreemapNode[]{ name, value?, colorIndex?, children? }[]
width / heightnumber480 / 240
childPaddingnumber4Inner padding around children inside a parent
headerHeightnumber16Space reserved at the top of a parent for its label
drillablebooleantrueClick a top-level rect with children to drill in
showBreadcrumbbooleantrueRender breadcrumb + ↑ Up control when drilled

反馈与讨论

Treemap · Discussion

0
0 / 600
正在加载评论...