介绍
D3.js,或D3,是一个JavaScript库。 它的名字代表 Data- Driven Documents (3 “D”s) 和它被称为一个互动和动态数据可视化库网络。 首次发布于2011年2月,D3的版本4于2016年6月发布。在撰写本文时,最新的稳定版本是4.4版本,并且不断更新。 D3利用 可缩放矢量图形 ,或 SVG格式,它可以让你呈现形状,线条和填充,可以放大或缩小,而不会丢失质量。 本教程将指导您使用JavaScript D3库创建条形图。先决条件
为了充分利用本教程,您应该熟悉JavaScript编程语言以及CSS和HTML的知识。 虽然你将使用CSS样式D3,这是值得注意的,很多标准的CSS,关于HTML的工作原理不同SVG的-也就是说,你会用stroke
代替
border
,和
fill
,而不是
color
。 要了解更多信息,您可以阅读
的SVG和CSS Mozilla开发者网络文章 。 我们将使用文本编辑器和网络浏览器。出于测试目的,推荐使用工具来检查和调试JavaScript,HTML和CSS如
Firefox的开发者工具 ,或
铬DevTools 。
第1步 - 创建文件和参考D3
让我们开始创建一个目录来保存我们所有的文件。你可以调用任何你想,我们会在这里称之为 D3项目 。一旦创建,移动到目录。mkdir D3-project
cd D3-project
要利用D3的功能,您必须包括
d3.js
在你的网页文件。它大约16,000行长和500kb。 让我们用
curl
将文件下载到我们的目录。 要下载更好的包含您的项目的压缩版本,请键入:
curl https://d3js.org/d3.v4.min.js --output d3.min.js
如果你计划阅读D3代码,最好是通过键入以下内容获得带有人类友好的空格的未压缩版本:
curl https://d3js.org/d3.v4.js --output d3.js
我们将使用
d3.min.js
整个教程文件,但如果您选择使用人类可读的版本,然后引用
d3.js
在HTML文件来代替。 由于D3版本4是模块化的,您可以通过仅提取您将使用的模块来减小文件大小。 随着D3下载,让我们设置我们的CSS和HTML文件。您可以选择任何文本编辑器,您想对这个文件的工作,如
nano
。 我们将与CSS文件,开始
style.css
,这样我们就可以立即从我们的HTML文件链接到它。
nano style.css
我们将从一个标准的CSS声明开始,将页面风格设置为100%高度,没有页边距。
html, body {
margin: 0;
height: 100%;
}
现在可以保存并关闭CSS文件。 接下来,我们将创建我们的JavaScript文件,我们将其命名为
barchart.js
因为我们将要做出一个柱状图的这个例子。 这个文件是我们D3工作的大部分将存在的地方,我们将开始在下一步工作。 因为我们不需要打开文件,现在和可以使用
touch
命令。
touch barchart.js
现在,让我们来连接所有这些元素一个HTML文件,我们将调用
barchart.html
:
nano barchart.html
我们可以建立这个文件像大多数其他的HTML文件,并在它里面,我们将引用
style.css
和
barchart.js
我们刚创建的文件以及该
d3.min.js
脚本。
barchart.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bar Chart</title>
<link rel="stylesheet" type="text/css" href="style.css">
<!-- Alternatively use d3.js here -->
<script type="text/javascript" src="d3.min.js"></script>
</head>
<body>
<script type="text/javascript" src="barchart.js"></script>
</body>
</html>
现在可以保存和关闭HTML文件。
第2步 - 在JavaScript中设置SVG
现在,我们可以打开barchart.js
与我们选择的文本编辑器文件中:
nano barchart.js
让我们开始添加一个数字数组,我们将使用它作为条形图的基础:
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
接下来,我们需要创建SVG元素。这是我们将放置我们所有的形状。在D3中,我们使用
d3.select
告诉浏览器搜索元素。 我们可以用单线做到这一点
d3.select("body").append("svg");
但它会更好,如果我们声明它作为一个变量,以便我们可以随时在我们的代码中引用它。
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg");
如果我们现在加载
barchart.html
到我们选择的网页浏览器,我们应该能够与我们的开发工具来检查
DOM或
文档对象模型将鼠标悬停在SVG框。根据您的浏览器,它可能相当小。
早在我们的JavaScript文件,我们可以链
属性的SVG,使其在网络页面的完整高度和宽度。 我们将使用
.attr()
的属性。虽然我们可以保持这一切都在一条线,它是一个更好的可读性打破了这一点。请确保将分号向下移动到变量声明的末尾。
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
如果您在浏览器中重新载入网页,当您将鼠标悬停在DOM上时,应该会看到一个占据整个屏幕的矩形。
第3步 - 添加矩形
随着我们的SVG准备好,我们可以开始将数据集的矩形添加到JavaScript文件。
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect");
像
d3.select
上面,我们告诉浏览器搜索元素。 这一次,它是一个矩形数组。 因为它是一个数组,我们使用
d3.selectAll
并且我们使用
d3.selectAll("rect")
因为它是矩形的阵列。如果浏览器找到矩形,它将在选择中返回它们,如果它是空的,它将被返回为空。使用D3,你必须首先选择你要采取行动的元素。 我们配合这个矩形阵列存储在数据
dataArray
使用
.data(dataArray)
。 要真正在选择添加一个矩形为每个项目(对应于数据数组),我们还将添加
.enter().append("rect");
以附加矩形。在此示例中,将有9个矩形对应于数组中的9个数字。 如果您现在重新载入网页,您将看不到任何矩形,但如果您检查DOM,您会看到定义的9个矩形。
我们还没有为矩形设置属性以使它们可见,所以让我们添加它们。
设置形状的属性
我们可以在我们定义了SVG的属性相同的方式属性添加到形状,通过使用.attr()
D3中的每个形状将具有不同的属性,这取决于它们如何被定义和绘制。 我们的矩形将包含4个属性:
("height", " height_in_pixels ")
为矩形的高度("width", " width_in_pixels ")
为矩形的宽度("x", " distance_in_pixels ")
从浏览器窗口的左边为他们的距离("y", " distance_in_pixels ")
用于从所述浏览器窗口的顶部的距离
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("height","250")
.attr("width","40")
.attr("x","25")
.attr("y","50");
如果我们刷新浏览器,我们会看到所有的矩形重叠:
默认情况下,D3中的形状填充为黑色,但我们可以稍后修改,因为我们需要首先解决矩形的位置和大小。
使矩形反映数据
目前,我们数组中的所有矩形都具有沿着X轴的相同位置,并且不以高度表示数据。 要修改矩形的位置和大小,我们需要为某些属性引入函数。添加函数将使值是动态的,而不是手动的。 让我们先从修改x
属性。目前这行代码看起来像这样:
.attr("x","25")
我们将用一个函数来替换25像素的数字。我们将路过维生素D3定义的两个变量
function()
,代表数据点和索引。 该索引告诉我们数组中数据点的位置。 这是惯例使用
d
数据点,
i
的指数,如
function(d, i)
但你可以使用任何你想要的变量。 JavaScript的将通过迭代
d
和
i
。 让我们为它迭代的每个索引添加间距,以便每个矩形间隔开。 要做到这一点,我们可以乘以索引
i
由一定数目的像素。我们现在使用60,但你可以决定哪个间距看起来适合你。我们的X轴属性新行如下所示:
.attr("x", function(d, i) {return i * 60;})
但是,如果我们现在运行代码,我们会看到矩形在浏览器左侧被刷新,所以让我们添加一些额外的间距,比如边缘25像素。现在我们的完整代码应该看起来像这样:
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("height","250")
.attr("width","40")
.attr("x", function(d, i) {return (i * 60) + 25})
.attr("y","50");
如果我们在此时刷新浏览器,我们将看到如下所示的内容:
现在我们有我们的矩形沿X轴间隔,代表我们数组中的每个项目。接下来,让矩形的高度反映数组中的数据。 现在,我们将与合作
height
属性,并会加入类似于我们已经添加到一个功能
x
属性。 让我们通过传递变量开始
d
和
i
来
function
,并返回
d
。 回想一下,
d
代表数据点。
.attr("height", function(d, i) {return (d)})
如果你现在运行代码,你会注意到两件事。首先,矩形是相当小,第二,它们附加到图表的顶部,而不是底部。
为了解决矩形的小尺寸,让我们乘以
d
返回的:
.attr("height", function(d, i) {return (d * 10)})
现在矩形的大小更大,但它们仍然显示从上到下。 浏览器通常从左上到右下阅读网页,而我们从底部到顶部读取条形图。要重新定位矩形,我们将修改
y
属性减去之上的空间。 同样,我们将使用
function(d, i)
我们会返回一个Y值比我们柱状图的最高值高,让我们说400我们将减去返回的高度
(d * 10)
400 ,所以我们的线现在看起来像这样:
.attr("y", function(d, i) {return 400 - (d * 10)});
让我们看看我们的完整JavaScript代码:
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("height", function(d, i) {return (d * 10)})
.attr("width","40")
.attr("x", function(d, i) {return (i * 60) + 25})
.attr("y", function(d, i) {return 400 - (d * 10)});
此时,当我们重新加载页面时,我们将看到一个条形图,我们可以从底部到顶部读取:
现在,我们可以处理图表样式。
第4步 - 使用D3进行样式化
我们将使用我们的CSS文件来设计我们的D3形状,但首先,为了使这个工作更容易,我们将给我们的矩形在JavaScript文件中的类名,我们可以在我们的CSS文件中引用。 添加类就像使用点表示法添加任何其他属性一样。我们将调用类的bar
,因为它是一个柱状图,但我们可以把它叫做什么,我们希望,只要所有引用参考相同的名称。我们的语法如下所示:
.attr("class", "bar")
我们可以在任何地方添加此属性。保持它作为第一个属性可以使我们的CSS文件中更容易引用。
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function(d, i) {return (d * 10)})
.attr("width","40")
.attr("x", function(d, i) {return (i * 60) + 25})
.attr("y", function(d, i) {return 400 - (d * 10)});
现在,让我们切换到我们
style.css
文件,目前看起来是这样的:
style.css
html, body {
margin: 0;
height: 100%
}
我们可以开始通过改变其填充颜色,引用修改我们的矩形
bar
我们刚刚创建的类:
style.css
html, body {
margin: 0;
height: 100%
}
.bar {
fill: blue
}
在这里,我们使矩形变成蓝色,我们可以给它们一个十六进制颜色代码,如:
.bar {
fill: #0080FF
}
在这一点上,我们的矩形看起来像这样:
我们可以给矩形,如附加的值
stroke
勾勒矩形在一个特定的颜色,和一个
stroke-width
:
style.css
html, body {
margin: 0;
height: 100%
}
.bar {
fill: #0080FF;
stroke: black;
stroke-width: 5
}
这将为我们的矩形提供一个宽度为5像素的黑色轮廓。
此外,我们还可以为图表添加一点交互性,方法是为鼠标悬停时更改条形颜色的样式:
.bar:hover {
fill: red
}
现在,当我们鼠标移动到一个矩形时,那个特定的矩形会变成红色:
或者,您可以通过添加其他属性来为JavaScript文件中的形状设置样式。在矩形块,我们会写这些像其他
.attr()
属性。 因此,围绕增加矩形黑色行程将被写为
.attr("stroke", "black")
我们还添加了
stroke-width
的5个像素,并且一定要向下移动分号。
barchart.js
...
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function(d, i) {return (d * 10)})
.attr("width","40")
.attr("x", function(d, i) {return (i * 60) + 25})
.attr("y", function(d, i) {return 400 - (d * 10)})
.attr("stroke", "black")
.attr("stroke-width", "5");
选择取决于你如何决定风格的形状和在什么文件。在这个例子中,我们将在工作
style.css
文件,并保持它仅限于填充颜色和悬停填写:
style.css
html, body {
margin: 0;
height: 100%
}
.bar {
fill: #0080FF
}
.bar:hover {
fill: #003366
}
当在网络上使用颜色时,重要的是要牢记您的受众,并努力包括尽可能普及的颜色。要了解更多关于颜色辅助功能的考虑,你可以检查出
Acessibility和我 。
第5步 - 添加标签
我们的最后一步是以标签的形式向图中添加一些可量化的标记。这些标签将对应于数组中的数字。 添加文本类似于添加我们上面做的矩形形状。我们需要选择文本,然后将其附加到SVG。我们也将它绑在dataArray
我们创建。 而不是
"rect"
,我们将使用
"text"
,但一般格式是类似于我们做了添加矩形上方。 我们将这些行添加到我们的底部
barchart.js
文件。
barchart.js
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function(d, i) {return (d * 10)})
.attr("width","40")
.attr("x", function(d, i) {return (i * 60) + 25})
.attr("y", function(d, i) {return 400 - (d * 10)});
svg.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function(d) {return d;});
当我们刷新浏览器时,我们不会在网页上看到任何文字,但我们会在DOM中再次看到:
如果将鼠标悬停在DOM中的文本行上,您将看到文本全部位于页面的顶部,X和Y等于0.我们将使用相同的函数公式修改位置,用于通过添加属性的矩形。
barchart.js
...
svg.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function(d) {return d})
.attr("x", function(d, i) {return (i * 60) + 25})
.attr("y", function(d, i) {return 400 - (d * 10)});
当您立即加载网页时,您会看到浮动在栏上方的数字。
值得注意的是,因为这是SVG而不是图像,你可以选择文本,就像在页面上看到的任何其他文本。 从这里,您可以通过修改函数公式开始重新定位数字。您可能希望将它们悬浮在酒吧上方,例如:
barchart.js
...
svg.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function(d) {return d})
.attr("x", function(d, i) {return (i * 60) + 36})
.attr("y", function(d, i) {return 390 - (d * 10)});
或者,您可以通过根据Y轴修改它们的位置,让数字浮在矩形本身上。我们还需要使这个更具可读性,让我们补充一点,我们可以从我们的访问类
style.css
文件。
barchart.js
...
svg.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function(d) {return d})
.attr("class", "text")
.attr("x", function(d, i) {return (i * 60) + 36})
.attr("y", function(d, i) {return 415 - (d * 10)});
在我们
style.css
文件,我们就会使文本白色和无衬线,通过添加下列行到我们的文件的底部。
style.css
...
.text {
fill: white;
font-family: sans-serif
}
您可以通过定位和样式尽可能多地修改文本。例如,您可能还需要改变
font-size
的属性
style.css
文件。
完成代码和代码改进
此时,您应该在JavaScript的D3库中呈现一个功能完整的条形图。让我们看看我们所有的代码文件。
barchart.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bar Chart</title>
<!-- Reference style.css -->
<link rel = "stylesheet" type="text/css" href="style.css">
<!-- Reference minified version of D3 -->
<script type="text/javascript" src="d3.min.js"></script>
</head>
<body>
<script type="text/javascript" src="barchart.js"></script>
</body>
</html>
style.css
html, body {
margin: 0;
height: 100%
}
/*Rectangle bar class styling*/
.bar {
fill: #0080FF
}
.bar:hover {
fill: #003366
}
/*Text class styling*/
.text {
fill: white;
font-family: sans-serif
}
barchart.js
// Create data array of values to visualize
var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];
// Create variable for the SVG
var svg = d3.select("body").append("svg")
.attr("height","100%")
.attr("width","100%");
// Select, append to SVG, and add attributes to rectangles for bar chart
svg.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.attr("class", "bar")
.attr("height", function(d, i) {return (d * 10)})
.attr("width","40")
.attr("x", function(d, i) {return (i * 60) + 25})
.attr("y", function(d, i) {return 400 - (d * 10)});
// Select, append to SVG, and add attributes to text
svg.selectAll("text")
.data(dataArray)
.enter().append("text")
.text(function(d) {return d})
.attr("class", "text")
.attr("x", function(d, i) {return (i * 60) + 36})
.attr("y", function(d, i) {return 415 - (d * 10)})
这个代码是完全工作,但有很多,你可以做,以改善代码。例如,您可以利用SVG组元素将SVG元素组合在一起,从而允许您在较少的代码行中修改文本和矩形。 您还可以以不同的方式访问数据。我们使用一个数组来保存我们的数据,但是您可能想要可视化已经访问的数据,并且它可能比在数组中工作良好的数据多得多。 D3将允许您使用几种不同的数据文件类型:
- HTML
- JSON
- 纯文本
- CSV(逗号分隔值)
- TSV(制表符分隔值)
- XML
d3.json("myData.json", function(json) {
// code for D3 charts in here
}
您还可以将D3库与您可能已经从vanilla JavaScript了解的其他交互功能组合。