0%

D3 基础知识

D3.js基础知识,介绍了添加元素、绑定数据、使用数据、矢量图SVG、比例尺Scale和坐标轴Axis。本篇案例都是使用D3.js v4版本。

D3官网:D3
参考教程:D3 Tutorials - Scott Murray

添加元素

1
d3.select("body").append("p").text("New paragraph!")

在html中添加了一个p标签,p标签text值为“New paragraph!”。

绑定数据

Array

1
2
3
4
5
6
7
var dataset = [5, 10, 15, 20, 25];
d3.select("body")
.selectAll("p")
.data(dataset)
.enter()
.append("p")
.text("New paragraph!");

d3.select("body") —— 在DOM中找到body节点。
.selctAll("p") —— 在上一步找到的body节点中选择所有的p标签节点。如果没有,返回空,但是这个空代表将要存在的段落。
.data(dataset) —— 绑定数据到选择的DOM元素上。
.enter() —— enter()将创建一个占位符元素,用来绑定数据。
.append("p") —— 获取enter()创建的占位符,将p元素插入到DOM中。
.text("New paragraph!") —— 为每个p元素插入文本值。

html中添加了5个p标签,text值均为“New paragraph!”。

TSV

TSV是一种方便的表格数据格式。该表格可以从Microsoft Excel等表格程序导出,也可以在文本编辑器中手工编写。每一行代表一个表行,其中每行的数据由制表符Tab分隔组成。第一行是标题行,并指定列名。例如,我们的数据文件data.tsv内容如下:

1
2
3
4
5
6
7
name	value
Locke 4
Reyes 8
Ford 15
Jarrah 16
Jone 23
Kwon 42

要在浏览器中使用此数据,需要从服务器下载文件,然后解析文件,将文件的文本转换为可用的JavaScript对象。这件事情可以由函数d3.tsv实现。
下载是异步的。当调用d3.tsv时,文件在后台下载然后返回数据。在下载完成后的某个时候,回调函数将使用新数据调用,如果下载失败,则返回错误。

1
2
3
4
5
// 1. 这里的代码首先运行,处于文件下载前。
d3.tsv("data.tsv", function(error, data) {
//3. 这里的代码最后运行,此时文件下载完成。
});
// 2. 这里的代码第二时间运行,文件正在下载中。

TSV文件的文本转换为JavaScript对象是这个样子:

1
2
3
4
5
6
7
8
var data = [
{name: "Locke", value: 4},
{name: "Reyes", value: 8},
{name: "Ford", value:15},
{name: "Jarrah", value: 16},
{name: "Jone", value: 23},
{name: "Kwon", value: 42}
]

使用d3.jsond3.csv能够分别从json文件、csv文件绑定数据,用法相同。

使用数据

1
2
3
4
5
6
7
var dataset = [5, 10, 15, 20, 25];
d3.select("body")
.selectAll("p")
.data(dataset)
.enter()
.append("p")
.text(function(d) { return d; });

创建了5个p标签,text值分别为5,10,15,20,25。

绘制div

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
<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
div.bar {
display: inline-block;
width: 20px;
height: 75px; /* We'll override this later */
background-color: teal;
margin-left: 2px;
}
</style>
</head>
<body>
<div id="example"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript">
var dataset = []; //Initialize empty array
for (var i = 0; i < 25; i++) { //Loop 25 times
var newNumber = Math.random() * 30; //New random number (0-30)
dataset.push(newNumber); //Add new number to array
}
d3.select("#example").selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
.style("height", function(d) {
var barHeight = d * 5;
return barHeight + "px";
});
</script>
</body>
<html>

效果图如下:

SVG

在绘制任何东西之前,必须先创建一个SVG元素,并将该SVG元素作为绘制视觉效果的画布。最好指定SVG的宽度和高度。

1
<svg width="500" height="50"></svg>

常用的svg标签有rectcircleellipselinetextpath

rect

rect绘制一个矩形。使用x和y指定左上角的坐标,width和height分别指定矩形的宽度和高度。

1
<rect x="0" y="0" width="500" height="50" />

效果图:

circle

circle绘制一个圆。使用cx和cy指定圆心的坐标,r指定半径。

1
<circle cx="250" cy="25" r="25" />

效果图:

ellipse

ellipse绘制一个椭圆。与圆类似,使用cx和cy指定中心的坐标,但是对于每个轴需要单独的半径值。rx为横轴方向的半径,ry为纵轴方向的半径。

1
<ellipse cx="250" cy="25" rx="100" ry="25" />

效果图:

line

line绘制一条线条。使用x1和y1来指定线一端的坐标,x2和y2指定另一端的坐标。必须指定线条的颜色使线条可见。

1
<line x1="0" y1="0" x2="500" y2="50" stroke="black" />

效果图:

text

text呈现文字。使用x指定左边缘的位置,y指定基线的垂直位置。

1
<text x="250" y="25">Hello World</text>

效果图:

Hello World

text继承父元素CSS指定的字体样式。我们也可以覆盖格式如下:

1
<text x="250" y="25" font-family="sans-serif" font-size="25" fill="steelblue">Hello World</text>

效果图:

Hello World

path

path用于绘制更为复杂的内容(如地理图的国家轮廓等)。现在,我们先掌握简单的形状。

Scale

D3的scale函数可以定义一个缩放比例。调用scale函数时,传入一个数据值,可以返回一个缩放后的输出值。

创建一个Scale:

1
var scale = d3.scaleLinear();

使用domain函数可以设置数据的输入域:

1
scale.domain([100, 500]);

使用range函数可以设置数据的输出域:

1
scale.range([10, 350]);

可以将上述步骤链接在一行代码中:

1
2
3
4
5
6
7
var scale = d3.scaleLinear()
.domain([100, 500])
.range([10, 350]);

scale(100); //Returns 10
scale(300); //Returns 180
scale(500); //Returns 350

Axis

axis函数用来创建坐标轴。
d3.axisTop - 创建一个上部轴生成器。
d3.axisRight - 创建一个右部轴生成器。
d3.axisBottom - 创建一个底部轴生成器。
d3.axisLeft - 创建一个左部轴生成器。

1
var xAxis = d3.axisBottom();

每个轴需告知操作的尺度规模大小,即scale:

1
xAxis.scale(xScale);

可以使用ticks函数告诉坐标轴粗略的设置几个刻度:

1
xAxis.ticks(5);

我们也可以把代码链接起来:

1
2
3
var xAxis = d3.axisBottom()
.scale(xScale)
.ticks(5);

最后,我们把生成的轴插入到SVG中。

1
2
svg.append("g")
.call(xAxis);