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 提供两种强有力的“画布”:SVGCanvas

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基础教程的主要内容,如果未能解决你的问题,请参考以下文章

零基础自学前端 D3.js 初体验03 柱状图+排序

怎么学习d3.js

前端3D动画相关开源JS

零基础前端开发工程师视频教程全套,基础+进阶+项目实战(共120G)

在渲染 D3.js 图之前从 GET 请求中获取数据

D3.js的基础部分之数组的处理 数组的排序和求值(v3版本)