D3是一个数据可视化工具,都说挺好。但是我个人这两天的体验来看,D3想要入门不是太简单,至少至少都要有HTML和JavaScript基础才行,对JavaScript的DOM要求也有点高。
其实网上也能找到很多学习资源。下面是我搜集的一些教程:
D3呢就是一个js库,使用它主要是用来做数据可视化的,官网上有很多酷炫的例子。
D3的官网
我最近学习的教程:
慕课网:使用D3制作图表
极客学院:D3.js入门教程
这两个教程对于初学者还是比较友好的,我前两天对D3还是一无所知,现在已经可以get到用D3画线图,面积图,柱状图,饼状图的方法了。
下面是我对画这几种图表的笔记:
线性图表
线性图表应该是最简单的图表了,我们从小学起就会画了,它可以用来描述两个变量之间的对应关系。
在绘制线性图表之前先在HTML文档中添加一个container容器,不要忘了引入D3的库文件。
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html lang="en">
<head>
<meta charset="UTF-8">
<title>D3-test-1</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="container"></div>
<script src="http://d3js.org/d3.v3.js"></script>
<script src="js/index.js"></script>
</body>
</html>
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 var width = 500,
height = 250,
margin = {left:50, top:30, right:20, bottom:20},
g_width = width - margin.left - margin.right,
g_height = height - margin.top - margin.bottom;
//svg
var svg = d3.select("#container") //选择container容器
.append("svg") //添加svg元素
//定义宽高
.attr("width",width)
.attr("height",height);
var g = d3.select("svg")
.append("g")
.attr("transform","translate("+margin.left+","+margin.top+")");//g元素偏移
//数据
var data = [1, 2, 4, 8, 3, 2, 5];
// 缩放函数,X轴线性缩放
var scale_x = d3.scale.linear()
.domain([0,data.length-1]) // 输入范围
.range([0,g_width]); //输出范围
//Y轴缩放函数
var scale_y = d3.scale.linear()
.domain([0,d3.max(data)])
.range([g_height,0]);//倒着写是为了让纵坐标在显示的时候是从下往上增大的(因为浏览器的左边原点在左上而数学习惯是在左下)
//绘制函数,line_generator是我们指定的绘制函数
var line_generator = d3.svg.line()
.x(function(d,i) { return scale_x(i);})//X轴的点用数据的下标来表示
.y(function(d) { return scale_y(d);})
.interpolate("cardinal");//指定拟合方式,如果没有它,图是折线形式的,有了它就很圆润了
//添加path路径,就可以绘图啦
d3.select("g")
.append("path")
.attr("d",line_generator(data));
//绘制X轴和Y轴
var x_axis = d3.svg.axis().scale(scale_x),
y_axis = d3.svg.axis().scale(scale_y).orient("left"); //orient("left")确定左边方向
g.append("g")
.call(x_axis)
.attr("transform","translate(0,"+g_height+")"); //偏移
g.append("g")
.call(y_axis)
//添加文字元素
.append("text")
.text("Price($)")
.attr("transform","rotate(-90)") //Y轴旋转-90°
.attr("text-anchor","end")
.attr("dy","1em");
js文件我都写了详细的注释。
style样式文件用来定义container容器,path路径以及坐标轴的一些样式。
style.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #container {
background-color: #ccc;
width: 500px;
height: 250px;
}
path {
fill: none;
stroke: #468284;
stroke-width: 2;
}
.domain, .tick line {
stroke: gray;
stroke-width: 1;
}
我觉得比较重要的就是选择元素select()
和插入元素append()
操作,还有缩放函数的方法和定义X轴、Y轴的方法。这些都是基础又基础的东西!
面积图表
面积图表是在线性图表的基础上绘制的
将绘制函数改为area()
函数:1
2
3
4
5
6//绘制函数,面积图用D3的area()函数绘制
var area_generator = d3.svg.area()
.x(function(d,i) { return scale_x(i);})
.y0(g_height)
.y1(function(d) { return scale_y(d);})
.interpolate("cardinal");
这个时候图表已经成为一个闭合的图形了:
在绘制图形后在添加一个填充样式.style("fill","#468284")
:1
2
3
4d3.select("g")
.append("path")
.attr("d",area_generator(data))
.style("fill","#468284");
一个面积图表就完成了。
柱状图表
柱状图的要点是添加矩形元素。这里跟上面线性图表的代码风格不太一样,是因为我觉得这个demo更直观,更清晰。
1 | <html> |
要特别注意的地方是理解enter()
的用法,在极客学院的教程上是这样讲的:
有数据,而没有足够图形元素的时候,使用此方法可以添加足够的元素。
如果数组为 [3, 6, 9, 12, 15],将此数组绑定到三个 p 元素的选择集上。可以想象,会有两个数据没有元素与之对应,这时候 D3 会建立两个空的元素与数据对应,这一部分就称为 Enter。而有元素与数据对应的部分称为 Update。如果数组为 [3],则会有两个元素没有数据绑定,那么没有数据绑定的部分被称为 Exit。示意图如下所示。
外部数据文件的读取
慕课网的教程讲到了外部数据文件的读取,我觉得挺有用的
值得注意的一点是浏览器读取本地文件,它有一个跨域请求的问题,会报如下的错误:
解决办法是使用server提供的一种访问机制,用Python启用服务器,你要是想运行呢,首先你要安装python,下面是python2.到3以下版本执行的命令
1 | python -m SimpleHTTPServer 8888 |
3以上用下面的命令
1 | python -m http.server 8888 & |
启用服务是在当前图表文件内运行的,启用服务后在浏览器中输入localhost:8888
就可以访问自己写的图表了
我们要读取的数据文件名为data.csv
1
2
3
4
5
6
7year,population
1953,5.94
1964,6.95
1982,10.08
1990,11.34
2000,12.66
2010,13.40
6次人口普查的数据,这里用到了D3的d3.csv(url[,accessor][,callback])
函数,以下面的函数为例,第一个参数是必选的,是我们要读取的csv文件的路径;第二个参数是数据的处理,定义一个type函数将字符串转换为数值的形式;第三个参数用一个函数调用的方式使用数据,把最终的数据放到data数组当中。1
2
3
4
5
6
7
8
9d3.csv("data.csv",type,function(data) {
console.log(data);
···
});
function type(d) {
d.population =+ d.population;
return d;
}
饼状图表
饼状图表的要点就是:第一我们要用d3.svg.arc()
画圆的函数;第二就是起始角度的设置:
HTML还是像线性图表一样定义一个container容器即可
1 |
|
数据文件
data.csv
1 | education,population |
index.js
1 | d3.csv("data.csv",type,function(data) { |