d3学习之(Data Visualization with d3.js Cookbook )(第四章)-1

第四章 范围,域

        在本章中我们将学习下面的内容:

           1.使用定量范围尺

           2.使用时间范围尺

           3.使用分类范围尺

           4.插入字符串

           5.插入颜色

           6.插入对象

           7.其他自定义插入

     引言

     作为数据可视化的开发人员,对数据的范围和可视化的范围的界定是一项重要的任务,比如说可视化你最近购买一样物品价格为453美元,用长453px的div条,你在某个酒吧消费24美元,用长24px的div条。各自反映了各自的范围,这就是数据可视化通过可视化元素来精确直观反映数据的方式,数据范围是数据可视化一个基本的任务,D3在这方面提供了丰富的支持,这一章我们就来关注这个主题。

     什么是scales?

     D3提供了丰富的结构叫做scales来帮助你完成范围的界定,要成为一个出色的可视化工程师,理解和掌握这些结构的思想和概念是非常重要的。因为这个scales不仅是可以用来界定范围,也是其他d3结构的基础,比如转移和轴。那么这些scales到底是什么呢?简单来说,scales可以被认为是数学方法,数学方法在一些开发语言中不同于其他方法,比如在js方法,在数学上来说,方法是两个集合之间的映射。就像我们以前学过的数学f(a)=b。虽然这个定义很难懂,但是我们可以发现这种方式对数据可视化来说非常的有效,比如数据集为a,可视化元素集为b,那么通过f方法我们就能完成数据到可视化元素的映射关系。另一个我们需要理解的基础内容就是函数的定义域和值域,这个初中高中数学中应该都有讲到。来复习下,如果一个方法f是数据集A到数据集B的映射,那么A就是f的定义域,B就是f的值域。为了帮助理解我们来看下图:

d3学习之(Data Visualization with d3.js Cookbook )(第四章)-1_第1张图片

      function f maps A to B

    在上图我们就可以很清楚的看出这些关系,设想下如果A是我们的数据集,B是我们的可视化元素集,那么这里的f就是D3中的scale,完成A到B的映射。

    现在我们已经在概念上对D3的scale方法有所了解,现在我们就来看看这个方法是如何帮助我们来开发数据可视化的。


1.使用定量范围尺(Using quantitative scales)

     在这一部分,我们将检验D3常用的范围标尺,定量范围标尺,包括线性,幂度和对数范围尺。

     打开编辑器输入下面代码:

     

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Quantitative Scales</title>
     <link rel="stylesheet" type="text/css" href="styles.css"/>
     <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
</head>

<body>

<div id="linear" class="clear"><span>n</span></div>
<div id="linear-capped" class="clear">
    <span>1 <= a*n + b <= 20</span>
</div>
<div id="pow" class="clear"><span>n^2</span></div>
<div id="pow-capped" class="clear">
    <span>1 <= a*n^2 + b <= 10</span>
</div>
<div id="log" class="clear"><span>log(n)</span></div>
<div id="log-capped" class="clear">
    <span>1 <= a*log(n) + b <= 10</span>
</div>

<script type="text/javascript">
    var max = 11, data = [];
    for (var i = 1; i < max; ++i) data.push(i);

    var linear = d3.scale.linear() // <-A
        .domain([1, 10]) // <-B
        .range([1, 10]); // <-C        
    var linearCapped = d3.scale.linear()
        .domain([1, 10])        
        .range([1, 20]); // <-D
        
    var pow = d3.scale.pow().exponent(2); // <-E
    var powCapped = d3.scale.pow() // <-F
        .exponent(2)
        .domain([1, 10])
        .rangeRound([1, 10]); // <-G
        
    var log = d3.scale.log(); // <-H
    var logCapped = d3.scale.log() // <-I
        .domain([1, 10])
        .rangeRound([1, 10]);


    function render(data, scale, selector) {
        d3.select(selector).selectAll("div.cell")
                .data(data)
                .enter().append("div").classed("cell", true);

        d3.select(selector).selectAll("div.cell")
                .data(data)
                .exit().remove();

        d3.select(selector).selectAll("div.cell")
                .data(data)
                .style("display", "inline-block")
                .text(function (d) {
                    return d3.round(scale(d), 2);
                });
    }

    render(data, linear, "#linear");
    render(data, linearCapped, "#linear-capped");
    render(data, pow, "#pow");
    render(data, powCapped, "#pow-capped");
    render(data, log, "#log");
    render(data, logCapped, "#log-capped");
</script>

</body>

</html>
     上面的代码输出的内容为:

d3学习之(Data Visualization with d3.js Cookbook )(第四章)-1_第2张图片

      下面来看看这些是如何实现的,在上面的代码中我们展示了D3中最常用的scales。

        线性标尺(linear scale)

      首先我们在最开始利用for循环,创建了一个数组,里面的元素是从0到10的整数,接着在A处的代码我们创建了一个线性标尺,var linear = d3.scale.linear()该方法返回一个线性的定量标尺永远默认的定义域和值域[0,1].因此这个默认的映射就是对他数据本身的映射,因此这个默认的方法对我们并没有多大的意义,我们需要对它的定义域和值域进行自定义,在B和C处我们设置了它的定义域和值域,同样设置成了一样的[1,10],这样这个映射实际上就是f(n)=n。

var linear = d3.scale.linear() // <-A
        .domain([1, 10]) // <-B
        .range([1, 10]); // <-C  

输出的效果如下:


    

      第二个标尺就比较有趣一点了,并且更能说明对两个集合的映射关系。在D处,我们又定义了一个标度尺,并且这次我们将其定义域和值域设置成不同的范围。

var linearCapped = d3.scale.linear()
        .domain([1, 10])        
        .range([1, 20]); // <-D

     于是这里的映射函数就相当于数学方程式f(n)=a*n+b;1<=f(n)<=20;这种情况下的输出效果为:

    

     在这种情况下,D3会自动计算并且制定常量a和b的值来匹配等式。


     接下来我们创建的是幂度尺,在E处,var pow = d3.scale.pow().exponent(2); // <-E我们定义了一个幂度为2的幂度尺,默认的方法幂度为1。此时的输出如下:

     

     然后在F处,定义了另一个幂度尺,这里我们自定义了其定义域和值域

var powCapped = d3.scale.pow() // <-F
        .exponent(2)
        .domain([1, 10])
        .rangeRound([1, 10]); // <-G

     rangeRound和range的方法都是用来定义值域的,只是rangeRound的方法是取整数部分,忽略小数。这里的映射相当于方程式f( n) = a* n ^ 2 + b, 1 < = f( n) < = 10。

     输出的效果为:

     

     那么下面的对数标尺,原理和前面一样也不多做讲解。

 var log = d3.scale.log(); // <-H
    var logCapped = d3.scale.log() // <-I
        .domain([1, 10])
        .rangeRound([1, 10]);


    在D3中还提供了其他的定量标尺,包括quantize, threshold, quantile, and identity scales,出于篇幅限制不一一讲解,有兴趣的可以查看网页 https://github.com/mbostock/d3/wiki/Quantitative-Scales#wiki-quantitative 进行学习。

你可能感兴趣的:(d3学习之(Data Visualization with d3.js Cookbook )(第四章)-1)