D3.js入门之比例尺的使用与绘制
FinGet 人气:0中国这么大,要在一张小小地图上画上中国,那么就需要按一定的比例缩小。D3 可视化画图,也是如此,例如:一个柱状图的最大值为10000,但是画布最大高度只有400,那么10000就只能被映射为400,那么8000、5000...又该映射成哪个值呢?
比例尺
D3中的比例尺大概有20多种(d3.scaleLinear
、d3.scalePow
、d3.scaleTime
、d3.scaleBand
等)。大体上可以分为三类:
- 连续输入和连续输出
- 连续输入和离散输出
- 离散输入和离散输出
常用比例尺
scaleLinear 线性比例尺
const scale = d3.scaleLinear() // 连续输入和连续输出 .domain([0, 500]) // 输入域 0 ~ 500 .range([0, 300]); // 输出域 0 ~ 300 console.log(scale(100)) // 60 console.log(scale(300)) // 180 console.log(scale(500)) // 300
scaleBand 有序序数比例尺
scaleBand
:有助于创建条形图,同时考虑每个条形之间的间隔。域被指定为一组值(每个波段一个值),范围为波段的最小和最大范围(例如条形图的总宽度)。
实际上scaleBand
会将范围拆分为n 个带区(其中n是域数组中的值的数量),并考虑在指定间隔的情况下计算条形图的位置和宽度。
const scale = d3.scaleBand() .domain([1,2,3,4]) .range([0,100]) console.log(scale(1)) // 0 console.log(scale(3)) // 50 console.log(scale(4)) // 75 console.log(scale.bandwidth()) // 25 (100 分为4份,每份25(柱状图宽度))
d3.scaleTime() 时间比例尺
d3.scaleTime()
类似于d3.scaleLinear()
线性比例尺,只不过输入域变成了一个时间轴。
const scale = d3.scaleTime() .domain([new Date(2022, 0, 1), new Date(2022, 0, 31)]) .range([0, 30]) console.log(scale3(new Date(2022, 0, 15))) // 14
scaleOrdinal 无序序数比例尺
const scale = d3.scaleOrdinal() // 离散输入和离散输出 .domain(['jack', 'rose', 'john', 'lucy']) .range([10, 20, 30]) console.log(scale("jack")); // 10 console.log(scale("lucy")); // 10 console.log(scale("rose")); // 20 console.log(scale("john")); // 30 console.log(scale("finget")) // 20 输入域以外的值 const scale = d3.scaleOrdinal() .domain(['jack', 'rose', 'john', 'lucy']) .range([10, 20, 30]) .unknown(23) // 指定未知输入域的输出值 console.log(scale("finget")) // 23
如果输入域大于输出域,domain()
的值按照顺序循环依次对应range()
的值
scalePoint 点比例尺
// 创建从一组离散值映射到指定范围内等距的点 const scale = d3.scalePoint() // 离散输入和离散输出 .domain(['jack', 'rose', 'john']) .range([0, 100]) console.log(scale4('jack')) // 0 console.log(scale4('rose')) // 50 console.log(scale4('john')) // 100 console.log(scale4.step()) // 访问点之间的距离 50
scaleThreshold 阈值比例尺
// scaleThreshold 将连续数值输入映射到范围定义的离散值 let scaleThreshold = d3.scaleThreshold() // 连续输入和离散输出 .domain([0, 10, 20]) .range(['small', 'medium', 'large', 'xlarge']) console.log(scaleThreshold(5)) // medium console.log(scaleThreshold(15)) // large console.log(scaleThreshold(25)) // xlarge console.log(scaleThreshold(35)) // xlarge console.log(scaleThreshold(45)) // xxlarge
如果指定了 domain 则将比例尺的输入范围设置为指定的数组。数组必须是升序排序的。值通常是数值,也可以是能进行排序的其他类型。如果输出域的值个数为 N
+ 1, 则输入域中值的个数必须为 N
. 如果比 N
少则对应的输出域中多余的值会被忽略。如果多于 N
则会出现返回 undefined
的情况。如果没指定 domain 则返回比例尺当前的输入域。
// invertExtent 返回输出域中的值 value 对应的输入范围 console.log(scaleThreshold.invertExtent('small')) // [Infinity, 0] console.log(scaleThreshold.invertExtent('medium')) // [0, 10] console.log(scaleThreshold.invertExtent('large')) // [10, 20] console.log(scaleThreshold.invertExtent('xlarge')) // [20, Infinity]
scaleQuantize 量化比例尺
const scale = d3.scaleQuantize() // 连续输入和离散输出 .domain([0, 10]) .range(['red', 'green', 'blue', 'pink']) console.log(scale(-1)) // red console.log(scale(2)) // red console.log(scale(8)) // pink console.log(scale(20)) // pink console.log(scale.invertExtent('red')) // [0, 2.5] console.log(scale.invertExtent('green')) // [2.5, 5] console.log(scale.invertExtent('blue')) // [5, 7.5] console.log(scale.invertExtent('pink')) // [7.5, 10]
颜色比例尺
D3提供了一些颜色比例尺:点击查看文档
d3.schemeCategory10 d3.schemeAccent d3.schemeDark2 d3.schemePaired d3.schemePastel1 d3.schemePastel2 d3.schemeSet1 d3.schemeSet2 d3.schemeSet3 // 定义一个序数颜色比例尺 let color = d3.scaleOrdinal(d3.schemeCategory10) console.log(color(1)) // #1f77b4
总结
本章介绍了几种常用的比例尺,D3 还有一些比例尺可以查看官方文档了解:
d3.scaleIdentity() // 恒等比例尺 d3.scaleSqrt() // 乘方比例尺 d3.scalePow() // 类似scaleSqrt的乘方比例尺 d3.scaleLog() // 对数比例尺 d3.scaleQuantile() // 分位数比例尺
上述的各种使用比例尺的例子都相当于一个正序的过程,从domain
的数据集映射到range
数据集中,那么有没有逆序的过程呢?D3中提供了invert()
以及invertExtent()
方法可以实现这个过程。
加载全部内容