我正在玩drag multiples example,我发现了一些我无法解释的事情。
在此片段中:
var svg = d3.select("body").selectAll("svg")
.data(d3.range(16).map(function() { return {x: width / 2, y: height / 2}; }))
.enter().append("svg")
.attr("width", width)
.attr("height", height);
我将selectAll
更改为select
。它仍然有效,但现在svg
元素在 </body>
标记之后添加了。包含selectAll
的原始代码会在<body>
标记之后添加它们,如您所料。
由于原始html不包含硬编码的<svg>
元素,我认为select
和selectAll
都只返回空选择。所以我无法弄清楚它们导致不同行为的原因。
我只是在寻找解释。谢谢!
答案 0 :(得分:8)
select和selectAll之间的基本区别在于select会压缩现有选择的层次结构,而selectAll会保留它。
因此,当你在另一个之后使用一个selectAll时,结果将很像嵌套for循环列表。
答案 1 :(得分:4)
查看Mike Bostock关于select / selectAll:Nested Selections
的帖子引用:
select和selectAll之间存在重要差异:select保留现有分组,而selectAll创建新分组。因此调用select会保留原始选择的数据,索引甚至父节点!
答案 2 :(得分:0)
这里的其他答案有些偏离,并且没有引用正确的来源;这仅与嵌套有切线关系。 D3的作者在他的join概念中对此进行了解释。我在这里查看其完整性:
您有两组(数组):
在应用程序运行期间的任何给定时间,这些设置可能并不完全相同。想象一个实时数据集(流)-也许上一次我们只有98个元素,而现在却只有100个元素。页面上仍然有98个<div>
,但是现在我们需要再创建2个。正是确切地在您的代码中自动发生的情况:
.selectAll("svg")
,您说的是,“创建一组<svg>
元素,即使它们不存在”。另一种表达方式是,“让我们想象一下,我们可以选择一组<svg>
来匹配我们给定的数据集。现在,继续创建该集合。” .enter().append(...)
正是这么做的。相反,如果新数据集中的元素过多(因为以前数据集中的元素比现在多了),.exit().remove(...)
就可以解决。 enter
是我们需要创建的元素集; exit
是我们需要删除的内容。
您的.selectAll("svg")
不会返回任何内容,但是由于它比提案更重要,因此它是提案,然后它在.enter().append("svg")
中创建所需的内容,以匹配给定的数据集。