12

我正在玩阻力倍数示例,我注意到一些我无法解释的事情。

在这个片段中:

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返回空选择。所以我无法弄清楚为什么它们会导致不同的行为。

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

4

3 回答 3

9

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

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

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

于 2015-02-07T22:36:16.563 回答
6

查看 Mike Bostock 关于 select/selectAll 的帖子:嵌套选择

去引用:

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

于 2013-01-30T20:02:03.190 回答
2

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

你有两组(数组):

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

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

  1. 通过调用.selectAll("svg")您是在说,“创建一组<svg>元素,即使它们不存在。” 另一种说法是,“假设我们可以选择一组<svg>与我们给出的数据集匹配的 s。现在,继续创建该组。”
  2. ...这正是.enter().append(...)当时所做的。相反,如果我们的新数据集的元素太多(因为我们以前在数据集中的元素比现在多),.exit().remove(...)将处理这个问题。

enter是我们需要创建的一组元素;exit是我们需要删除的。

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

于 2018-12-02T14:01:57.533 回答