D3.js

D3.js

为什么学习D3

D3.js和threejs的应用场景完全不一样。threejs主要应用与基于webGL的3D场景,而D3.js确主要应用与2D场景。

它们一起形成了一种互补关系。

简而言之D3JS就是一个数据可视化的库。

那什么是数据可视化呢?

给出一组数据 [10,80,40,100,30,20,50]

image-20190801162422591.png

类似的库 eharts

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器,ECharts 提供了常规的折线图、柱状图、散点图、饼图 等等。

和eharts的区别

eharts是封装好的各种的图表可以直接拿来使用,类似于图表模具,直接拿来使用即可。

D3.js就像画笔一样,一切都由你自由发挥。

基本介绍

D3.jsData-Driven Documents)是一个使用动态图形进行数据可视化的JavaScript程序库。与W3C标准兼容,并且利用广泛实现的SVG、JavaScript和CSS标准,改良自早期的Protovis程序库。与其他的程序库相比,D3对视图结果有很大的可控性。D3是2011年面世的,同年的8月发布了2.0.0版。到2018年4月,D3已被更新到了5.5.0版[1]。

发展历史

在D3.js开发之前已经有出现过许多尝试做数据可视化的包,例如Prefuse,Flare和Protovis程序库,他们都可以视为D3.js的前身。然而Prefuse和Flare皆有缺点,皆不能只透过浏览器完成渲染,皆须要透过额外插件来完成。

例如2005年发布的Prefuse是一个数据可视化程序库,但是它需要透过网页的Java插件才能于浏览器中呈现;而Flare是2007年发布的另一个数据可视化工具包,由于其是使用ActionScript编程语言开发,因此也需要额外插件,即Flash插件才能完成渲染。

2009年,史丹佛大学的史丹佛可视化团队(Stanford Visualization Group)的杰佛瑞·赫尔、迈克·保斯托和瓦迪姆·欧格菲兹齐利用开发Prefuse和Flare的经验开始用Javscript开发了可从给定数据产生SVG图形的Protovis程序库。而Protovis程序库在业界和学界皆有一定的知名度[3]。

2011年,史丹佛可视化团队停止开发Protovis,并开始开发新的数据可视化程序库,借由之前开发Protovis的经验,开发出了D3.js程序库,在注重于Web标准的同时提供了更丰富的平台也有了更好的性能[4]。

技术原理

D3.js透过预先创建好迁入于网页中的JavaScript函数来选择网页元素、创建SVG元素、调整CSS来呈现数据,并且也可以设置动画、动态改变对象状态或加入工具提示来完成用户交互功能。使用简单的D3.js函数就能够将大型的数据数据结构与SVG对象进行绑定,并且能生成格式化文本和各种图表。

基本使用

hello world

先尝试用 D3 写第一个 HelloWorld 程序。学编程入门的第一个程序都是在屏幕上输出 HelloWorld,本课稍微有些不同,不是单纯的输出。

在 HTML 中输出 HelloWorld 是怎样的呢,先看下面的代码。

 
   
         
        HelloWorld 
   
     
        

Hello World 1

Hello World 2

用 JavaScript 来更改 HelloWorld

对于上面输出的内容,如果想用 JavaScript 来更改这两行文字,怎么办呢?我们会添加代码变为:

 
   
         
        HelloWorld 
   
     
    

Hello World 1

Hello World 2

用 D3 来更改 HelloWorld

如果使用 D3.js 来修改这两行呢?只需添加一行代码即可。注意不要忘了引用 D3.js 源文件。

引入


 
   
         
        HelloWorld 
   
     
        

Hello World 1

Hello World 2

接下来改变字体的颜色和大小,稍微修改上述代码:

//选择中所有的

,其文本内容为 www.ourd3js.com,选择集保存在变量 p 中 var p = d3.select("body") .selectAll("p") .text("www.ourd3js.com"); //修改段落的颜色和字体大小 p.style("color","red") .style("font-size","72px");

选择元素

在 D3 中,用于选择元素的函数有两个:

  • d3.select():是选择所有指定元素的第一个
  • d3.selectAll():是选择指定元素的全部

这两个函数返回的结果称为选择集。

例如,选择集的常见用法如下。

var body = d3.select("body"); //选择文档中的body元素
var p1 = body.select("p");      //选择body中的第一个p元素
var p = body.selectAll("p");    //选择body中的所有p元素
var svg = body.select("svg");   //选择body中的svg元素
var rects = svg.selectAll("rect");  //选择svg中所有的svg元素

绑定数据

