图表
BoxPlot
一个度量在各个分类上的分布范围。
什么时候用它
「这东西波动有多大」,而且要一次看六个。要看**单个**分布的形状,用 Histogram;观测点少到能全画出来,用 ScatterChart。
示例
default
| name | Minimum | Lower quartile | Median | Upper quartile | Maximum | Outliers |
|---|---|---|---|---|---|---|
| Sydney | 182 | 195.75 | 207 | 219.25 | 236 | 1 |
| Singapore | 244 | 259 | 271.5 | 287.75 | 318 | 0 |
| Frankfurt | 310 | 326.5 | 341 | 358.75 | 379 | 1 |
| Oregon | 268 | 280.25 | 290.5 | 305.75 | 341 | 0 |
orientation
| name | Minimum | Lower quartile | Median | Upper quartile | Maximum | Outliers |
|---|---|---|---|---|---|---|
| ap-southeast-2 | 182 | 195.75 | 207 | 219.25 | 236 | 1 |
| ap-southeast-1 | 244 | 259 | 271.5 | 287.75 | 318 | 0 |
| eu-central-1 | 310 | 326.5 | 341 | 358.75 | 379 | 1 |
| us-west-2 | 268 | 280.25 | 290.5 | 305.75 | 341 | 0 |
notched
| name | Minimum | Lower quartile | Median | Upper quartile | Maximum | Outliers |
|---|---|---|---|---|---|---|
| Control | 180 | 214 | 236 | 262 | 318 | 0 |
| Variant A | 176 | 208 | 229 | 255 | 310 | 0 |
| Variant B | 184 | 226 | 258 | 291 | 356 | 0 |
说明
一个度量在每个分类上的分布——中位数、中间那一半、触及的范围,以及落在范围之外的那些点。
当问题是「这东西波动有多大」时,就该拿它;而且它回答这个问题所花的墨水,只有一个分类一张直方图的十分之一。六条响应时间分布画成六个箱子,一屏就排得下;画成六张直方图,根本排不下。
箱线图藏起来的是多峰。 一个箱子就是五个数,而五个数分不出一个峰和两个峰。一个双峰分布——一条走缓存的快路径和一条走数据库的慢路径,一个平均值里裹着两拨人——画出来的箱子,和一个中心落在同一位置的平滑分布一模一样,读者没有任何办法从图上看出来:箱子正中间那个值,几乎没有谁真的取到过。它同时还藏起了样本量:六个点画出的箱子和六千个点画出的箱子长得毫无分别,所以 count 值得一路带着,也所以在要比较中位数时值得把缺口打开——缺口是真的会去读 count 的。当问题是某一条分布的形状时,改用 <Histogram>;当观测少到可以全部画出来时,改用 <ScatterChart>,把点一个个摆上去。
Recharts 在这里是配得上的:这些箱子需要一根带真实刻度的共享数值轴、一根分类轴、一层网格和一个 tooltip——这已经是一张笛卡尔图表的大半了。它没有的是箱形标记,所以每个箱子都是画在一根区间柱上的自定义图形——柱子负责提供分类带和刻度,而里面那个字形是我们自己的。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| children必填 | ReactNode | 组合进来的各个部分——坐标轴、网格、tooltip,以及 `<BoxPlot.Boxes>`。 | |
| data必填 | BoxPlotDatum[] | 一个分类一条,可以是原始观测,也可以是已经算好的摘要。 | |
| title必填 | string | 这张图在讲什么,用一句读者能据此行动的话。必填,而且即使不显示出来也会播报给读屏软件。 | |
| chartProps | ComponentProps<typeof RechartsBarChart> | 通往原始 Recharts 图表元素的逃生口。 | |
| className | string | 最后合并到 figure 上,所以调用处可以决定它的尺寸和间距。 | |
| config | ChartConfig | DEFAULT_CONFIG | 唯一那条序列——它的标签和上色。只会读**第一**项;箱线图只有一个度量,有几个分类就有几个箱子。 |
| description | ReactNode | 标题下面的一行——单位、时间窗口、需要提醒的地方。 | |
| empty | ChartEmptyProps | false | 图表没东西可画时显示什么。传 `false` 保留坐标轴,用于那种「空本身就是结论」的图。 | |
| formatValue | (value: number) => string | defaultTick | 格式化这张图印出来的每一个数——刻度、tooltip、表格。 |
| hideDataTable | boolean | false | 去掉隐藏的表格视图。只有当页面自己已经把数据印出来时,这才是对的。 |
| orientation | BoxPlotOrientation | 'vertical' | 箱子朝哪个方向排。当分类名长到必须在箱子底下斜着放时,用 `horizontal`。 |
| showTitle | boolean | 把标题印在图上方,而不是藏起来。 |
类型
export type BoxPlotOrientation = 'vertical' | 'horizontal'
export type BoxPlotDatum = BoxPlotSample | (BoxPlotSummary & { values?: never })无障碍
- 一个箱子就是五个数,而五个数分不出一个峰和两个峰。双峰分布画出来的箱子,和一个中心相同的光滑分布**一模一样**——组件把这一点写进了自己的说明里,而不是塞在脚注里。
- 它同样隐藏样本量:六个点画出来的箱子和六千个点画出来的一样。所以 count 值得带上,而在比较中位数时一定要打开 notched。
- 原始数值用 Tukey 栅栏归纳,这件事写在页面上而不是默认读者知道——换一套栅栏规则,同一份数据会画出不同的离群点。
- 隐藏的表格视图带着每个分类完整的五个数,所以不看图形也读得懂这张图。