简介
D3.js ,即D3,是一个JAVASCRIPT库。它的名字代表** D** ata-** D** riven** D** ocuments(3),它被认为是一个交互式的、动态的Web数据可视化库。
D3《S》第四版于2011年2月上映,2016年6月上映。在撰写本文时,最新的稳定版本是4.4版,并且正在不断更新。
D3利用可伸缩矢量图形 或** SVG** 格式,允许您渲染可以放大或缩小而不会降低质量的形状、线条和填充。
本教程将指导您使用JAVASCRIPT D3库创建条形图。
前提条件
要最大限度地利用本教程,您应该熟悉一些JavaScript编程语言,以及关于CSS和HTML的知识。
尽管您将使用css来设置D3的样式,但值得注意的是,许多在HTML上工作的标准css在SVG上的工作方式不同--也就是说,您将使用stroke
而不是border
,以及使用填充
而不是Color
。要了解更多信息,可以阅读Mozilla Developer Network上关于svg和CSS.的文章
我们将使用文本编辑器和Web浏览器。出于测试目的,建议使用诸如Firefox Developer Tools,或Chrome DevTools.]之类的工具来检查和调试脚本、超文本标记语言和css
第一步-创建文件和引用D3
让我们首先创建一个目录来保存我们所有的文件。你可以随心所欲地叫它,我们这里叫它D3-项目。创建后,移到目录中。
1mkdir D3-project
2cd D3-project
要使用D3‘S功能,您的网页中必须包含d3.js
文件。它大约有16,000行长,500kb。
让我们使用curl
将文件下载到我们的目录中。
要下载更适合包含在项目中的压缩版本,请键入:
1curl https://d3js.org/d3.v4.min.js --output d3.min.js
如果您计划阅读D3代码,通过输入以下命令可能更好地获得带有人类友好的空格的未压缩版本:
1curl https://d3js.org/d3.v4.js --output d3.js
在本教程中,我们将使用d3.min.js
文件,但如果您选择使用人类可读的版本,请在您的HTML文件中引用d3.js
。
因为D3版本4是模块化的,所以您也可以通过只拉入您将使用的模块来减小文件大小。
下载D3后,让我们设置CSS和HTML文件。你可以选择任何一个文本编辑器来处理这个文件,比如nano
。我们将从CSS文件style.css
开始,这样我们就可以立即从HTML文件链接到它。
1nano style.css
我们将从一个标准的CSS声明开始,以100%的高度设置页面的样式,不留边距。
1html, body {
2 margin: 0;
3 height: 100%;
4}
您现在可以保存并关闭该css文件。
接下来,我们将创建我们的JavaScript文件,我们将其命名为barchart.js
,因为我们将为本例制作一个条形图。这个文件是我们D3工作的主要部分,我们将在下一步开始处理它。因为我们现在不需要打开文件,可以使用Touch
命令。
1touch barchart.js
现在,让我们将所有这些元素连接到一个HTML文件,我们将其称为barchart.html
:
1nano barchart.html
我们可以像大多数其他的HTML文件一样设置这个文件,在它里面我们将引用我们刚刚创建的yle le.css
和barchart.js
文件以及d3.min.js
脚本。
1[label barchart.html]
2<!DOCTYPE html>
3<html lang="en">
4 <head>
5 <meta charset="utf-8">
6 <title>Bar Chart</title>
7 <link rel="stylesheet" type="text/css" href="style.css">
8
9 <!-- Alternatively use d3.js here -->
10 <script type="text/javascript" src="d3.min.js"></script>
11
12 </head>
13
14 <body>
15 <script type="text/javascript" src="barchart.js"></script>
16 </body>
17</html>
现在可以保存并关闭该HTML文件。
Step 2 -在JavaScript中设置SVG
我们现在可以使用我们选择的文本编辑器打开barchart.js
文件:
1nano barchart.js
让我们从添加一个数字数组开始,我们将使用它作为条形图的基础:
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
接下来,我们需要创建SVG元素。这就是我们要放置所有形状的地方。在D3中,我们使用d3.selt
来通知浏览器搜索元素。
我们可以使用一行d3.select().append();
来完成此操作,但如果将其声明为变量会更好,这样我们以后就可以在代码中引用它。
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg");
如果我们现在将barchart.html
加载到我们选择的Web浏览器中,我们应该能够使用我们的开发人员工具检查DOM 或** 文档对象模型 ** ,并将鼠标悬停在SVG框上。根据您的浏览器,它可能很小。
中可见
回到我们的JavaScript文件中,我们可以将属性 链接到SVG,使其成为网页的完整高度和宽度。我们将使用.attr()
作为属性。虽然我们可以将所有这些都放在一行中,但将它们分开会更具可读性。确保将分号下移到变量声明的末尾。
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg")
5 .attr("height","100%")
6 .attr("width","100%");
如果您在浏览器中重新加载页面,当您将鼠标悬停在DOM上时,您应该会看到一个占据整个屏幕的矩形。
第三步-添加矩形
准备好SVG后,我们就可以开始将数据集的矩形添加到JavaScript文件中。
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg")
5 .attr("height","100%")
6 .attr("width","100%");
7
8svg.selectAll("rect")
9 .data(dataArray)
10 .enter().append("rect");
与上面的d3.selt
一样,我们告诉浏览器搜索元素。这一次,它是针对矩形数组的。因为它是一个数组,所以我们使用d3.selectAll
,我们使用d3.selectAll()
,因为它是一个矩形数组。如果浏览器找到矩形,它将在选择中返回它们,如果它是空的,则返回空。在D3中,您必须首先选择要对其执行操作的元素。
我们使用.data(dataArray
)将这个矩形数组绑定到
dataArray`中存储的数据。
要为选择中的每一项实际添加一个矩形(对应于数据数组),我们还将添加.enter().append();
来附加矩形。在本例中,将有9个矩形对应于数组中的9个数字。
如果您现在重新加载页面,您将不会看到任何矩形,但如果您检查DOM,您将看到其中定义了9个矩形。
中显示的D3矩形
我们还没有为矩形设置属性以使它们可见,所以让我们将这些属性添加到中。
设置形状属性
我们可以使用.attr()
为形状添加属性,方法与为SVG定义属性的方式相同。D3中的每个形状将具有不同的属性,具体取决于它们的定义和绘制方式。
我们的矩形将包含4个属性:
()
用于矩形的高度()
用于矩形的宽度()
表示它们与浏览器窗口左侧的距离()
表示它们与浏览器窗口顶部的距离
因此,如果我们想要高250像素、宽40像素、距浏览器左侧25像素、距顶部50像素的矩形,我们将按如下方式编写代码:
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg")
5 .attr("height","100%")
6 .attr("width","100%");
7
8svg.selectAll("rect")
9 .data(dataArray)
10 .enter().append("rect")
11 .attr("height","250")
12 .attr("width","40")
13 .attr("x","25")
14 .attr("y","50");
如果我们刷新浏览器,我们将看到所有的矩形重叠:
中重叠
默认情况下,D3中的形状以黑色填充,但我们可以稍后修改,因为我们需要首先处理矩形的位置和大小。
让矩形反映数据
目前,我们的数组中的所有矩形在X轴上都有相同的位置,并且不以高度表示数据。
要修改矩形的位置和大小,我们需要为某些属性引入functions。添加这些函数将使该值成为动态而不是手动的。
让我们从修改x
属性开始。目前,该行代码如下所示:
1.attr("x","25")
我们将用一个函数替换25个像素的数字。我们将把D3定义的两个变量传递给Function()
,分别代表数据点和索引。索引告诉我们数据点在数组中的位置。通常使用d
作为数据点,使用i
作为索引,就像函数(d,i)
一样,但您可以使用任何您想要的变量。
JavaScript将遍历d
和i
。让它为它遍历的每个索引添加间距,以便每个矩形间隔开。要实现这一点,我们可以将索引`i‘乘以一定数量的像素。我们现在使用60,但您可以决定哪个间距适合您。我们的X轴属性的新行现在如下所示:
1.attr("x", function(d, i) {return i * 60;})
但是,如果我们现在运行代码,我们将看到矩形与浏览器的左侧齐平,所以让我们在那里添加一些额外的间距,比如距离边缘25个像素。现在,我们的完整代码应该如下所示:
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg")
5 .attr("height","100%")
6 .attr("width","100%");
7
8svg.selectAll("rect")
9 .data(dataArray)
10 .enter().append("rect")
11 .attr("height","250")
12 .attr("width","40")
13 .attr("x", function(d, i) {return (i * 60) + 25})
14 .attr("y","50");
如果我们在这一点上刷新浏览器,我们将看到如下所示:
现在,我们将矩形沿X轴隔开,表示数组中的每一项。接下来,让我们让矩形的高度反映数组中的数据。
我们现在将使用height
属性,并将添加一个类似于我们添加到x
属性的函数。让我们首先将变量d
和i
传递给函数
,然后返回d
。回想一下,d
代表数据点。
1.attr("height", function(d, i) {return (d)})
如果您现在运行代码,您将注意到两件事。首先,矩形相当小,其次,它们附着在图表的顶部,而不是底部。
为了解决矩形的小问题,让我们将返回的d
相乘:
1.attr("height", function(d, i) {return (d * 10)})
现在矩形的大小变大了,但它们仍然是从上到下显示的。
浏览器通常从左上角到右下角阅读网页,而我们从下到上阅读条形图。要重新定位矩形,我们将修改`y‘属性以减去顶部的空格。
同样,我们将使用函数(d,i)
,并返回一个比条形图的最高值更高的Y值,比方说400。我们将从400中减去返回的(d* 10)
的高度,结果如下所示:
1.attr("y", function(d, i) {return 400 - (d * 10)});
让我们看看完整的JavaScript代码:
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg")
5 .attr("height","100%")
6 .attr("width","100%");
7
8svg.selectAll("rect")
9 .data(dataArray)
10 .enter().append("rect")
11 .attr("height", function(d, i) {return (d * 10)})
12 .attr("width","40")
13 .attr("x", function(d, i) {return (i * 60) + 25})
14 .attr("y", function(d, i) {return 400 - (d * 10)});
此时,当我们重新加载页面时,我们将看到一个可以从下到上阅读的条形图:
中的D3条形图
现在,我们可以设置图表的样式了。
第四步--D3造型
我们将使用我们的css文件来设置D3形状的样式,但首先,为了使这项工作更容易,我们将在JavaScript文件中为矩形指定一个类名,以便在我们的css文件中引用。
添加一个类就像使用点符号添加任何其他属性一样。我们将类命名为‘bar’,因为它是一个条形图,但我们可以随心所欲地命名它,只要所有引用都引用相同的名称。我们的语法将如下所示:
1.attr("class", "bar")
我们可以随心所欲地添加此属性。将其保留为第一个属性可以使其更容易在我们的css文件中引用。
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg")
5 .attr("height","100%")
6 .attr("width","100%");
7
8svg.selectAll("rect")
9 .data(dataArray)
10 .enter().append("rect")
11 .attr("class", "bar")
12 .attr("height", function(d, i) {return (d * 10)})
13 .attr("width","40")
14 .attr("x", function(d, i) {return (i * 60) + 25})
15 .attr("y", function(d, i) {return 400 - (d * 10)});
现在,让我们切换到我们的yle le.css
文件,该文件目前如下所示:
1[label style.css]
2html, body {
3 margin: 0;
4 height: 100%
5}
我们可以通过更改矩形的填充颜色来开始修改矩形,引用我们刚刚创建的bar
类:
1[label style.css]
2html, body {
3 margin: 0;
4 height: 100%
5}
6
7.bar {
8 fill: blue
9}
在这里,我们将矩形设置为蓝色,也可以为它们分配十六进制颜色代码,如下所示:
1.bar {
2 fill: #0080FF
3}
此时,我们的矩形如下所示:
我们可以为矩形赋予附加值,例如用特定颜色勾勒矩形轮廓的stroke
和strokWidth
:
1[label style.css]
2html, body {
3 margin: 0;
4 height: 100%
5}
6
7.bar {
8 fill: #0080FF;
9 stroke: black;
10 stroke-width: 5
11}
这将为我们的矩形提供宽度为5个像素的黑色轮廓。
此外,我们还可以通过为鼠标悬停时更改的条形图颜色添加样式来为图表添加一些交互效果:
1.bar:hover {
2 fill: red
3}
现在,当我们将鼠标移到其中一个矩形上时,该特定矩形将变为红色:
或者,您也可以通过添加其他属性来设置JavaScript文件中形状的样式。在矩形块中,我们将像其他.attr()
属性一样编写这些属性。因此,在矩形周围添加黑色笔触将写为.attr()
。我们还将添加5个像素的笔划宽度
,并确保将分号向下移动。
1[label barchart.js]
2...
3svg.selectAll("rect")
4 .data(dataArray)
5 .enter().append("rect")
6 .attr("class", "bar")
7 .attr("height", function(d, i) {return (d * 10)})
8 .attr("width","40")
9 .attr("x", function(d, i) {return (i * 60) + 25})
10 .attr("y", function(d, i) {return 400 - (d * 10)})
11 .attr("stroke", "black")
12 .attr("stroke-width", "5");
您可以自行决定如何设置形状样式以及在哪个文件中设置样式。在本例中,我们将处理style le.css
文件,并将其限制为填充颜色和悬停填充:
1[label style.css]
2html, body {
3 margin: 0;
4 height: 100%
5}
6
7.bar {
8 fill: #0080FF
9}
10
11.bar:hover {
12 fill: #003366
13}
在网络上使用颜色时,重要的是要记住你的受众,并尽可能地使用普遍可访问的颜色。要了解更多关于颜色可访问性的注意事项,您可以查看Acessibility & Me。
第五步-添加标签
我们的最后一步是将一些可量化的标记以标签的形式添加到我们的图中。这些标签将与我们数组中的数字相对应。
添加文本类似于添加上面所做的矩形形状。我们需要选择文本,然后将其附加到SVG。我们还会将其绑定到我们创建的dataArray
。我们将使用Text
而不是rect
,但一般格式类似于我们添加上述矩形时所做的操作。我们将把这些行添加到barchart.js
文件的底部。
1[label barchart.js]
2var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
3
4var svg = d3.select("body").append("svg")
5 .attr("height","100%")
6 .attr("width","100%");
7
8svg.selectAll("rect")
9 .data(dataArray)
10 .enter().append("rect")
11 .attr("class", "bar")
12 .attr("height", function(d, i) {return (d * 10)})
13 .attr("width","40")
14 .attr("x", function(d, i) {return (i * 60) + 25})
15 .attr("y", function(d, i) {return 400 - (d * 10)});
16
17svg.selectAll("text")
18 .data(dataArray)
19 .enter().append("text")
20 .text(function(d) {return d;});
当我们刷新浏览器时,我们将不会在页面上看到任何文本,但我们将在DOM中再次看到它:
中显示的D3文本
如果将鼠标悬停在DOM中的文本行上,您将看到文本都位于页面的顶部,其中X和Y等于0。我们将通过添加属性,使用与矩形相同的函数公式来修改位置。
1[label barchart.js]
2...
3svg.selectAll("text")
4 .data(dataArray)
5 .enter().append("text")
6 .text(function(d) {return d})
7 .attr("x", function(d, i) {return (i * 60) + 25})
8 .attr("y", function(d, i) {return 400 - (d * 10)});
当你现在加载网页时,你会看到数字漂浮在条形图上方。
的文本标签
值得注意的是,因为这是SVG而不是图像,所以您可以像在页面上看到的任何其他文本一样选择文本。
从这里,您可以通过修改函数公式开始重新定位数字。例如,您可能希望使它们漂浮在栏杆上方:
1[label barchart.js]
2...
3svg.selectAll("text")
4 .data(dataArray)
5 .enter().append("text")
6 .text(function(d) {return d})
7 .attr("x", function(d, i) {return (i * 60) + 36})
8 .attr("y", function(d, i) {return 390 - (d * 10)});
或者,您可以通过修改矩形在Y轴上的位置来使数字浮动在矩形本身上。我们还希望使其更具可读性,因此让我们添加一个可以从style le.css
文件访问的类。
1[label barchart.js]
2...
3svg.selectAll("text")
4 .data(dataArray)
5 .enter().append("text")
6 .text(function(d) {return d})
7 .attr("class", "text")
8 .attr("x", function(d, i) {return (i * 60) + 36})
9 .attr("y", function(d, i) {return 415 - (d * 10)});
在我们的`style le.css‘文件中,我们将把文本变成白色和sans-serif,方法是在文件的底部添加以下行。
1[label style.css]
2...
3.text {
4 fill: white;
5 font-family: sans-serif
6}
的白色文本标签
您可以通过定位和设置样式来随意修改文本。例如,您可能还想更改style le.css
文件中的font-size
属性。
完成代码和代码改进
此时,您应该已经有了一个功能齐全的条形图,该条形图呈现在JAVASCRIPT的D3库中。让我们来看看我们所有的代码文件。
1[label barchart.html]
2<!DOCTYPE html>
3<html lang="en">
4 <head>
5 <meta charset="utf-8">
6 <title>Bar Chart</title>
7
8 <!-- Reference style.css -->
9 <link rel = "stylesheet" type="text/css" href="style.css">
10
11 <!-- Reference minified version of D3 -->
12 <script type="text/javascript" src="d3.min.js"></script>
13 </head>
14
15 <body>
16 <script type="text/javascript" src="barchart.js"></script>
17 </body>
18</html>
1[label style.css]
2html, body {
3 margin: 0;
4 height: 100%
5}
6
7/*Rectangle bar class styling*/
8
9.bar {
10 fill: #0080FF
11}
12
13.bar:hover {
14 fill: #003366
15}
16
17/*Text class styling*/
18
19.text {
20 fill: white;
21 font-family: sans-serif
22}
1[label barchart.js]
2// Create data array of values to visualize
3var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
4
5// Create variable for the SVG
6var svg = d3.select("body").append("svg")
7 .attr("height","100%")
8 .attr("width","100%");
9
10// Select, append to SVG, and add attributes to rectangles for bar chart
11svg.selectAll("rect")
12 .data(dataArray)
13 .enter().append("rect")
14 .attr("class", "bar")
15 .attr("height", function(d, i) {return (d * 10)})
16 .attr("width","40")
17 .attr("x", function(d, i) {return (i * 60) + 25})
18 .attr("y", function(d, i) {return 400 - (d * 10)});
19
20// Select, append to SVG, and add attributes to text
21svg.selectAll("text")
22 .data(dataArray)
23 .enter().append("text")
24 .text(function(d) {return d})
25 .attr("class", "text")
26 .attr("x", function(d, i) {return (i * 60) + 36})
27 .attr("y", function(d, i) {return 415 - (d * 10)});
这段代码完全正常工作,但是您可以做很多事情来改进代码。例如,您可以利用SVG组元素将SVG元素分组在一起,从而允许您在更少的代码行中修改文本和矩形。
您还可以通过不同的方式访问数据。我们使用数组来保存数据,但您可能希望可视化您已有权访问的数据,这些数据可能比在数组中正常工作的数据多得多。D3将允许您使用几种不同的数据文件类型:
- 超文本标记语言
- JSON
- 纯文本
- CSV(逗号分隔值)
- TSV(制表符分隔值)
- XML
例如,您可以在网站目录中放置一个JSON文件,然后将其连接到JavaScript文件
1d3.json("myData.json", function(json) {
2// code for D3 charts in here
3});
您还可以将D3库与您可能已经从普通的JavaScript中了解的其他交互功能组合在一起。
结论
本教程介绍了如何在JAVASCRIPTERD3库中创建条形图。您可以通过访问GitHub.上的D3API]了解更多关于D3.js的信息
其他编程语言提供了不限于Web浏览器的其他可视化数据的方法。从这里,您可以学习如何使用[matplotlib]与Python](https://andsky.com/tech/tutorials/how-to-plot-data-in-python-3-using-matplotlib).一起绘制数据