D3.js基础教程
Posted 节省钱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3.js基础教程相关的知识,希望对你有一定的参考价值。
D3: Data-Driven Documents
D3 (或D3.js)是一个javascript库,用于使用Web标准可视化数据。 D3帮助您使用SVG,Canvas和html使数据栩栩如生。 D3将强大的可视化和交互技术与数据驱动的DOM操作方法相结合,为您提供现代浏览器的全部功能,并为您的数据设计正确的可视界面提供了自由。
官方资源
安装D3
- npm安装
安装命令npm install d3
;
导入D3到ES2015应用中,或者导入D3中一个模块使用,范例如下:
import scaleLinear from "d3-scale";
导入D3所有模块:
import * as d3 from "d3";
在Node环境中使用:
var d3 = require("d3");
自定义导入D3模块组合:
var d3 = Object.assign(, require("d3-format"), require("d3-geo"), require("d3-geo-projection"));
- 直接下载D3包
请下载最新版本,发行的 release包支持anonymous AMD, CommonJS, and vanilla环境。你也可以直接从d3js.org, CDNJS, or unpkg上下载,例如:
<script src="https://d3js.org/d3.v5.js"></script>
引用压缩版本:
<script src="https://d3js.org/d3.v5.min.js"></script>
也可以直接引用其中的一个微库,例如: d3-selection:
<script src="https://d3js.org/d3-selection.v1.js"></script>
D3的优点
前端可视化库中,Hightcharts(商业付费)、Echarts、Charts可以看作一类,能够非常简单的制作图表,但是给予开发者控制和设计的空间少,封装层次太高,会失去部分自由,太低又会使程序太长,D3取得了相对完美的平衡:
1)D3相对比较底层,代码却足够简洁;
2)D3更像数学库,为绘图提供了支持;
3)封装了很多操作,又给予了足够的自由;
如何使用D3来绘图
0、D3的学习方法
D3是一个JS库,api非常多,也很完善,尤其是,出版物都非常完善,示例很多,只需要看相关示例,会查API文档即可。下面拿几个D3基本的使用来介绍下D3的运用。
1、选择元素和绑定数据
如何选择元素
在 D3 中,用于选择元素的函数有两个:
- d3.select():是选择所有指定元素的第一个
- d3.selectAll():是选择指定元素的全部
这两个函数返回的结果称为选择集。
例如,选择集的常见用法如下:
var body = d3.select("body"); //选择文档中的body元素
var svg = body.select("svg"); //选择body中的svg元素
var p = body.selectAll("p"); //选择body中所有的p元素
var p1 = body.select("p"); //选择body中第一个p元素
var rects = svg.selectAll("rect"); //选择svg中所有的rect元素
假设在 body 中有三个段落元素:
<p>Apple</p>
<p>Pear</p>
<p>Banana</p>
现在,要分别完成以下四种选择元素的任务。
选择第一个 p 元素
使用 select ,参数传入 p 即可,如此返回的是第一个 p 元素。
var body = d3.select("body");
var p1 = body.select("p");
p1.style("color","red"); // 将第一p元素内容置为红色
选择所有 p 元素
使用 selectAll 选择 body 中所有的 p 元素。
var body = d3.select("body");
var p = body.selectAll("p");
p.style("color", "red");
根据id选择元素
使用 select 选择元素,注意参数中 id 名称前要加 # 号。该方法可用于选择任何位置的元素,示例如下:
<p>Apple</p>
<p id="pear-id">Pear</p>
<p>Banana</p>
<script>
var body = d3.select("body");
var p2 = body.select("#pear-id");
p2.style("color", "red");
</script>
选择后两个 p 元素
给后两个元素添加 class,
<p class="myclass">Pear</p>
<p class="myclass">Banana</p>
由于需要选择多个元素,要用 selectAll。注意参数,class 名称前要加一个点。
var p = body.selectAll(".myclass");
p.style("color","red");
关于 select 和 selectAll 的参数,其实是符合 CSS 选择器的条件的,即用“井号(#)”表示 id,用“点(.)”表示 class。
此外,对于已经绑定了数据的选择集,还有一种选择元素的方法,那就是灵活运用 function(d, i)。我们已经知道参数 i 是代表索引号的,于是便可以用条件判定语句来指定执行的元素。
如何绑定数据
D3 中是通过以下两个函数来绑定数据的:
- datum():绑定一个数据到选择集上
- data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定
相对而言,data() 比较常用。
假设现在有三个段落元素如下:
<p>Apple</p>
<p>Pear</p>
<p>Banana</p>
datum()
作用是绑定一个数据到选择集上。
假设有一字符串 World,要将此字符串分别与三个段落元素绑定,代码如下:
var str = "World";
var body = d3.select("body");
var p = body.selectAll("p");
p.datum(str);
p.text(function(d, i)
return "第 "+ i + " 个元素绑定的数据是 " + d;
);
绑定数据后,使用此数据来修改三个段落元素的内容,其结果如下:
第 0 个元素绑定的数据是 World
第 1 个元素绑定的数据是 World
第 2 个元素绑定的数据是 World
在上面的代码中,用到了一个无名函数 function(d, i)。当选择集需要使用被绑定的数据时,常需要这么使用。其包含两个参数,其中:
- d 代表数据,也就是与某元素绑定的数据。
- i 代表索引,代表数据的索引号,从 0 开始。
例如,上述例子中:第 0 个元素 apple 绑定的数据是 World。
data()
有一个数组,接下来要分别将数组的各元素绑定到三个段落元素上。
var dataset = ["I like dog","I like cat","I like snake"];
绑定之后,其对应关系的要求为:
- Apple 与 I like dog 绑定
- Pear 与 I like cat 绑定
- Banana 与 I like snake 绑定
调用 data() 绑定数据,并替换三个段落元素的字符串为被绑定的字符串,代码如下:
var body = d3.select("body");
var p = body.selectAll("p");
p.data(dataset)
.text(function(d, i)
return d;
);
这段代码也用到了一个无名函数 function(d, i),其对应的情况如下:
- 当 i == 0 时, d 为 I like dog。
- 当 i == 1 时, d 为 I like cat。
- 当 i == 2 时, d 为 I like snake。
此时,三个段落元素与数组 dataset 的三个字符串是一一对应的,因此,在函数 function(d, i) 直接 return d 即可。
结果自然是三个段落的文字分别变成了数组的三个字符串。
I like dog
I like cat
I like snake
2、插入、删除元素
插入元素
插入元素涉及的函数有两个:
- append():在选择集末尾插入元素
- insert():在选择集前面插入元素
假设有三个段落元素,与上文相同。
append()
body.append("p")
.text("append p element");
在 body 的末尾添加一个 p 元素,结果为:
Apple
Pear
Banana
append p element
insert()
在 body 中 id 为 myid 的元素前添加一个段落元素。
body.insert("p","#pear-id")
.text("insert p element");
已经指定了 Pear 段落的 id 为 myid,因此结果如下。
Apple
insert p element
Pear
Banana
删除元素
删除一个元素时,对于选择的元素,使用 remove 即可,例如:
var p = body.select("#pear-id");
p.remove();
如此即可删除指定 id 的段落元素。
3、做一个简单的图表
柱形图是一种最简单的可视化图标,主要有矩形、文字标签、坐标轴组成。本文为简单起见,只绘制矩形的部分,用以讲解如何使用 D3 在 SVG 画布中绘图。
画布是什么
前几章的处理对象都是 HTML 的文字,没有涉及图形的制作。
要绘图,首要需要的是一块绘图的“画布”。
HTML 5 提供两种强有力的“画布”:SVG 和 Canvas。
SVG 是什么
SVG,指可缩放矢量图形(Scalable Vector Graphics),是用于描述二维矢量图形的一种图形格式,是由万维网联盟制定的开放标准。 SVG 使用 XML 格式来定义图形,除了 IE8 之前的版本外,绝大部分浏览器都支持 SVG,可将 SVG 文本直接嵌入 HTML 中显示。
SVG 有如下特点:
- SVG 绘制的是矢量图,因此对图像进行放大不会失真。
- 基于 XML,可以为每个元素添加 JavaScript 事件处理器。
- 每个图形均视为对象,更改对象的属性,图形也会改变。
- 不适合游戏应用。
Canvas 是什么
Canvas 是通过 JavaScript 来绘制 2D 图形,是 HTML 5 中新增的元素。
Canvas 有如下特点:
- 绘制的是位图,图像放大后会失真。
- 不支持事件处理器。
- 能够以 .png 或 .jpg 格式保存图像
- 适合游戏应用(是逐像素进行渲染的)
添加画布
D3 虽然没有明文规定一定要在 SVG 中绘图,但是 D3 提供了众多的 SVG 图形的生成器,它们都是只支持 SVG 的。因此,建议使用 SVG 画布。
使用 D3 在 body 元素中添加 svg 的代码如下:
var width = 300; //画布的宽度
var height = 300; //画布的高度
var svg = d3.select("body") //选择文档中的body元素
.append("svg") //添加一个svg元素
.attr("width", width) //设定宽度
.attr("height", height); //设定高度
有了画布,接下来就可以在画布上作图了。
绘制矩形
本文绘制一个横向的柱形图。只绘制矩形,不绘制文字和坐标轴。
在 SVG 中,矩形的元素标签是 rect。例如:
<svg>
<rect></rect>
<rect></rect>
</svg>
上面的 rect 里没有矩形的属性。矩形的属性,常用的有四个:
- x:矩形左上角的 x 坐标
- y:矩形左上角的 y 坐标
- width:矩形的宽度
- height:矩形的高度
要注意,在 SVG 中,x 轴的正方向是水平向右,y 轴的正方向是垂直向下的。
现在给出一组数据,要对此进行可视化。数据如下:
var dataset = [ 250 , 210 , 170 , 130 , 90 ]; //数据(表示矩形的宽度)
为简单起见,我们直接用数值的大小来表示矩形的像素宽度(后面会说到这不是一种好方法)。然后,添加以下代码。
var rectHeight = 25; //每个矩形所占的像素高度(包括空白)
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x",20)
.attr("y",function(d,i)
return i * rectHeight;
)
.attr("width",function(d)
return d;
)
.attr("height",rectHeight-2)
.attr("fill","steelblue");
这段代码添加了与 dataset 数组的长度相同数量的矩形,所使用的语句是:
svg.selectAll("rect") //选择svg内所有的矩形
.data(dataset) //绑定数组
.enter() //指定选择集的enter部分
.append("rect") //添加足够数量的矩形元素
这段代码以后会常常出现在 D3 的代码中,请务必牢记。目前不深入讨论它的作用机制是怎样的,只需要读者牢记,当:有数据,而没有足够图形元素的时候,使用此方法可以添加足够的元素。
添加了元素之后,就需要分别给各元素的属性赋值。在这里用到了 function(d, i),前面已经讲过,d 代表与当前元素绑定的数据,i 代表索引号。给属性赋值的时候,是需要用到被绑定的数据,以及索引号的。
最后一行的:
.attr("fill","steelblue");
是给矩形元素设置颜色。一般来说,最好写成外置 CSS 的形式,方便归类和修改。这里为了便于初学者理解,将样式直接写到元素里。
结果图如下所示:
4、比例尺的使用
比例尺是 D3 中很重要的一个概念,上一章里曾经提到过直接用数值的大小来代表像素不是一种好方法,本章正是要解决此问题。
为什么需要比例尺
上一章制作了一个柱形图,当时有一个数组:
var dataset = [ 250 , 210 , 170 , 130 , 90 ];
绘图时,直接使用 250 给矩形的宽度赋值,即矩形的宽度就是 250 个像素。
此方式非常具有局限性,如果数值过大或过小,例如:
var dataset_1 = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
var dataset_2 = [ 2500, 2100, 1700, 1300, 900 ];
对以上两个数组,绝不可能用 2.5 个像素来代表矩形的宽度,那样根本看不见;也不可能用 2500 个像素来代表矩形的宽度,因为画布没有那么长。
于是,我们需要一种计算关系,能够:
将某一区域的值映射到另一区域,其大小关系不变。
这就是比例尺(Scale)。
有哪些比例尺
比例尺,很像数学中的函数。例如,对于一个一元二次函数,有 x 和 y 两个未知数,当 x 的值确定时,y 的值也就确定了。
在数学中,x 的范围被称为定义域,y 的范围被称为值域。
D3 中的比例尺,也有定义域和值域,分别被称为 domain 和 range。开发者需要指定 domain 和 range 的范围,如此即可得到一个计算关系。
D3 提供了多种比例尺,下面介绍最常用的两种。
线性比例尺
线性比例尺,能将一个连续的区间,映射到另一区间。要解决柱形图宽度的问题,就需要线性比例尺。
假设有以下数组:
var dataset = [1.2, 2.3, 0.9, 1.5, 3.3];
现有要求如下:
将 dataset 中最小的值,映射成 0;将最大的值,映射成 300。
代码如下:
var min = d3.min(dataset); //得到最小值
var max = d3.max(dataset); //得到最大值
var scaleLinear = d3.scaleLinear()
.domain([min, max])
.range([0, 300]);
scaleLinear(0.9); //返回 0
scaleLinear(2.3); //返回 175
scaleLinear(3.3); //返回 300
其中,d3.scaleLinear() 返回一个线性比例尺。domain() 和 range() 分别设定比例尺的定义域和值域。在这里还用到了两个函数,它们经常与比例尺一起出现:
- d3.max()
- d3.min()
这两个函数能够求数组的最大值和最小值,是 D3 提供的。按照以上代码,
比例尺的定义域 domain 为:[0.9, 3.3]
比例尺的值域 range 为:[0, 300]
因此,当输入 0.9 时,返回 0;当输入 3.3 时,返回 300。当输入 2.3 时呢?返回 175,这是按照线性函数的规则计算的。
有一点请大家记住:
d3.scaleLinear() 的返回值,是可以当做函数来使用的。因此,才有这样的用法:scaleLinear(0.9)。
序数比例尺
有时候,定义域和值域不一定是连续的。例如,有两个数组:
var index = [0, 1, 2, 3, 4];
var color = ["red", "blue", "green", "yellow", "black"];
我们希望 0 对应颜色 red,1 对应 blue,依次类推。
但是,这些值都是离散的,线性比例尺不适合,需要用到序数比例尺。
var scaleOrdinal = d3.scaleOrdinal()
.domain(index)
.range(color);
scaleOrdinal (0); //返回 red
scaleOrdinal (2); //返回 green
scaleOrdinal (4); //返回 black
用法与线性比例尺是类似的。
给柱形图添加比例尺
在上一章的基础上,修改一下数组,再定义一个线性比例尺。
var dataset = [ 2.5 , 2.1 , 1.7 , 1.3 , 0.9 ];
var scaleLinear = d3.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 250]);
其后,按照上一章的方法添加矩形,在给矩形设置宽度的时候,应用比例尺。
var rectHeight = 25; //每个矩形所占的像素高度(包括空白)
svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x",20)
.attr("y",function(d,i)
return i * rectHeight;
)
.attr("width",function(d)
return scaleLinear(d); //在这里用比例尺
)
.attr("height",rectHeight-2)
.attr("fill","steelblue");
如此一来,所有的数值,都按照同一个线性比例尺的关系来计算宽度,因此数值之间的大小关系不变。
5、坐标轴
坐标轴,是可视化图表中经常出现的一种图形,由一些列线段和刻度组成。坐标轴在 SVG 中是没有现成的图形元素的,需要用其他的元素组合构成。D3 提供了坐标轴的组件,如此在 SVG 画布中绘制坐标轴变得像添加一个普通元素一样简单。
坐标轴由什么构成
在 SVG 画布的预定义元素里,有六种基本图形:
- 矩形
- 圆形
- 椭圆
- 线段
- 折线
- 多边形
另外,还有一种比较特殊,也是功能最强的元素:
- 路径
画布中的所有图形,都是由以上七种元素组成。
显然,这里面没有坐标轴 这种元素。如果有的话,我们可以采用类似以下的方式定义:
<axis x1="" x2="" ...></axis>
很可惜,没有这种元素。但是,这种设计是合理的:不可能为每一种图形都配备一个单独的元素,那样 SVG 就会过于庞大。
因此,我们需要用其他元素来组合成坐标轴,最终使其变为类似以下的形式:
<g>
<!-- 第一个刻度 -->
<g>
<line></line> <!-- 第一个刻度的直线 -->
<text></text> <!-- 第一个刻度的文字 -->
</g>
<!-- 第二个刻度 -->
<g>
<line></line> <!-- 第二个刻度的直线 -->
<text></text> <!-- 第二个刻度的文字 -->
</g>
...
<!-- 坐标轴的轴线 -->
<path></path>
</g>
<g>
分组元素 ,是 SVG 画布中的元素,意思是 group。此元素是将其他元素进行组合的容器,在这里是用于将坐标轴的其他元素分组存放。
如果需要手动添加这些元素就太麻烦了,为此,D3 提供了轴生成器:d3.axisTop()、d3.axisRight()、
d3.axisBottom()、d3.axisLeft()。它为我们完成了以上工作。
定义坐标轴
上一章提到了比例尺的概念,要生成坐标轴,需要用到比例尺,它们二者经常是一起使用的。下面,在上一章的数据和比例尺的基础上,添加一个坐标轴的组件。
坐标轴是有朝向的,在这里我们以向下朝向、水平方向的坐标轴为例,其他朝向的(比如向左朝向的、垂直的坐标轴)类似。
var dataset = [2.5, 2.1, 1.7, 1.3, 0.9]; //数据
//定义线性比例尺
var xScale = d3
.scaleLinear()
.domain([0, d3.max(dataset)])
.range([0, 250]);
SQL基础教程的介绍
参考技术A
SQL基础教程:由费希利 (美)著,冯宇晖,贾文峰 翻译,人民邮电出版社出版的一部介绍如何使用最常用的SQL语言维护和查询数据库信息的基础教材。介绍如何使用最常用的SQL语言维护和查询数据库信息介绍如何使用最常用的SQL语言维护和查询数据库信息
以上是关于D3.js基础教程的主要内容,如果未能解决你的问题,请参考以下文章