这是键功能,第二个参数selection.data的目的:它可以让你通过控制数据被绑定到哪个元素保持object constancy。例如,假设你有对象的数组代表水果:
var fruits = [
{name: "orange", value: 200},
{name: "apple", value: 124},
{name: "banana", value: 32}
];
当你第一次创建的元素,你并不需要的关键功能,因为没有任何现有的元素,所以你可以使用标准的全选,数据输入,追加模式:
var div = d3.select("body").selectAll(".fruit")
.data(fruits)
.enter().append("div")
.attr("class", "fruit")
.text(function(d) { return d.name + ": " + d.value; });
这种操作的结果是:
<body>
<div class="fruit">orange: 200</div>
<div class="fruit">apple: 124</div>
<div class="fruit">banana: 32</div>
</body>
但是,现在让我们假设你的数据的变化,并且要更新到refle新数据。这一新数据可能会以不同的顺序,并且一些元素可以添加或删除:
var fruits2 = [
{name: "apple", value: 124},
{name: "lemon", value: 17},
{name: "banana", value: 32},
{name: "strawberry", value: 1465}
];
苹果和香蕉分别在原始数据,所以我们想留住他们。这被称为更新选择。草莓和柠檬是新的;这是输入的选择。最后橘子走开了,形成了退出的选择。
使用引用数据的name
属性的键函数,我们可以按照预期将新数据分配给旧元素。然后,我们可以创建进入水果和删除退出的水果:
var div = d3.select("body").selectAll(".fruit")
.data(fruits2, function(d) { return d.name; });
div.enter().append("div")
.attr("class", "fruit")
.text(function(d) { return d.name + ": " + d.value; });
div.exit().remove();
这就是所谓的general update pattern。 (你可有周围做这个的第一次;它的全选,数据输入,追加模式的更一般的形式)的结果是:
<body>
<div class="fruit">apple: 124</div>
<div class="fruit">banana: 32</div>
<div class="fruit">lemon: 17</div>
<div class="fruit">strawberry: 1465</div>
</body>
虽然选择div
顺序的数据相匹配fruit2
,DOM中的顺序不是而是,因为输入元素被添加到主体的末尾。 (选择。追加没有任何花哨的逻辑来保证排序;它只是将新元素添加到父项的最后)。使用SVG时,我们通常不关心DOM元素的顺序,因为所有元素都是绝对定位的。如果您做一下顺序护理,你可以使用selection.order进入后修复:
div.order(); // make the DOM element order match the selection
而且,在这个例子中,我们不需要做出更新选择的任何变化,因为这些值对于苹果和香蕉没有改变。如果更新数据也发生变化,您可以直接调用selection.attr和selection.text来调用上面的selection.data调用。
谢谢迈克!!!! – ehsan
THx的答案。我在两个准相同的情况下使用selection.order(),一次它工作,一次它不。选择的顺序究竟是什么?它取决于给数据功能的关键吗? – JulienFr
我想答案是基于“[enter.append有一个方便的副作用:它用更新选择中的新元素替换了输入选择中新创建的元素。因此,在enter.append之后,更新选择是修改为包含输入和更新元素。](https://bost.ocks.org/mike/selection/#enter-update)“。但是,我的[测试](https://gist.github.com/an0/a924bf0d25e43d71584402dff6e28344)似乎并非如此。更新选择仍然只包含enter.append后的更新。必须在'update'和'enter'的'merge'上调用'order'使其工作。为什么? – an0