D3 使用称为data join 的更新范例。它针对数据的增量更新进行了优化,适合图表使用。
要使用数据连接,您需要对“选择”进行操作。您不是通过选择来表示您想要做什么,而是表示您希望数据如何转换。
let dataset = [ {name: "a", value: 1}, {name: "b", value: 2}, {name: "c", value: 3} ]
let svg = d3.select("body")
.append("svg")
const selection = svg.selectAll("rect")
.data(dataset, d => d.name) // data join, each "rect" will correspond to an data
// second argument is a key function to uniquely identify each data
selection
.enter()
.append("rect")
/* attr: x, y, height, width */
selection 代表数据连接。在这里,您告诉 D3 您正在进行选择。不过,目前 DOM 中不存在任何内容,因此我们得到一个空选择。
定义选择时:
换个角度看:
data
data &nodes nodes
+-----+
+--------------------+
| | | |
| a:1 | | |
| b:2 | | |
| c:3 | | |
| | | |
+--------------------+
+-----+
enter 选择将包含没有节点的数据。这就是您在使用 enter 时正在处理的数据。
假设我们现在更改数据集。我们如何更新 DOM 节点?
dataset = [ {name: "a", value: 9}, {name: "c", value: 3}, {name: "d", value: 4} ]
// note how we need to select rect to get the existing data.
// this is the "update" selection
const selection = svg.selectAll("rect")
.data(dataset, d => d.name)
.attr("x", d => d.value)
// the "enter" selection
selection.enter()
.append("rect")
// the "exit" selection
selection.exit().remove()
我们现在有三个选择。如果我们再次绘制图表,这就是我们现在的数据所在的位置:
data
data &nodes nodes
+-----+
+--------------------+
| | | |
| d:4 | a:9 | b:2 |
| | | |
| | | |
| | | |
+--------------------+
+-----+
在我们进行数据连接时会发生什么?数据发生了变化。现在svg.selectAll("rect") 采用已经存在的选择:D3 保存在 DOM 中。 这就是您需要将 CSS 选择器传递给 selectAll 的原因。 D3 使用该选择器来查找现有选择,通过每个 DOM 节点上的 .__data__ 属性保存在 DOM 中。
现在我们正在观察新数据,并将其与 DOM 中的数据进行比较:
- a 仍然有一个数据,并且它有一个来自先前数据连接的节点。我们知道 a 仍然存在,但它的值已经改变,因为我们的数据是具有 {name, value} 的对象。所以它在“数据和节点”中。
- b在dom中有节点,但是对应的新数据中不存在。它在“节点”中。
- d 是一个新项目:它是没有节点的数据。所以它进入“数据”。
由于 c 没有更新,它不在任何选择中。
让我们重命名图中的内容:
enter update exit
+-----+
+--------------------+
| | | |
| d:4 | a:9 | b:2 |
| | | |
| | | |
| | | |
+--------------------+
+-----+
当您直接使用选择(更新选择)、调用enter() 或调用exit() 时,您始终在处理这三个选择中的任何一个。只在需要时管理更新,或者不每次都重新创建节点 - 只在需要时销毁,效率要高得多,尤其是对于大数据。
即使您只使用enter() 转换,D3 也会通过确保只创建新项目来提高效率。
这个想法是,您可以将管理所有三种状态的 sn-p 放在类似 render() 函数的东西中,并一直调用它:当您第一次生成图形时和更新数据时。 D3 为您管理所有数据簿记。