跳到正文
册页

图表

TreemapChart - 矩形树图

整体的组成部分——当部分多到饼图撑不住、而且还会嵌套时。

用法

什么时候用它

饼图在六项时就已经失效,矩形树图在五十项时还读得动。项目少于十几个、而且要读排名时,柱状图的长度是更精确的编码。

来自@misoto22/folio/charts

TSX
import { TreemapChart } from '@misoto22/folio/charts'

说明

整体的组成部分——当整体的部分多到饼图撑不住、而且这些部分还会嵌套时。

矩形树图把值编码成面积,眼睛读面积比读长度差、但比读角度好得多,而且它是这里唯一一种到五十项还读得动的形式。两条规则让它保持诚实:不能有负值(面积不可能是负的),以及各块加总起来要是读者认得出的那个“整体”。

项目少于十几个、而且排名才是重点时,改用 <BarChart>——柱子的长度是更精确的编码,而矩形树图的布局本来就不会单纯按值给色块排序。

结构

TreemapChart anatomy
部件说明
图框必填ChartFigure 的那个 <figure>,由 title 命名,包着一个 ChartContainer。
色块必填根节点自己的色块渲染器。色块之间的缝隙是一道 2px 的 --chart-surface 描边,而不是把矩形画小,所以这些块仍然铺满整片——各部分不再相接的树图,就不再读作对一个整体的划分了。
色块标签showLabels,默认打开,但只有宽于 56px、且高于 26px 的色块才会带标签。小于这个尺寸,名字是被丢掉、而不是被裁掉,所以长尾没有标签是设计使然。
提示气泡<TreemapChart.Tooltip>,以色块名称为键。它在这里干的活比在别处更重:一个小到装不下自己标签的色块,只有靠它才叫得出名字。
隐藏数据表必填那张 sr-only 表格列的是叶子,每一片都带着命名它的那条路径。一棵嵌套的树被逐行念出来没人跟得上,所以层级被压平进了行表头里。
上色variant="ramp" 按色块索引在 --series-1 到 --series-8 之间走;variant="nested" 改按深度走,而一旦问题变成“什么装在什么里面”,后者才是对的编码。

实践建议

推荐

  • 喂给它非负的值,而且加总起来要是读者认得出的那个整体。编码用的是面积,面积不可能为负,而一片取值为零或更低的叶子会被排成零宽度、从图里消失——隐藏表格会把它印成「未绘制」,而不是让两个视图对一共有多少片叶子各执一词。
  • 只要存在长尾,就组合 <TreemapChart.Tooltip>。小于 56 乘 26 像素的块根本不带标签,而在一张五十项的树图上,那是其中的大多数。
  • 树一旦有了第二层,就换成 variant="nested"。ramp 是按色块索引取填充的,所以它只把同级的块分开,关于深度什么都没说。

避免

  • 不要把这套梯度当成图例来读。槽位是索引对 8 取模,所以第一块和第九块上的色一模一样——这里的填充是为了区分,不是身份,而且读者要是反过来理解了,图上没有任何东西会纠正他。
  • 不要用它来给十来个项目排名。柱子的长度比矩形的面积读得精确得多,而且 squarify 布局刻意不只按值排列色块,所以读者连按顺序扫一遍都做不到。

示例

默认

八个包,作为一个整体的一次划分。矩形树图把值编码成面积,而眼睛读面积比读长度差、比读角度好得多,它也是这里唯一一种到五十项还保持可读的形式。有两条规则让它保持诚实:不能有负值,因为面积不能是负的;以及这些方块必须加总成一个读者认得出是「整体」的东西——十来项以内、又要读排名的时候,BarChart 是更精确的编码,因为矩形树图刻意不只按值来排列它的方块。

Bundle size by package
Bundle size by package
pathValue
recharts480
react-dom310
motion140
@remixicon/react96
cmdk62
tailwind-merge41
clsx12
sonner28

嵌套

两层,以及给它们上色的两种方式。ramp 沿着序列的灰阶走,于是同级之间靠明度分开,而这正是一组扁平方块想要的;nested 则改为按深度加深,于是同一层上的每个方块共享一个分量,而颜色所回答的问题变成了「什么装在什么里面」。只有叶子带尺寸——一个枝干是它子节点的和——而那张隐藏数据表被压平到这些叶子上,因为一棵嵌套的树一行一行念出来,没有谁跟得下去。

Bundle size by group — nested
Bundle size by group — nested
pathValue
runtime › react-dom310
runtime › react92
charts › recharts480
charts › motion140
ui › @remixicon/react96
ui › cmdk62
ui › sonner28
ui › clsx12

大量小块

长尾,而这既是矩形树图挣得它一席之地的地方,也是它不再为自己命名的地方:一个方块只有在宽于 56 像素、高于 26 像素时才会被打上标签,所以承载这条路由的那两个文件有名字,而其余十八个里的大多数是匿名矩形。tooltip 在指针底下一次命名一个,而那张隐藏数据表——从画出这些方块的同一批叶子生成,所以两者不可能对不上——正是让那些小方块不靠指针也够得着的东西。dataKey 是面积据以度量的那个叶子字段,也是那张表所印出的那一列。

Route payload by fileKilobytes, gzipped
Route payload by file
pathValue
editor.chunk.js412
framework.js268
charts.chunk.js96
markdown.js74
highlight.js58
icons.js41
router.js33
forms.js28
dates.js24
toast.js19
dialog.js17
popover.js15
tooltip.js12
menu.js11
tabs.js9
avatar.js7
badge.js5
kbd.js4
spinner.js3
clsx.js2

类型

TSX
export type TreemapVariant = 'ramp' | 'nested'
export type TreemapExtras = Omit<ComponentProps<typeof RechartsTreemap>, 'data' | 'dataKey'>

无障碍

  • title 必填。表格视图列的是叶子以及命名它的路径:一棵嵌套的树被逐行念出来,没人跟得上。
  • 编码用的是面积,所以数据必须非负,而且加总起来要是读者认得出的那个“整体”。
  • 色块之间的缝隙是一道页面色描边、而不是把矩形画小——各部分不再相接的树图,就不再读作对一个整体的划分了。