简单介绍下D3,D3.js是一个开源的js库,全名是Data-Driven Documents
,因为三个字母开头都是D,所以简称D3,主要是对DOM元素的数据驱动操作。下面看看第一部分,简单介绍下几个常用的基本概念。
1.Selections:
在D3中,可以选择DOM元素,进而对他们进行操作,例如更改样式,修改其属性,执行数据连接或插入/删除元素。
两个方法,
.select() 选择单一的DOM元素、
.selectAll()选择所有符合条件的DOM元素
![](https://img.haomeiwen.com/i13084806/ee9dab5dfe29351c.png)
2.关于绑定数据,给定一组数据和前面说到的D3 Selections,我们可以将每个数组元素附加或“连接”到Selections的每个元素。同样有两个方法:
- .datum(),绑定单一的数据到单一DOM元素上,基本不用。
- .data(),支持绑定多个数据到多个DOM元素上,经常使用。
对于.data()函数,该函数返回一个对象,对象里面包含updata selection以及enter()和exit()两个函数。 - updata selection显示的是成功绑定数据的DOM元素,就是数据和DOM元素一一对应的部分。
- .enter()函数,返回 相比较dom element多出的那部分data;
- .exit()函数,返回 相比较data多出的那部分dom element,下面会说它们两种情况的处理方式。
对于.data()函数,该函数有两个参数,第一个参数是要绑定的数据集合,第二个参数是 key函数,决定你要绑定数据的顺序。
如.data(array1,function(d){return d.key;})
至于第二个参数,什么情况下需要设置? - 设置key函数,就是规定了数组绑定DOM元素的顺序,每个数据绑定的DOM元素固定,不论数组中的数据如何变化,绑定的DOM元素都不变,让我们视觉上看起来很舒服,很有条理;
- 不设置key函数,就是默认按照数组索引号绑定DOM元素,适用于当你的数据和DOM元素的顺序相同时。当你每次对数组中的数据进行动态更新时,会重新绑定所有的DOM元素,很容易出错,达不到数据驱动DOM元素的目的。
例子:https://bl.ocks.org/BMPMS/21ca3ca9671e93b57bee831ff2e0e99d
3.关于.enter()/.exit()的处理。
前面说到了这两个函数分别返回的是什么,
-
.enter()函数,返回 相比较dom element多出的那部分data,我们使用D3的目的是为了把数据和DOM元素进行绑定,以便于对数据的可视化,那现在数据比DOM元素多,此时应该为多出来的数据创建DOM元素,让他们一一绑定。
创建DOM元素有两种方法,
(1).append(),一般都是跟随.enter().append(''),这样就为多出来的数据分别创建DOM元素,此种方法是顺序创建,默认在上一个DOM元素之后。
(2).insert(),同样是跟随.enter().insert('',''),两个参数,第一个参数是要创建的DOM元素,第二个参数是你要插入到哪个DOM元素的前面。此种方法是指定了创建之后元素的位置,其实应该叫插入比较合适。 -
.exit()函数,返回 相比较data多出的那部分dom element,很明显,既然这部分的数据已经不存在了,那之前为之分配的DOM元素也没有存在的必要了,直接把DOM元素移除。一般这么使用,.exit().remove()。
4.为什么要使用merge(),merge()可以把 update和enter部分的操作合一,更加方便数据更新。
例子:https://www.codementor.io/milesbryony/d3-js-merge-in-depth-jm1pwhurw
- d3js v3和v4中如何一次性获取和处理enter以及update selections统一处理相应逻辑?
在d3js中,我们已经很熟悉通过select.data().append().attr这种pattern来处理可视化,我们也知道data操作符调用后返回update selection并且通过update selection也可以访问exit和enter selection,这些selection加起来才是整个可视化的dom集合,在d3.v3版本中无须任何其他调用,只要你执行了update.enter().append()之后enter selection自然就merge到update selection中去了,因此我们对update selection的任何操作都会影响到整个dom集。但是在v4中,这个特性消失了,取而代之的是必须使用merge调用。但是要注意的是通过merge获取到整个dom集合后,update段的数据更新(比如在.each函数中对每个数据dataum增加一个字段,而在其他地方使用该数据)在该场景下可能存在问题。
<html>
<head>
<script src="d3.v3.min.js"></script>
</head>
<body>
<p>p1</p>
<p>p2</p>
<p>p3</p>
</body>
</html>
var update = d3.select("body").selectAll("p").data([4,5,6,7,8])
update.enter().append("p");
update.text(function(d,i){return d}) // V3下一次调用就可以对所有5个dom元素执行操作
// 而v4下则必须使用merge函数调用,比如:
var update = d3.select("body").selectAll("p").data([4,5,6,7,8])
var enter = update.enter().append("p")
enter.merge(update).text(function(d){return d;}) // 一次调用text就可以对所有的selection设置对应数据了
网友评论