选择集和绑定数据通常是一起使用的。

D3 有一个很独特的功能:能将数据绑定到 DOM 上,也就是绑定到文档上。这么说可能不好理解,例如网页中有段落元素 p 和一个整数 5,于是可以将整数 5 与 p 绑定到一起。绑定之后,当需要依靠这个数据才操作元素的时候,会很方便。

D3 中是通过以下两个函数来绑定数据的:

  • datum():绑定一个数据到选择集上
  • data():绑定一个数组到选择集上,数组的各项值分别与选择集的各元素绑定

相对而言,data() 比较常用。

假设现在有三个段落元素如下。

Apple

Pear

Banana

datum()

假设有一字符串 China,要将此字符串分别与三个段落元素绑定,代码如下:

var str = "China";

var body = d3.select("body");
var p = body.selectAll("p");

p.datum(str);

p.text(function(d, i){
    return "第 "+ i + " 个元素绑定的数据是 " + d;
});

绑定数据后,使用此数据来修改三个段落元素的内容,其结果如下:

第 0 个元素绑定的数据是 China

第 1 个元素绑定的数据是 China

第 2 个元素绑定的数据是 China

在上面的代码中,用到了一个无名函数 function(d, i)。当选择集需要使用被绑定的数据时,常需要这么使用。其包含两个参数,其中:

  • d 代表数据,也就是与某元素绑定的数据。
  • i 代表索引,代表数据的索引号,从 0 开始。

例如,上述例子中:第 0 个元素 apple 绑定的数据是 China。

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

选择、插入、删除元素

已经讲解了 select 和 selectAll,以及选择集的概念。本节具体讲解这两个函数的用法。

假设在 body 中有三个段落元素:

Apple

Pear

Banana

现在,要分别完成以下四种选择元素的任务。

选择第一个 p 元素
t("p");
p1.style("color","red");
选择三个 p 元素
var p = body.selectAll("p");
p.style("color","red");
选择第二个 p 元素

有不少方法,一种比较简单的是给第二个元素添加一个 id 号。

Pear

然后,使用 select 选择元素,注意参数中 id 名称前要加 # 号。

var p2 = body.select("#myid");
p2.style("color","red");
选择后两个 p 元素

给后两个元素添加 class,

Pear

Banana

由于需要选择多个元素,要用 selectAll。注意参数,class 名称前要加一个点。

var p = body.selectAll(".myclass");
p.style("color","red");

插入元素

插入元素涉及的函数有两个:

  • 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","#myid")
  .text("insert p element");

已经指定了 Pear 段落的 id 为 myid,因此结果如下。

Apple
insert p element
Pear
Banana

删除元素

删除一个元素时,对于选择的元素,使用 remove 即可,例如:

var p = body.select("#myid");
p.remove();

SVG 基本使用

SVG 意为可缩放矢量图形(Scalable Vector Graphics)。

SVG 使用 XML 格式定义图像。

什么是svg

  • SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
  • SVG 用来定义用于网络的基于矢量的图形
  • SVG 使用 XML 格式定义图形
  • SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
  • SVG 是万维网联盟的标准
  • SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体

hello-world



 

My first SVG

简单的 SVG 实例

一个简单的SVG图形例子:

这里是SVG文件(SVG文件的保存与SVG扩展):





  

第一行包含了 XML 声明。请注意 standalone 属性!该属性规定此 SVG 文件是否是"独立的",或含有对外部文件的引用。

standalone="no" 意味着 SVG 文档会引用一个外部文件 - 在这里,是 DTD 文件。

第二和第三行引用了这个外部的 SVG DTD。该 DTD 位于 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"。该 DTD 位于 W3C,含有所有允许的 SVG 元素。

SVG 代码以 元素开始,包括开启标签和关闭标签 。这是根元素。width 和 height 属性可设置此 SVG 文档的宽度和高度。version 属性可定义所使用的 SVG 版本,xmlns 属性可定义 SVG 命名空间。

SVG 的 用来创建一个圆。cx 和 cy 属性定义圆中心的 x 和 y 坐标。如果忽略这两个属性,那么圆点会被设置为 (0, 0)。r 属性定义圆的半径。

stroke 和 stroke-width 属性控制如何显示形状的轮廓。我们把圆的轮廓设置为 2px 宽,黑边框。

fill 属性设置形状内的颜色。我们把填充颜色设置为红色。

关闭标签的作用是关闭 SVG 元素和文档本身。

SVG 在 HTML 页面

SVG 文件可通过以下标签嵌入 HTML 文档: 或者