可视化前端初探(一)--D3.js

96
nightZing
0.2 2017.12.14 18:28* 字数 1905

一.D3.js 概述

1.D3 是什么
D3 的全称是(Data-Driven Documents),翻译过来就是一个被数据驱动的文档。简而言之,就是一个主要是用来做数据可视化的 JavaScript 的函数库。由于它本质上是 JavaScript ,所以用 JavaScript 也是可以实现所有功能的,但它能大大减小你的工作量,尤其是在数据可视化方面,D3 已经将生成可视化的复杂步骤精简到了几个简单的函数,你只需要输入几个简单的数据,就能够转换为各种绚丽的图形。

2.什么是数据可视化以及为什么要数据可视化

将枯燥乏味复杂的数据以图形的方式表现出来,这就是数据可视化。如现在有一组数据【5,15,23,78,110,57,29,34,71】,这里的数据不多,还是比较容易直接看出它们的大小关系,但更直观的是用图形显示,如下图:

数据可视化条形图.png

通过图形的显示,能很清楚地知道他们的大小关系。这只是D3.js这个框架的一个应用示例,它具有更强大的功能。

3.为什么用D3这类js框架来做前端数据可视化

就拿上面数据可视化条形图来举例子,我们用原生js来实现这个效果。

目标:用横向柱状图来直观显示以下数据
var data = [5,15,23,78,110,57,29,34,71];

HTML代码:

<html>
<head>
</head>
<body>
    <div id="barChart"></div>
</body>
</html>

css代码:

#barChart{
    background:#f0f0f0;
    padding:10px;
    font-family:Verdana;
        color:white;
}
#barChart .bar{
    left:0px;
    height:20px;
    background:blue;
    margin:5px;
}

js代码:

//要展示的数据对象
var data =  [5,15,23,78,110,57,29,34,71];;

window.onload = function(){
    //计算data的长度
    var len = data.length;

    //获取容器DOM对象
    var barChart = document.querySelector("#barChart");

    //创建len个div对象,并设置其属性
    for(var i=0;i<len;i++){
        //创建一个新DOM元素
        var e = document.createElement("div");
        //设置元素的CSS类为bar
        e.setAttribute("class", "bar");
        //设置元素宽度为对应数据值
        e.style.width = data[i] + 50;
        //设置元素的文本为对应数据值
        e.innerText = data[i];
        //向容器追加此DIV对象
        barChart.appendChild(e);
    }
};

可以看到哪怕只是一个很简单很基础的数据图表,也要写不少js代码,当可视化数据越来复杂时,就需要D3这样的封装库来提高开发效率了。

4.D3的几个特点概述

(1). d3.js不是一个图形绘制库,依赖于标准的web技术来绘制可视化元素,比如 HTML、SVG、CSS。
(2).d3.js是一个基于集合概念的DOM操作库,它对DOM操作进行了封装。和jQuery类似,d3依赖于选择符选 中一组元素,建立一个集合,然后使用集合对象的方法操作DOM。
(3).d3.js的大量功能集中在数据处理方面,要将数据映射到图形,有很多琐碎的工作,比如数据范围的变换、插值的计算、布局的 计算等等
(4).d3.js的核心是对数据和可视化元素的匹配,一个数据对应一个可视化元素,一个 数值对应一个可视化元素的属性。d3封装了这个匹配的复杂过程,让我们得以简单的 通过声明数据和可视化元素来完成数据可视化的任务。

4.D3的下载和使用
D3官网 里面有详尽的文档,只不过是英文的
D3github地址 里面有详细的安装和使介绍

二.D3.js 语法基础

1.选择集
使用 d3.select() 或 d3.selectAll() 选择元素后返回的对象,就是选择集。
D3 能够连续不断地调用函数,列如:d3.select().selectAll().text(),这称为链式语法,和 JQuery 的语法很像。如下示例,用 D3 来更改 文本和样式

<html> 
  <head> 
        <meta charset="utf-8"> 
        <title>HelloWorld</title> 
  </head> 
    <body> 
        <p>Hello World 1</p>
        <p>Hello World 2</p>
        <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
        <script>  
          var p = d3.select("body")
          .selectAll("p")
          .text("http://www.jianshu.com");

          //修改段落的颜色和字体大小
          p.style("color","red").style("font-size","22px");           
        </script> 
    </body> 
</html>
运行结果

2.选择元素和绑定数据
(1)选择元素

d3.select():是选择所有指定元素的第一个
d3.selectAll():是选择指定元素的全部

var body = d3.select("body"); //选择文档中的body元素
var p1 = body.select("p");      //选择body中的第一个p元素
var p = body.selectAll("p");    //选择body中的所有p元素
var p = body.selectAll(".car");    //选择body中的所有类名为car的元素
var svg = body.select("svg");   //选择body中的svg元素
var rects = svg.selectAll("rect");  //选择svg中所有的svg元素

(2)绑定数据
D3 一个很强大的特点是能将数据绑定到 DOM 上,也就是绑定到文档上。
例如网页中有段落元素 <span> 和一个整数 100,于是可以将整数 100 与 <span>绑定到一起。绑定之后,当需要依靠这个数据才操作元素的时候,会很方便。

D3 中是通过以下两个函数来绑定数据的:
datum():绑定一个数据到选择集上
data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定

接下来分别使用 datum() 和 data(),将数据绑定到以下HTML元素上。

<p>我爱简书</p>
<p>I love jianshu</p>

用datum()实现

var str = "nightzing";
var body = d3.select("body");
var p = body.selectAll("p");
p.datum(str);
p.text(function(d, i){
    return "第 "+ i + " 个元素绑定的数据是 " + d;
});
运行结果

在上面的代码中,用到了一个无名函数 function(d, i)。当选择集需要使用被绑定的数据时,常需要这么使用。其包含两个参数,其中:

d 代表数据,也就是与某元素绑定的数据。
i 代表索引,代表数据的索引号,从 0 开始。

用data()实现

var dataset = ["I like food","I like gaoxiao"];

var body = d3.select("body");
var p = body.selectAll("p");

p.data(dataset)
  .text(function(d, i){
      return d;
  });
运行结果

以上代码也用到了一个无名函数 function(d, i),其对应的情况如下:

当 i == 0 时, d 为 I like food。
当 i == 1 时, d 为 I like gaoxiao。
此时,元素与数组 dataset 的三个字符串是一一对应的,因此,在函数 function(d, i) 直接 return d 即可。

(3)插入元素
插入元素涉及的函数有两个:

append():在选择集末尾插入元素
insert():在选择集前面插入元素

HTML元素同上,以下代码是插入元素的示例。

/* 在 body 的末尾添加一个 p 元素 */
body.append("p")
    .text("append p element")
/* 在 body 中 id 为 car 的元素前添加一个段落元素 */
body.insert("p","#car")
  .text("insert p element");

(4) 删除元素
删除一个元素时,对于选择的元素,使用 remove 即可,例如:

var p = body.select("#car");
p.remove();

三.D3.js 实战

基础讲完了,下面就为大家介绍几个D3实战的例子, D3 提供了许多的 SVG 图形的生成器,它们都是只支持 SVG 的。因此,在D3中使用 SVG 画布来绘制图表是很常见也是被推荐的一种方式。

1.横向条形图
在文章最开始介绍了用原生js来绘制简单的横向条形图,现在来介绍下用D3来绘制类似的效果。看D3代码之前可以先来简单的复习一下SVG基本知识,可以看看我之前的一篇文章,SVG全攻略

目标:用横向柱状图来直观显示以下数据
var data = [5,15,23,78,110,57,29,34,71];
为了代码简洁方便,直接用数值的大小来表示矩形的像素宽度,同时为了方便理解,元素和样式都都直接在D3的js代码中实现,之前用原生js实现的例子那里的html元素和css样式都可以不要了,直接写下面的代码即可实现效果

var rectHeight = 25; //每个矩形所占的像素高度(包括空白)
var data = [5,15,23,78,110,57,29,34,71];
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x",20)
.attr("y",function(d,i){
return i * rectHeight;
})
.attr("width",function(d){
return d;
})
.attr("height",rectHeight-2)
.attr("fill","blue");

运行结果

这段代码最主要的部分是:

svg.selectAll("rect")   //选择svg内所有的矩形
    .data(dataset)  //绑定数组
    .enter()        //指定选择集的enter部分
    .append("rect") //添加足够数量的矩形元素

有数据,而没有足够图形元素的时候,使用此方法可以添加足够的元素。
添加了元素之后,就需要分别给各元素的属性赋值。在这里用到了 function(d, i),前面已经讲过,d 代表与当前元素绑定的数据,i 代表索引号。给属性赋值的时候,是需要用到被绑定的数据,以及索引号的。最后一行代码:
.attr("fill","blue")
是给矩形元素设置颜色。正式开发中推荐写在 CSS 文件中去,方便归类和修改。这里为了便于理解,将样式直接写到元素里。

前端杂技