D3.js 第6课 比例尺的使用

第6课 比例尺的使用

这里写图片描述
比例尺是 D3 中很重要的一个概念

为什么要用比例尺

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

var dataset = [ 250 , 210 , 170 , 130 , 90 ];

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

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

var dataset_1 = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
var dataset_2 = [ 2500, 2100, 1700, 1300, 900 ];

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

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

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

这就是比例尺(Scale)。

有哪些比例尺

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

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

D3 中的“比例尺”

有定义域和值域
定义域: domain
值域:range

开发者需要指定 domain 和 range 的范围,如此即可得到“一个计算关系”

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

线性比例尺

能将一个连续的区间,映射到另一区间

解决柱形图宽度的问题,就需要线性比例尺。

如下数组

var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];

将 dataset 中最小的值,映射成 0;将最大的值,映射成 300。
代码如下:

var min = d3.min(dataset);
var max = d3.max(dataset);

var linear = d3.scale.linear()
        .domain([min, max])
        .range([0, 300]);

linear(0.9);    //返回 0
linear(2.3);    //返回 175
linear(3.3);    //返回 300

scale:比例尺
d3.scale.linear() : 返回一个线性比例尺
domain():设定比例尺的定义域
range():设定比例尺的值域

d3.max():求数组的最大值
d3.min():求数组的最小值

按照以上代码,

比例尺的定义域 domain 为:[0.9, 3.3]
比例尺的值域 range 为:[0, 300]

因此,
当输入 0.9 时,返回 0;
当输入 3.3 时,返回 300。
当输入 2.3 时呢?返回 175,这是按照线性函数的规则计算的。

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

序数比例尺

定义域和值域不一定是连续的

如这两个数组:

var index = [0, 1, 2, 3, 4];
var color = ["red", "blue", "green", "yellow", "black"];

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

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

var ordinal = d3.scale.ordinal()
        .domain(index)
        .range(color);

ordinal(0); //返回 red
ordinal(2); //返回 green
ordinal(4); //返回 black

ordinal() 序数比例尺

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

给柱形图添加比例尺

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

var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];

var linear = d3.scale.linear()
        .domain([0, d3.max(dataset)])
        .range([0, 250]);

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

var rectHeight = 25;   //每个矩形所占的像素高度(包括空白)

svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x",20)
    .attr("y",function(d,i){
         return i * rectHeight;
    })
    .attr("width",function(d){
         return linear(d);   //在这里用比例尺
    })
    .attr("height",rectHeight-2)
    .attr("fill","steelblue");

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

源代码一如下:

<html>  
<head>  
    <meta charset="utf-8">  
    <title>比例尺的使用</title>  
</head>

<body>  

    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>  
    <script>

    var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];

    var min = d3.min(dataset);
    var max = d3.max(dataset);

    var linear = d3.scale.linear()
                    .domain([min, max])
                    .range([0, 300]);

    linear(0.9);    //返回 0
    linear(2.3);    //返回 175
    linear(3.3);    //返回 300


    var index = [0, 1, 2, 3, 4];
    var color = ["red", "blue", "green", "yellow", "black"];

    var ordinal = d3.scale.ordinal()
                    .domain(index)
                    .range(color);

    ordinal(0); //返回 red
    ordinal(2); //返回 green
    ordinal(4); //返回 black


    </script>  

</body>  
</html>  

源代码二 如下:

<html>  
<head>  
    <meta charset="utf-8">  
    <title>给柱形图添加比例尺</title>  
</head>

<body>  

    <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>  
    <script>

    var width = 300;    //画布的宽度
    var height = 300;   //画布的高度

    var svg = d3.select("body")             //选择文档中的body元素
                .append("svg")              //添加一个svg元素
                .attr("width", width)       //设定宽度
                .attr("height", height);    //设定高度

    var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];

    var linear = d3.scale.linear()
                    .domain([0, d3.max(dataset)])
                    .range([0, 250]);

    var rectHeight = 25;    //每个矩形所占的像素高度(包括空白)

    svg.selectAll("rect")
          .data(dataset)
          .enter()
          .append("rect")
          .attr("x",20)
          .attr("y",function(d,i){
                return i * rectHeight;
          })
          .attr("width",function(d){
                return linear(d);
          })
          .attr("height",rectHeight-2)
          .attr("fill","steelblue");


    </script>  

</body>  
</html>  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值