开始学习D3.js,网上没有找到很满意的中文教程,可是发现了一个很好的英文教程,讲解的很是详细。从一个初始简单的HTML网页开始,逐步加入D3.js的应用,几乎是逐句讲解。学习的时候,就顺便翻译成中文,来和你们分享 。固然,更推荐看英文原文教程了,点击这里。javascript
简单例子html
在这个例子中,你将会使用D3.js来把数据绑定到简单网页的DOM元素(DOM element)上。java
如今开始了!下面是一个简单的HTML网页:数组
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <script type="text/javascript" src="d3.v3.min.js"></script> 5 </head> 6 <body> 7 </body> 8 </html>
打开Chrome的开发者工具进入JavaScript控制台,观察元素查阅器(inspector)。app
在JavaScript控制台上输入下面这段代码:dom
1 var theData = [1,2,3] //一个数组 2 3 var p = d3.select("body").selectAll("p") 4 .data(theData) 5 .enter() 6 .append("p") 7 .text("hello");
结果以下:工具
恭喜你!你如今已经成功使用D3.js把一些数据绑定到了DOM元素上了!学习
D3.js 的 SelectAll 方法spa
在上面那段Javascript代码中,有一个方法是:.selectAll("p").翻译
D3.js中的selectAll方法使用的是CSS3中的选择器来获取DOM元素。不一样于select方法(该方法获取的是第一个目标元素),而selectAll方法选择的是全部匹配的元素。
可是!!初识的HTML网页中并不包含<p>,也就是说,该方法返回的是一个空的选择结果(selection)。
在此以后呢,咱们又使用了.data(theData)和.enter()把数据绑定到这个空的选择结果中,这是怎么回事呢?
D3.js的data操做符(operator)
在上面那段Javascript代码中,接下来的是.data(theData)。
这个data操做符是把一个数据数组(多是数值数组、对象数组或者别的什么数组)与当前的选择结果联系(join)起来。
在本例中,并无提供key值,所以theData数组中的每个元素都被分配到当前选择结果中的一个元素上。数组中第一个元素,也就是数字1,被分配到第一个<p>元素,第二个元素2被分配到相应的第二个<p>,以此类推。
可是!!正如上面说过的,初识网页中根本没有一个<p>,那么到底怎么回事?
D3.js的Virtual Selections
与D3.js中的其余方法不一样的是,data操做符返回的是三个Virtual selection。
这三个virtual selection是enter,update以及exit。
enter选集:对全部缺失的元素以占位符placeholder替代。
update选集:包含现有的元素,并绑定到数据
剩下的元素最终都会出如今exit选集中,并被移除。
因为从下面代码获得的选集是空的:
1 d3.select("body").selectAll("p")
所以,虚拟enter选集中包含的是<p>元素的占位符。
咱们将会的后面章节继续讨论虚拟选集enter,update,exit,而如今,咱们就把焦点放在enter虚拟选集上。
若是想要了解更多虚拟选集(virtual selection)知识,这里推荐一篇经典文章:Mike Bostock 写的"Thinking with Joins"。
D3.js的enter方法
D3.js的enter方法从data操做符返回一个虚拟选集。这个方法只能做用于data操做符,由于只有data操做符返回的是三个虚拟选集。
1 var p = d3.select("body").selectAll("p") 2 .data(theData) 3 .enter()
正如前面所说,对于数组中的数据元素,若是缺乏与之对应的DOM元素,那么就会有一个占位符来顶替,而enter方法返回的就是这些占位符集合的引用(reference)。
获得这个引用以后,就能对该集合操做了。
在这里须要特别注意的是,这个引用后只能连接(chaining)append,insert以及select操做符,经过他们来操做该引用所指向的集合。
在这些操做符连接到.enter()选集,咱们就能够像处理其余选集那样,来对其内容进行更改。
D3.js的Append操做符
咱们再次来看看这段代码:
1 var p = d3.select("body").selectAll("p") 2 .data(theData) 3 .enter() 4 .append("p")
咱们把.append("p")做用于.enter()选集之上。
对上一步中所产生的每一个占位符(placeholder),都有一个P元素插入进去。
因为在咱们的数据数组中,有三个数据元素(1,2,3),可是在网页中,没有一个P元素,因此.append("p")就建立并加入了3个段落元素。
在本例中,当咱们对.enter()的选集使用了append操做符以后,返回的是一个具备3个HTML段落元素的选集。
D3.js的text操做符
若是咱们把以前那段Javascript代码作一改变,去掉text操做符:
1 var theData = [1,2,3] 2 3 var p = d3.select("body").selectAll("p") 4 .data(theData) 5 .enter() 6 .append("p");
咱们获得的结果是:
咱们注意到,与以前的那张图片相对比,这里的段落都是不包含任何文字的。
text操做符对全部被选择的元素的textContent属性进行赋值。
在本例中,.text("hello"),值是“hello”。由于咱们的选集中有3个<p>元素,所以每一个元素都被插入了“hello”。
数据到哪儿去了?
在本文的例子中,一开始就是一个Javascript的数据数组:
1 var theData = [1,2,3]
但是到最后,咱们获得了三个内容是“hello”的段落。
那么对于数字1,2,3,发生了什么?
D3.js的data操做符回顾
让咱们经过一个简单的例子,在javascript控制台中再次观察下data操做符:
1 console.log(d3.select("body"));
当咱们点击回车,而后点击向下的箭头来查看“body”的属性,你看到的应该以下:
在0:<body>这一行下面,你能够看到HTML中body元素的属性。
如今,咱们在Javascript控制台运行一下下面这句代码,咱们加入了.data()操做符。
1 console.log(d3.select("body").data([1]));
咱们的数据出如今名为_data_的属性中:
当咱们把数据分配到一个元素上时,这个数据被存储到_data_属性中。
到此,数据能够经过_data_属性被再选。这也就是咱们所说的数据绑定到Dom元素(Binding Data to Dom Elements)。
初始例子回顾
回顾咱们在页面最上方提到的那个例子,如今咱们使用console.log()来查看数据绑定到什么地方了:
1 var theData = [1,2,3] 2 3 var p = d3.select("body").selectAll("p") 4 .data(theData) 5 .enter() 6 .append("p") 7 .text("love") 8 9 console.log(p);
结果是:
从上图能够看出3个段落元素被添加。
你还会看到最后一个(第三个)段落元素的_data_属性值为3,这个值就是来自咱们的数据集theData!