我使用包含数组值的子div填充div。在第一次传递时,数组看起来像这样:
arr_subpop_unique = ["CPL", "NAP", "NPL", "SAP", "SPL", "TPL", "UMW", "WMT", "XER"]
我的选择输入/更新/退出如下所示:
var sizemapHeader = d3.select("#d3-sizemap-hr").selectAll("div")
.data(arr_subpop_unique)
sizemapHeader.enter().append("div")
.attr("class", "sizemap-hr-title ellipsis scroll_on_hover")
.html(function(d,i){ return d; });
sizemapHeader.exit().remove();
这很好用,给每个包含字符串的元素一个div。
当我再次运行该函数时,我的数据数组更新为:
arr_subpop_unique = ["MAN_MADE", "NATURAL"]
更新返回两个div,但是,它们包含" CPL"和" NAP" (索引值0和1)。有人可以解释为什么这不能用" MAN_MADE"取代前两个指标。和" NATURAL"?
感谢您的帮助...尝试在D3中获取输入/更新/退出数据连接的挂起!
答案 0 :(得分:5)
值得注意的是,链接有点不对称,因为enter()
具有合并到更新选择的副作用。这意味着,如果在append()
之后向更新选择添加功能,它们也将添加到输入节点上。另一方面,更新选择未合并到输入选择中。因此,enter()
之后链接的任何功能都只会出现在输入选择中。
在OP问题的情况下,有两个更新节点和零输入节点。因此,HTML将添加到不存在的输入节点上,并且不会更新两个更新节点的HTML。
所以,是的,这有效......
var sizemapHeader = d3.select("#d3-sizemap-hr").selectAll("div")
.data(arr_subpop_unique)
//ENTER
sizemapHeader
.enter()
.append("div")
.attr("class", "sizemap-hr-title ellipsis scroll_on_hover")
//UPDATE
sizemapHeader
.html(function (d, i) { return d; })
//EXIT
sizemapHeader
.exit()
.remove();
但这不是......
var sizemapHeader = d3.select("#d3-sizemap-hr").selectAll("div")
.data(arr_subpop_unique)
//ENTER
//sizemapHeader
.enter()
.append("div")
.attr("class", "sizemap-hr-title ellipsis scroll_on_hover")
//UPDATE
sizemapHeader
.html(function (d, i) { return d; })
//EXIT
sizemapHeader
.exit()
.remove();
这会在初始更新中中断(当更新选择为空时)...
var sizemapHeader = d3.select("#d3-sizemap-hr").selectAll("div")
.data(arr_subpop_unique)
//UPDATE
sizemapHeader
.html(function (d, i) { return d; })
//ENTER
sizemapHeader
.enter()
.append("div")
.attr("class", "sizemap-hr-title ellipsis scroll_on_hover")
//EXIT
sizemapHeader
.exit()
.remove();
当您跟踪代码时,您会看到sizemapHeader
的值在.enter()
被调用后发生变化。
原因是埋在维基中......
追加时,回车选择合并到更新选择 或插入。而不是将相同的运算符应用于输入和 单独更新选择,您现在只能将它们应用到 进入节点后更新选择。如果你发现自己 删除整个选择的元素只是为了重新插入大部分元素, 这样做。例如:
var update_sel = svg.selectAll("circle").data(data)
update_sel.attr(/* operate on old elements only */)
update_sel.enter().append("circle").attr(/* operate on new elements only */)
update_sel.attr(/* operate on old and new elements */)
update_sel.exit().remove() /* complete the enter-update-exit pattern */
答案 1 :(得分:4)
只是对@Plato提供的答案提供了不同的看法......
在某些情况下,您可能希望将更改的数据识别为" new",即。成为enter
选择的一部分,而不仅仅是update
的一部分。在您的示例中,它被视为update
选择的一部分,因为您的数据基于索引绑定到DOM元素(这是默认值)。您可以通过将第二个参数传递给data
调用来更改此行为。
有关详细信息,请参阅https://github.com/mbostock/d3/wiki/Selections#data。它被称为key
参数。
以下是一个例子:
var sizemapHeader = d3.select("#d3-sizemap-hr").selectAll("div")
.data(arr_subpop_unique, function(d, i) { return d; });
sizemapHeader.enter().append("div")
.attr("class", "sizemap-hr-title ellipsis scroll_on_hover")
.html(function(d,i){ return d; });
sizemapHeader.exit().remove();
data
函数调用的第二个参数现在将确保数据按值绑定到DOM元素,而不是数组中的索引。
下次使用新数据调用函数时,任何当前未绑定到DOM元素的值都将被视为新的,并且是enter
选择的一部分。
这两种情况都很有用,具体取决于您尝试实现的目标。
答案 2 :(得分:3)
看看"General update pattern"
我认为你没有触发d3的更新选择
var sizemapHeader =
d3.select("#d3-sizemap-hr").selectAll("div")
.data(arr_subpop_unique)
sizemapHeader
.enter()
.append("div")
.attr("class", "sizemap-hr-title ellipsis scroll_on_hover")
sizemapHeader
.html(function(d,i){ return d; });
sizemapHeader
.exit()
.remove();