了解过 D3 的同学,对下边的这张图片想必都很熟悉
D3 是 data-diven-document 的意思,那么到底什么是数据驱动文档呢?D3 是怎样把数据跟 dom 元素连接到一起的?
一般是分为三步:
selectAll 选取
data 绑定
通过 enter() update() exit() 操作
就像下边的代码所示:
svg.selectAll(“circle”) //return empty selection
.data(data) // 跟一个数组绑定,返回 update selection
.enter() // 返回 enter selection
.append(“circle”) //
.attr("cx", function(d) {return d.x;})
.attr("cy", function(d) {return d.y;})
.attr("r", 2.5);
下面我们仔细的看一下 D3 的 select 和 data join
selection
一般来说,你可能会认为 selection 是包含 dom 元素的数组,其实这是错误的。selection 是 array 的子类,它包含了操做选中元素的方法,比如:attr style;并继承了 array 的方法。
selection 是数组的数组。d3.select 和 d3.selectAll 都返回的是把包含一个 group 数组的数组,而 selection.selectAll 返回包含多个 group 的数组。
数据绑定 (data join)
当你给 selectin 绑定数据,实际上 data 是存储在 selection 中每一个 dom 元素的__data__属性上。
d3.select('body').__data__ = 42 等价于
d3.select('body').datum(42)
d3.select('body').datum(42).append('h1') //h1 继承了父级的数据
什么是 D3 中的 data?
data 就是包含值的数组。
data 数组中的值是跟 selection 中的 group 对应的,而不是跟 group 中的元素。(selection.data defines data per-group rather than per-element: data is expressed as an array of values for the group, or a function that returns such an array. Thus, a grouped selection has correspondingly grouped data!)
数据绑定中的 key
默认是通过比较 datum 和 element 的 index 来绑定的。
另外我们还可以指定一个 key 函数,自定义 key pair。
需要注意:key 函数是每个 group 中的 each element 执行一次,而不是整个 group 来对比。
enter update exit
如果 selection 和 data 中的 key 匹配不上,那么就有了上述三个 selection
注意上述三个 selection 中未匹配的元素用 null 表示
Merging Enter & Update
enter.append 有一个副作用:把 update 中的 null 元素替换成 enter 中新创建的元素