当前内容所在位置(可进入专栏查看其他译好的章节内容)
- 第一部分 D3.js 基础知识
- 第一章 D3.js 简介(已完结)
- 1.1 何为 D3.js?
- 1.2 D3 生态系统------入门须知
- 1.3 数据可视化最佳实践(上)
- 1.3 数据可视化最佳实践(下)
- 1.4 本章小结
- 第二章 DOM 的操作方法(已完结)
- 2.1 第一个 D3 可视化图表
- 2.2 环境准备
- 2.3 用 D3 选中页面元素
- 2.4 向选择集添加元素
- 2.5 用 D3 设置与修改元素属性
- 2.6 用 D3 设置与修改元素样式
- 2.7 本章小结
- 第三章 数据的处理 ✔️
- 3.1 理解数据(已完结)
- 3.2 准备数据(已完结)
- 3.3 将数据绑定到 DOM 元素(已完结)
- 3.3.1 利用数据给 DOM 属性动态赋值
- 【3.4 让数据适应屏幕】 ✔️
- 3.4.1 比例尺简介(上篇)
- 3.4.2 线性比例尺(中篇)
- 3.4.2.1 基于 Mocha 测试 D3 线性比例尺(DIY 实战)
- 3.4.3 分段比例尺(下篇) ✔️
- 3.5 加注图表标签(待翻译 ⏳)
- 3.6 本章小结
文章目录
-
-
- [3.4.3 分段比例尺 Band scale](#3.4.3 分段比例尺 Band scale)
-
《D3.js in Action》全新第三版封面
3.4.3 分段比例尺 Band scale
绘制示例条形图要用到的第二种比例尺为 分段比例尺(band scale)。它属于之前介绍的第四类(详见 3.4.1 节内容):接受离散型输入、返回连续型输出。要在可用空间内处理离散的各矩形条的分布,这正是 D3 分段比例尺的强项。
声明一个分段比例尺,需要调用 d3.scaleBand()
函数。在以下代码片段中,分段比例尺赋给了常量 yScale
,表示它将负责 y 轴方向的元素排布。该比例尺的定义域,是一个包含数据集所有技术(technology
)名称的数组,可通过 JavaScript
的 map()
函数生成(关于 map()
的用法,可参考前面的 1.2.5 节内容)。至于比例尺的值域,则覆盖所有可用的垂直空间,即从 SVG 容器顶部的 0
像素一直到其底部的 700px
:
js
const yScale = d3.scaleBand()
.domain(data.map(d => d.technology))
.range([0, 700]);
向 createViz()
内部加入该比例尺,并写在数据绑定逻辑的代码前面。当使用数据集中的某项技术调用该函数时,会得到该技术对应的矩形条垂直坐标。例如,将字符串 "Excel"
传给 yScale
,将得到 0
,因为与 Excel
对应的矩形条是条形图中的第一个矩形,位于最上方;同理,若传入 "D3.js"
,则返回 272.72
,它代表 D3 对应的矩形条左上角的垂直坐标:
js
yScale("Excel") // => 0
yScale("D3.js") // => 272.72
之前每个矩形条的 y
属性值是通过手动计算得到的,还有印象吗?现在有了分段比例尺,我们可以非常轻松地用它来算出各矩形条的实际纵坐标:
js
svg
.selectAll("rect")
.data(data)
.join("rect")
...
.attr("y", d => yScale(d.technology))
...
分段比例尺还提供了一个非常方便的工具方法:bandwidth()
。它会返回矩形条的厚度。该厚度与矩形条的数量和可用空间成正比。本例中,该厚度即为矩形条的 height
属性值。如以下代码段所示,可以通过分段比例尺的 bandwidth()
方法来设置 height
属性:
js
svg
.selectAll("rect")
.data(data)
.join("rect")
...
.attr("height", yScale.bandwidth())
...
保存项目并在浏览器中查看,会看到如图 3.27 所示的效果。条形图填满了 SVG 容器所有可用的垂直空间。由于各矩形条间没有间隙,条形图看起来十分拥挤,阅读体验极差。
【图 3.27 配置了分段比例尺但没有设置间距的条形图效果】
间距的问题可以通过分段比例尺的 paddingInner()
属性(property)来解决。该属性专门用于指定各矩形条间的内边距(padding)大小,并接受一个 0
到 1
之间的值,这里设置为 0.2
,表示大小为矩形条高度的 20%
:
js
const yScale = d3.scaleBand()
.domain(data.map(d => d.technology))
.range([0, 700])
.paddingInner(0.2);
完成以上设置后,重新加载示例页面,条形图的布局看起来就好多了,如图 3.28 所示:
【图 3.28 配置了分段比例尺并添加间隙后的条形图效果】
而图 3.29 则梳理并复盘了 D3 分段比例尺的工作原理。首先是接受一个定义域,即数据集中的技术列表,并令其均匀分布到指定的值域内(即 SVG 容器垂直方向上的可用空间)。各矩形条的左上角垂直坐标可以通过调用分段比例尺函数计算得到(如 yScale("PowerPoint")
);同理,调用该比例尺的 bandwidth()
方法可以得到矩形条的高度值(即 yScale.bandwidth()
)。最后是各矩形条的间距,默认情况下为 0
,手动设置间距可以通过指定分段比例尺的 paddingInner()
属性实现(property)。它接受一个 0
到 1
之间的值,代表当前每个矩形条间的内边距大小(同时也表示其相对于矩形条高度 height
的百分比值)。
【图 3.29 分段比例尺在垂直方向的可用空间内均匀排布技术列表时的原理图】
译注
虽然作者没有提及,但本节附带的练习源码中我也加入了 Mocha.js 相关的测试代码,可以对分段比例尺的相关特性展开测试。感兴趣的小伙伴可以下载到本地试试,这里就不展开了。我本人实测过程中,发现最后的条形图并未居中,原来是上一次练习线性比例尺时忘了修改
x
属性的值,将0
更正为100
就和书中截图一样了。特此说明。