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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14187784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:57:37  来源:igfitidea点击:

Why are d3's select() and selectAll() behaving differently here?

javascriptd3.js

提问by Jonah

I am playing around with the drag multiples example, and I noticed something I can't explain.

我在玩拖动倍数的例子,我注意到一些我无法解释的东西。

In this snippet:

在这个片段中:

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);

I changed selectAllto select. It still works, but now the svgelements are added afterthe </body>tag. The original code, with selectAll, adds them after the <body>tag as you would expect.

我换selectAllselect。它仍然有效,但现在的svg元素将被添加</body>标签。如您所料,带有 的原始代码selectAll将它们添加到<body>标记之后。

Since the original html contains no hardcoded <svg>element, I would think that both selectand selectAlljust return the empty selection. So I cannot figure out why they result in different behavior.

由于原来的HTML不包含硬编码的<svg>元素,我认为无论是selectselectAll刚刚返回空选择。所以我无法弄清楚为什么它们会导致不同的行为。

I'm just looking for an explanation. Thanks!

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

回答by Avi Dubey

The basic difference between select and selectAll is that select squashes the hierarchy of the existing selections, while selectAll preserves it.

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

Therefore, when you use one selectAll after the other, the result will be a lot like a list of nested for loops.

因此,当您一个接一个地使用 selectAll 时,结果将很像嵌套的 for 循环列表。

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

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

回答by Dave Foster

Check Mike Bostock's post about select/selectAll: Nested Selections

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

To quote:

去引用:

There is an important difference between select and selectAll: select preserves the existing grouping, whereas selectAll creates a new grouping. Calling select thus preserves the data, index and even the parent node of the original selection!

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

回答by Engineer

Other answers here are a bit off, and don't cite the correct source; this is only tangentially related to nesting. D3's author explains it in his joinconcept. I review that here for completeness:

这里的其他答案有点偏离,不要引用正确的来源;这仅与嵌套有切线关系。D3 的作者在他的连接概念中解释了它。我在这里查看完整性:

You have two sets (arrays):

你有两组(数组):

  1. the dataset that drives the visualisation;
  2. the HTML elements that represent each data item in that dataset.
  1. 驱动可视化的数据集;
  2. 表示该数据集中每个数据项的 HTML 元素。

These sets may not be exactly the sameat any given time during the application's run. So we do a little management to ensure they do match, at all times (every processing frame). Imagine a real-time data set (stream) - maybe last time we only got 98 elements, now instead we've got 100. The page still has 98 <div>s, but now we need to create 2 more. That's exactlywhat happens, automagically, in your code:

在应用程序运行期间的任何给定时间,这些集合可能并不完全相同。因此,我们进行了一些管理以确保它们始终匹配(每个处理帧)。想象一个实时数据集(流)——也许上次我们只有 98 个元素,现在我们有 100 个。页面仍然有 98<div>秒,但现在我们需要再创建 2 个。这正是您的代码中自动发生的事情:

  1. By calling .selectAll("svg")you are saying, "Create a set of <svg>elements even if they don't exist." Another way to put this is, "Let's imagine we can select a set of <svg>s that matches the dataset we've given. Now, go ahead and create that set."
  2. ...Which is exactly what .enter().append(...)then does. Conversely, if there had been too many elements for our new dataset (because we previously had more in elements in the dataset than we do now), .exit().remove(...)would deal with that.
  1. 通过调用.selectAll("svg")您是在说:“即使<svg>元素不存在,也要创建一组元素。” 另一种说法是,“假设我们可以选择一组<svg>与我们提供的数据集相匹配的 s。现在,继续创建该组。”
  2. ......这正是.enter().append(...)当时所做的。相反,如果我们的新数据集有太多元素(因为我们以前在数据集中的元素比现在多),.exit().remove(...)就会处理这个问题。

enteris the set of elements we need to create; exitis those we need to remove.

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

Your .selectAll("svg")would return nothing, but as it is more of a proposal than an imperative, it then creates what it needs in .enter().append("svg"), in order to match the dataset given.

.selectAll("svg")不会返回任何内容,但由于它更像是一个建议而不是命令,然后它会在 中创建它需要的内容.enter().append("svg"),以匹配给定的数据集。