D3入门总结

D3.js 是基于数据操作文档的 JavaScript 库,通过 HTML、SVG 和 CSS 赋予数据以生命。D3 集强力的可视化组件与数据驱动型的 DOM 操作手法于一身,能最大限度地引出现代浏览器的性能,而不必束缚于特定的框架。

基础

选择元素

1
d3.select()

选择所有指定元素的第一个

1
d3.selectAll()

选择指定元素的全部

绑定元素

1
data()

绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定

1
dataum()

绑定一个数据到选择集上

1
function(d, i){ }

当选择集需要使用被绑定的数据时,常需要使用匿名函数。其包含两个参数,其中:
d 代表数据,也就是与某元素绑定的数据
i 代表索引,代表数据的索引号,从 0 开始

插入元素

1
append()

在选择集末尾插入元素

1
insert()

在选择集前面插入元素

删除元素

1
remove()

添加画布

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

绘制矩形

1
2
3
4
5
var dataset = [ 250 , 210 , 170 , 130 , 90 ];
svg.selectAll("rect") //选择svg内所有的矩形
.data(dataset) //绑定数组
.enter() //指定选择集的enter部分
.append("rect") //添加足够数量的矩形元素

有数据,而没有足够图形元素的时候,使用此方法可以添加足够的元素。

矩形的属性,常用的有四个:

  • x - 矩形左上角的 x 坐标
  • y - 矩形左上角的 y 坐标
  • width - 矩形的宽度
  • height - 矩形的高度

注意,在 SVG 中,x 轴的正方向是水平向右,y 轴的正方向是垂直向下的。

比例尺缩放

1
d3.scale.linear()

返回一个线性比例尺

1
2
domain()
range()

设定比例尺的定义域和值域

1
2
d3.max()
d3.min()

求数组的最大值和最小值

线性比例尺

1
2
3
4
5
6
7
8
9
10
11
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

上面的方法将dataset中最小的值,映射成0;将最大的值,映射成 300。

d3.scale.linear() 的返回值,是可以当做函数来使用的。因此,有这样的用法:linear(2.3),返回175。

序数比例尺

1
2
3
4
5
6
7
8
9
10
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

定义坐标轴

1
d3.svg.axis()

D3 中坐标轴的组件,能够在 SVG 中生成组成坐标轴的元素。

要生成坐标轴,需要用到比例尺,它们二者经常是一起使用的。

1
2
3
4
5
6
7
8
9
10
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 axis = d3.svg.axis()
.scale(linear) //指定比例尺
.orient("bottom") //指定刻度的方向
.ticks(7); //指定刻度的数量

  • scale():指定比例尺。
  • orient():指定刻度的朝向,bottom 表示在坐标轴的下方显示。
  • ticks():指定刻度的数量。

定义了坐标轴之后,只需要在 SVG 中添加一个分组元素 ,再将坐标轴的其他元素添加到这个 里即可

1
svg.append("g").call(axis);

在 D3 中,call() 的参数是一个函数,调用之后,将当前的选择集作为参数传递给此函数

完整的柱形图

test.png

添加 SVG 画布

1
2
3
4
5
6
7
8
var width = 400;
var height = 400;
var padding = {left:30, right:30, top:20, bottom:20};
//在 body 里添加一个 SVG 画布
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);

定义数据和比例尺

1
2
3
4
5
6
7
8
9
var dataset = [10, 20, 30, 40, 33, 24, 12, 5];
//x轴的比例尺
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, width - padding.left - padding.right]);
//y轴的比例尺
var yScale = d3.scale.linear()
.domain([0,d3.max(dataset)])
.range([height - padding.top - padding.bottom, 0]);

定义坐标轴

1
2
3
4
5
6
7
8
9
//定义x轴
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
//定义y轴
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");

添加矩形和文字元素

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
//矩形之间的空白
var rectPadding = 4;
//添加矩形元素
var rects = svg.selectAll(".MyRect")
.data(dataset)
.enter()
.append("rect")
.attr("class","MyRect")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
} )
.attr("y",function(d){
return yScale(d);
})
.attr("width", xScale.rangeBand() - rectPadding )
.attr("height", function(d){
return height - padding.top - padding.bottom - yScale(d);
});
//添加文字元素
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class","MyText")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
} )
.attr("y",function(d){
return yScale(d);
})
.attr("dx",function(){
return (xScale.rangeBand() - rectPadding)/2;
})
.attr("dy",function(d){
return 20;
})
.text(function(d){
return d;
});

添加坐标轴的元素

1
2
3
4
5
6
7
8
9
10
11
//添加x轴
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
.call(xAxis);
//添加y轴
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.call(yAxis);

过渡效果

1
transition()

启动过渡效果。

其前后是图形变化前后的状态(形状、位置、颜色等等)

1
duration()

指定过渡的持续时间,单位为毫秒。

1
ease()

指定过渡的方式,常用的有:

  • linear:普通的线性变化
  • circle:慢慢地到达变换的最终状态
  • elastic:带有弹跳的到达最终状态
  • bounce:在最终状态处弹跳几次
    1
    delay()

指定延迟的时间,表示一定时间后才开始转变,单位同样为毫秒。此函数可以对整体指定延迟,也可以对个别指定延迟。

Update、Enter、Exit

如果数组为 [3, 6, 9, 12, 15],将此数组绑定到3个 p 元素的选择集上。可以想象,会有两个数据没有元素与之对应,这时候 D3 会建立两个空的元素与数据对应,这一部分就称为 Enter。而有元素与数据对应的部分称为 Update。

如果数组为 [3],则会有两个元素没有数据绑定,那么没有数据绑定的部分被称为 Exit。

2.png

  • update 部分的处理办法一般是:更新属性值
  • enter 部分的处理办法一般是:添加元素后,赋予属性值
  • exit 部分的处理办法一般是:删除元素(remove)