Javascript 为什么d3';s select()和selectAll()在这里的行为不同吗?

Javascript 为什么d3';s select()和selectAll()在这里的行为不同吗?,javascript,d3.js,Javascript,D3.js,我在玩,我注意到一些我无法解释的事情 在此片段中: 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更改为

我在玩,我注意到一些我无法解释的事情

在此片段中:

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
元素添加在
标记之后。原始代码使用
selectAll
,将它们添加到
标记之后,正如您所期望的那样

由于原始html不包含硬编码的
元素,我认为
select
selectAll
都只返回空选择。所以我不明白为什么它们会导致不同的行为


我只是想找个解释。谢谢

查看Mike Bostock关于select/selectAll的帖子:

引述:

select和selectAll之间有一个重要区别:select保留现有分组,而selectAll创建新分组。因此,调用select将保留原始选择的数据、索引甚至父节点


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

因此,当您使用一个接一个selectAll时,结果将非常像嵌套的循环列表


这里的其他答案有点离题,并且没有引用正确的来源;这只与嵌套相关。D3的作者在他的概念中解释了这一点。我在此回顾完整性:

您有两个集合(数组):

  • 驱动可视化的数据集
  • 表示该数据集中每个数据项的HTML元素
  • 在应用程序运行期间的任何给定时间,这些集合可能不完全相同。因此,我们做了一些管理,以确保它们始终匹配(每个处理帧)。想象一下一个实时数据集(流)——也许上次我们只有98个元素,而现在我们只有100个。该页面仍有98个
    s,但现在我们需要再创建2个。这正是代码中自动发生的情况:

  • 通过调用
    .selectAll(“svg”)
    您会说,“创建一组
    元素,即使它们不存在。”另一种说法是,“让我们想象一下,我们可以选择一组与给定数据集相匹配的
    。现在,继续创建该集。”
  • …这正是
    .enter().append(…)
    所做的。相反,如果新数据集中的元素太多(因为以前数据集中的in元素比现在多),
    .exit().remove(…)
    可以解决这个问题
  • enter
    是我们需要创建的元素集<代码>退出是我们需要删除的


    您的
    .selectAll(“svg”)
    将不返回任何内容,但由于它更像是一个建议而非命令,因此它会在
    .enter().append(“svg”)
    中创建所需内容,以匹配给定的数据集。

    好吧,如果您确实想要处理多个元素,那么选择一个元素是没有意义的。所以我认为使用
    .select
    +
    .data
    无论如何都不应该是一个有效的用例
    .select
    似乎创建了一个选择,其中
    parentNode
    (HTML根节点)和
    。selectAll
    是一个选择,其中
    (在
    之后。选择('body')
    )。将元素添加到
    html
    似乎不是预期的行为,但可能是有意的。我会问作者,这也可能是一个bug。re:你关于select用例有效性的观点,我的理解是select和selectAll都返回一个selection对象,这是一种集合。select返回的集合恰好只有一个元素(或者是空的)。因此,应用data()在这两种情况下都是有效的。如果这种理解是错误的,请纠正我。select应该只获取与标识符匹配的第一个元素,它的附加方式不应该与selectAll不同。我会把它作为bug发布在Github上。