第六章 比例尺的使用

    上一章制作了一个柱形图,当时有一个数组:

    绘图时,直接使用 250 给矩形的宽度赋值,即矩形的宽度就是 250 个像素。

    此方式非常具有局限性,如果数值过大或过小,例如:

    1. var dataset_2 = [ 2500, 2100, 1700, 1300, 900 ];

    对以上两个数组,绝不可能用 2.5 个像素来代表矩形的宽度,那样根本看不见;也不可能用 2500 个像素来代表矩形的宽度,因为画布没有那么长。

    于是,我们需要一种计算关系,能够:

    将某一区域的值映射到另一区域,其大小关系不变。

    这就是比例尺(Scale)。

    比例尺,很像数学中的函数。例如,对于一个一元二次函数,有 x 和 y 两个未知数,当 x 的值确定时,y 的值也就确定了。

    在数学中,x 的范围被称为定义域,y 的范围被称为值域

    D3 提供了多种比例尺,下面介绍最常用的两种。

    线性比例尺,能将一个连续的区间,映射到另一区间。要解决柱形图宽度的问题,就需要线性比例尺。

    假设有以下数组:

    现有要求如下:

    将 dataset 中最小的值,映射成 0;将最大的值,映射成 300。

    代码如下:

    1. var min = d3.min(dataset);
    2. var max = d3.max(dataset);
    3. var linear = d3.scale.linear()
    4. .domain([min, max])
    5. linear(0.9); //返回 0
    6. linear(2.3); //返回 175

    其中,d3.scale.linear() 返回一个线性比例尺。domain() 和 range() 分别设定比例尺的定义域和值域。在这里还用到了两个函数,它们经常与比例尺一起出现:

    • d3.max()
    • d3.min()

    这两个函数能够求数组的最大值和最小值,是 D3 提供的。按照以上代码,

    比例尺的定义域 domain 为:[0.9, 3.3]

    比例尺的值域 range 为:[0, 300]

    有一点请大家记住:

    d3.scale.linear() 的返回值,是可以当做函数来使用的。因此,才有这样的用法:linear(0.9)。

    序数比例尺

    有时候,定义域和值域不一定是连续的。例如,有两个数组:

    我们希望 0 对应颜色 red,1 对应 blue,依次类推。

    但是,这些值都是离散的,线性比例尺不适合,需要用到序数比例尺。

    1. var ordinal = d3.scale.ordinal()
    2. .domain(index)
    3. .range(color);
    4. ordinal(0); //返回 red
    5. ordinal(2); //返回 green
    6. ordinal(4); //返回 black

    用法与线性比例尺是类似的。

    在上一章的基础上,修改一下数组,再定义一个线性比例尺。

    其后,按照上一章的方法添加矩形,在给矩形设置宽度的时候,应用比例尺。

    1. svg.selectAll("rect")
    2. .enter()
    3. .append("rect")
    4. .attr("x",20)
    5. .attr("y",function(d,i){
    6. return i * rectHeight;
    7. })
    8. .attr("width",function(d){
    9. return linear(d); //在这里用比例尺
    10. })
    11. .attr("height",rectHeight-2)

    如此一来,所有的数值,都按照同一个线性比例尺的关系来计算宽度,因此数值之间的大小关系不变。

    下载地址: