一.D3.js 概述
1.D3 是什么
D3 的全称是(Data-Driven Documents),翻译过来就是一个被数据驱动的文档。简而言之,就是一个主要是用来做数据可视化的 JavaScript 的函数库。由于它本质上是 JavaScript ,所以用 JavaScript 也是可以实现所有功能的,但它能大大减小你的工作量,尤其是在数据可视化方面,D3 已经将生成可视化的复杂步骤精简到了几个简单的函数,你只需要输入几个简单的数据,就能够转换为各种绚丽的图形。
2.什么是数据可视化以及为什么要数据可视化
将枯燥乏味复杂的数据以图形的方式表现出来,这就是数据可视化。如现在有一组数据【5,15,23,78,110,57,29,34,71】,这里的数据不多,还是比较容易直接看出它们的大小关系,但更直观的是用图形显示,如下图:
通过图形的显示,能很清楚地知道他们的大小关系。这只是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 文件中去,方便归类和修改。这里为了便于理解,将样式直接写到元素里。