为什么d3的select()和selectAll()在这里表现不同?

时间:2013-01-06 23:06:36

标签: javascript d3.js

我正在玩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>元素,我认为selectselectAll都只返回空选择。所以我无法弄清楚它们导致不同行为的原因。

我只是在寻找解释。谢谢!

3 个答案:

答案 0 :(得分:8)

select和selectAll之间的基本区别在于select会压缩现有选择的层次结构,而selectAll会保留它。

因此,当你在另一个之后使用一个selectAll时,结果将很像嵌套for循环列表。

http://bost.ocks.org/mike/nest/

答案 1 :(得分:4)

查看Mike Bostock关于select / selectAll:Nested Selections

的帖子

引用:

  

select和selectAll之间存在重要差异:select保留现有分组,而selectAll创建新分组。因此调用select会保留原始选择的数据,索引甚至父节点!

答案 2 :(得分:0)

这里的其他答案有些偏离,并且没有引用正确的来源;这仅与嵌套有切线关系。 D3的作者在他的join概念中对此进行了解释。我在这里查看其完整性:

您有两组(数组):

  1. 推动可视化的数据集;
  2. 表示该数据集中每个数据项的HTML元素。

在应用程序运行期间的任何给定时间,这些设置可能并不完全相同。想象一个实时数据集(流)-也许上一次我们只有98个元素,而现在却只有100个元素。页面上仍然有98个<div>,但是现在我们需要再创建2个。正是确切地在您的代码中自动发生的情况:

  1. 通过调用.selectAll("svg"),您说的是,“创建一组<svg>元素,即使它们不存在”。另一种表达方式是,“让我们想象一下,我们可以选择一组<svg>来匹配我们给定的数据集。现在,继续创建该集合。”
  2. ... .enter().append(...)正是这么做的。相反,如果新数据集中的元素过多(因为以前数据集中的元素比现在多了),.exit().remove(...)就可以解决。

enter是我们需要创建的元素集; exit是我们需要删除的内容。

您的.selectAll("svg")不会返回任何内容,但是由于它比提案更重要,因此它是提案,然后它在.enter().append("svg")中创建所需的内容,以匹配给定的数据集。