使用JavaScript和D3.js实现数据可视化
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~
介绍
D3.js是一个JavaScript库。它的全称是Data-Driven Documents(数据驱动文档),并且它被称为一个互动和动态的数据可视化库网络。2011年2月首次发布,在撰写本文时,最新的稳定版本是4.4版本,并且不断更新。D3利用可缩放矢量图形或SVG格式,允许您渲染可放大或缩小的形状,线条和填充,而不会降低质量。本教程将指导您使用JavaScript D3库创建条形图。
准备
为了充分利用本教程,您应该熟悉JavaScript编程语言以及CSS和HTML的知识。
尽管你将使用CSS来进行D3的样式设定,但值得注意的是,很多在HTML上使用的标准的CSS在SVG的使用方式会不一样-也就是说,你会用stroke
,而不是border
,使用fill
而不是color
。
我们将使用文本编辑器和Web浏览器。出于测试目的,建议使用工具来检查和调试JavaScript、HTML和CSS,例如Firefox Developer Tools或Chrome DevTools。
第一步 - 创建文件和参考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文件,请在HTML文件中引用d3.js。
由于D3是模块化的,您可以通过仅拉入您将使用的模块来减小文件大小。
下载D3后,让我们设置CSS和HTML文件。您可以选择要在此文件上使用的文本编辑器,例如nano
。我们将从CSS文件style.css
开始,以便我们可以立即从HTML文件链接到它。
nano style.css
我们将从一个标准的CSS声明开始,将页面设置为100%高度且无边距。
html, body {
margin: 0;
height: 100%;
}
您现在可以保存并关闭CSS文件。
接下来我们将创建我们的JavaScript文件,我们将其命名barchart.js
,我们将为此示例制作条形图。使用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>
保存并关闭。
第二步 - 在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
到我们的Web浏览器中,我们应该能够使用我们的开发人员工具检查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时看到一个占据整个屏幕的矩形。
第三步 - 添加矩形
随着我们的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,您必须首先选择您要处理的元素。
我们配合这个矩形用.data(dataArray)
阵列存储在dataArray
的数据。
要为选择中的每个项目(对应于数据数组)实际添加一个矩形,我们还将添加.enter().append("rect");
以附加矩形。在此示例中,将有9个矩形对应于阵列中的9个数字。
如果您现在重新加载页面,您将看不到任何矩形,但如果您检查DOM,您将看到在那里定义的9个矩形。
我们还没有为矩形设置属性以使它们可见,所以现在添加它们。
设置形状的属性
我们可以通过使用.attr()
,与为SVG定义属性相同的方式向形状添加属性。D3中的每个形状将具有不同的属性,具体取决于它们的定义和绘制方式。
我们的矩形将包含4个属性:
("height", "height_in_pixels")
对应矩形的高度("width", "width_in_pixels")
对应矩形的宽度("x", "distance_in_pixels")
代表与浏览器窗口左侧的距离("y", "distance_in_pixels")
代表与浏览器窗口顶部的距离
因此,如果我们想要长度为250像素,宽40像素,距离浏览器左侧25像素,距离顶部50像素的矩形,我们将编写如下代码:
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个像素。现在我们的完整代码应如下所示:
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。我们将从400减去返回的高度(d * 10)
,以便我们的行现在看起来像这样:
.attr("y", function(d, i) {return 400 - (d * 10)});
我们来看看我们的完整JavaScript代码:
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)});
此时,当我们重新加载页面时,我们会看到一个条形图,我们可以从下到上阅读:
现在,我们可以设计图表的样式。
第四步 - 使用D3设置样式
我们将使用我们的CSS文件来设计我们的D3形状,但首先,为了使这项工作更容易,我们将在JavaScript文件中为我们的矩形提供一个类名,我们可以在CSS文件中引用它。
添加类就像使用点表示法添加任何其他属性一样。我们称之为班级bar,因为它是一个条形图,但只要所有引用都引用相同的名称,我们就可以调用它。我们的语法如下所示:
.attr("class", "bar")
我们可以在任何地方添加此属性。将它保留为第一个属性可以使我们的CSS文件更容易引用。
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
文件,目前看起来像这样:
html, body {
margin: 0;
height: 100%
}
我们可以通过更改填充颜色来开始修改矩形,引用我们刚刚创建的bar类别:
style.css
html, body {
margin: 0;
height: 100%
}
.bar {
fill: blue
}
在这里,我们将矩形设为蓝色,我们也可以为它们分配一个十六进制颜色代码,如下所示:
.bar {
fill: #0080FF
}
此时,我们的矩形看起来像这样:
我们可以为矩形提供其他值,例如用stroke以特定颜色勾勒出矩形,以及stroke-width
:
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
个像素,并确保将分号向下移动。
...
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文件中操作,并将其限制为填充颜色和悬停填充:
html, body {
margin: 0;
height: 100%
}
.bar {
fill: #0080FF
}
.bar:hover {
fill: #003366
}
在网络上处理颜色时,重要的是要牢记您的观众并努力包含尽可能普遍可访问的颜色。
第五步 - 添加标签
我们的最后一步是以标签的形式在我们的图表中添加一些可量化的标记。这些标签将对应于我们阵列中的数字。
添加文本类似于添加上面我们所做的矩形形状。我们需要选择文本,然后将其附加到SVG。我们还将它与我们创建的dataArray
联系起来。我们将使用"text"
,而不是"rect"
,但一般格式和我们在上面添加矩形所做的类似。我们将这些行添加到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.我们将使用与我们相同的函数公式修改位置通过添加属性用于矩形。
...
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而不是图像,所以您可以选择文本,就像在页面上看到的任何其他文本一样。
从这里开始,您可以通过修改函数公式来重新定位数字。您可能希望将它们悬浮在条形图上方,例如:
...
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
文件中访问的类。
...
.text {
fill: white;
font-family: sans-serif
}
您可以通过定位和样式尽可能多地修改文本。例如,您可能还想更改style.css文件中的font-size属性。
完成的代码和代码改进
此时,您应该拥有一个在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
例如,您可以在网站的目录中拥有一个JSON文件,并将其连接到JavaScript文件
d3.json("myData.json", function(json) {
// code for D3 charts in here
});
您还可以将D3库与您可能已经从vanilla JavaScript中了解的其他交互式功能相结合。
结论
本教程通过在JavaScriptD3库中创建条形图。您可以通过访问GitHub上的D3 API来了解有关d3.js的更多信息。更多前端教程请前往腾讯云+社区学习更多知识。
参考文献:《Getting Started with Data Visualization Using JavaScript and the D3 Library 》
问答
相关阅读
此文已由作者授权腾讯云+社区发布,原文链接:https://cloud.tencent.com/developer/article/1181781?fromSource=waitui
欢迎大家前往腾讯云+社区或关注云加社区微信公众号(QcloudCommunity),第一时间获取更多海量技术实践干货哦~
海量技术实践经验,尽在云加社区! https://cloud.tencent.com/developer?fromSource=waitui
使用JavaScript和D3.js实现数据可视化的更多相关文章
- 交互式数据可视化-D3.js(四)形状生成器
使用JavaScript和D3.js实现数据可视化 形状生成器 线段生成器 var linePath = d3.line() - 使用默认的设置构造一个 line 生成器. linePath.x() ...
- d3.js:数据可视化利器之快速入门
hello,data! 在进入d3.js之前,我们先用一个小例子回顾一下将数据可视化的基本流程. 任务 用横向柱状图来直观显示以下数据: var data = [10,15,23,78,57,29,3 ...
- 利用d3.js绘制雷达图
利用d3,js将数据可视化,能够做到数据与代码的分离.方便以后改动数据. 这次利用d3.js绘制了一个五维的雷达图.即将多个对象的五种属性在一张图上对照. 数据写入data.csv.数据类型写入typ ...
- 【数据科学】Python数据可视化概述
注:很早之前就打算专门写一篇与Python数据可视化相关的博客,对一些基本概念和常用技巧做一个小结.今天终于有时间来完成这个计划了! 0. Python中常用的可视化工具 Python在数据科学中的地 ...
- D3.js学习笔记(六)——SVG基础图形和D3.js
目标 在这一章,我们将会重温SVG图形,学习如何使用D3.js来创建这些图形. 这里会包括前面例子中的SVG基础图形以及如何使用D3.js设置图形的属性. 使用D3.js画一个SVG 的 圆 circ ...
- Python数据可视化matplotlib和seaborn
Python在数据科学中的地位,不仅仅是因为numpy, scipy, pandas, scikit-learn这些高效易用.接口统一的科学计算包,其强大的数据可视化工具也是重要组成部分.在Pytho ...
- D3.js 之 d3-shap 简介(转)
[转] D3.js 之 d3-shap 简介 译者注 原文: 来自 D3.js 作者 Mike Bostock 的 Introducing d3-shape 译者: ssthouse 联系译者: 邮箱 ...
- 用 D3.js 画一个手机专利关系图, 看看苹果,三星,微软间的专利纠葛
前言 本文灵感来源于Mike Bostock 的一个 demo 页面 原 demo 基于 D3.js v3 开发, 笔者将其使用 D3.js v5 进行重写, 并改为使用 ES6 语法. 源码: gi ...
- D3.js加载csv和json数据
1.加载数据的基本命令 D3提供了方法可以对不同的数据类型进行加载,比如d3.text(), d3.xml(), d3.json(), d3.csv(), 和d3.html(). <!DOCTY ...
随机推荐
- leetCode刷题(找出数组里的两项相加等于定值)
最近被算法虐了一下,刷一下leetcode,找找存在感 如题: Given an array of integers, return indices of the two numbers such t ...
- Lua读取CSV文件到table中
创建Lua函数载入CSV文件并保存到表中的函数: function GetLines(fileName) indx = 0 myLines ={} for line in io.line(string ...
- JavaScrip对象
一.JavaScript对象概述 JavaScript 中的所有事物都是对象:字符串.数值.数组.函数...此外,JavaScript 允许自定义对象.JavaScript 提供多个内建对象,比如 S ...
- Python3 urllib.request库的基本使用
Python3 urllib.request库的基本使用 所谓网页抓取,就是把URL地址中指定的网络资源从网络流中读取出来,保存到本地. 在Python中有很多库可以用来抓取网页,我们先学习urlli ...
- Java高并发之无锁与Atomic源码分析
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...
- Maven install命令理解
每一个构建都需要唯一的坐标来标识位置,我们根据坐标位置就能够下载构建至本地仓库.那么如果我们是内部项目,自定义的构建并不公开至网络上,项目成员又想依赖他怎么办呢?想想maven找寻构建的步骤. 先找寻 ...
- java中使用hashSet的特性,判断数组是否有重复值
public static boolean cheakRepeat(int[] array){ HashSet<Integer> hashSet = new HashSet<Inte ...
- SSM-MyBatis-06:Mybatis中openSession到底做了什么
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 1.找SqlSesionFactory实现类 Ctrl+H:DefaultSqlSessionFactory: ...
- mysql事务隔离级别详解和实战
A事务做了操作 没有提交 对B事务来说 就等于没做 获取的都是之前的数据 但是 在A事务中查询的话 查到的都是操作之后的数据 没有提交的数据只有自己看得到,并没有update到数据库. 查看InnoD ...
- Linux kernel的中断子系统之(五):驱动申请中断API
返回目录:<ARM-Linux中断系统>. 总结:二重点区分了抢占式内核和非抢占式内核的区别:抢占式内核可以在内核空间进行抢占,通过对中断处理进行线程化可以提高Linux内核实时性. 三介 ...