图表
TreemapChart - 矩形树图
整体的组成部分——当部分多到饼图撑不住、而且还会嵌套时。
用法
什么时候用它
来自@misoto22/folio/charts
import { TreemapChart } from '@misoto22/folio/charts'说明
整体的组成部分——当整体的部分多到饼图撑不住、而且这些部分还会嵌套时。
矩形树图把值编码成面积,眼睛读面积比读长度差、但比读角度好得多,而且它是这里唯一一种到五十项还读得动的形式。两条规则让它保持诚实:不能有负值(面积不可能是负的),以及各块加总起来要是读者认得出的那个“整体”。
项目少于十几个、而且排名才是重点时,改用 <BarChart>——柱子的长度是更精确的编码,而矩形树图的布局本来就不会单纯按值给色块排序。
结构
| 部件 | 说明 |
|---|---|
| 图框必填 | 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 是更精确的编码,因为矩形树图刻意不只按值来排列它的方块。
| path | Value |
|---|---|
| recharts | 480 |
| react-dom | 310 |
| motion | 140 |
| @remixicon/react | 96 |
| cmdk | 62 |
| tailwind-merge | 41 |
| clsx | 12 |
| sonner | 28 |
嵌套
两层,以及给它们上色的两种方式。ramp 沿着序列的灰阶走,于是同级之间靠明度分开,而这正是一组扁平方块想要的;nested 则改为按深度加深,于是同一层上的每个方块共享一个分量,而颜色所回答的问题变成了「什么装在什么里面」。只有叶子带尺寸——一个枝干是它子节点的和——而那张隐藏数据表被压平到这些叶子上,因为一棵嵌套的树一行一行念出来,没有谁跟得下去。
| path | Value |
|---|---|
| runtime › react-dom | 310 |
| runtime › react | 92 |
| charts › recharts | 480 |
| charts › motion | 140 |
| ui › @remixicon/react | 96 |
| ui › cmdk | 62 |
| ui › sonner | 28 |
| ui › clsx | 12 |
大量小块
长尾,而这既是矩形树图挣得它一席之地的地方,也是它不再为自己命名的地方:一个方块只有在宽于 56 像素、高于 26 像素时才会被打上标签,所以承载这条路由的那两个文件有名字,而其余十八个里的大多数是匿名矩形。tooltip 在指针底下一次命名一个,而那张隐藏数据表——从画出这些方块的同一批叶子生成,所以两者不可能对不上——正是让那些小方块不靠指针也够得着的东西。dataKey 是面积据以度量的那个叶子字段,也是那张表所印出的那一列。
| path | Value |
|---|---|
| editor.chunk.js | 412 |
| framework.js | 268 |
| charts.chunk.js | 96 |
| markdown.js | 74 |
| highlight.js | 58 |
| icons.js | 41 |
| router.js | 33 |
| forms.js | 28 |
| dates.js | 24 |
| toast.js | 19 |
| dialog.js | 17 |
| popover.js | 15 |
| tooltip.js | 12 |
| menu.js | 11 |
| tabs.js | 9 |
| avatar.js | 7 |
| badge.js | 5 |
| kbd.js | 4 |
| spinner.js | 3 |
| clsx.js | 2 |
类型
export type TreemapVariant = 'ramp' | 'nested'
export type TreemapExtras = Omit<ComponentProps<typeof RechartsTreemap>, 'data' | 'dataKey'>无障碍
- title 必填。表格视图列的是叶子以及命名它的路径:一棵嵌套的树被逐行念出来,没人跟得上。
- 编码用的是面积,所以数据必须非负,而且加总起来要是读者认得出的那个“整体”。
- 色块之间的缝隙是一道页面色描边、而不是把矩形画小——各部分不再相接的树图,就不再读作对一个整体的划分了。