占位符在输入选择中的作用

什么是输入选择?

在 D3.js 中,当一个数据绑定到 DOM 元素时,可能有三种情况:

  1. 元素数量和数据点数量相同;
  2. 元素多于数据点;
  3. 数据点多于元素;

在情况#3 中,没有相应 DOM 元素的所有数据点都属于输入选择。因此,在 D3.js 中,输入选择是在将元素连接到数据之后包含与任何 DOM 元素不匹配的所有数据的选择。如果我们在输入选择中使用 append 函数,D3 将为我们创建绑定该数据的新元素。

这是一个维恩图,解释了有关数据点数/ DOM 元素数量的可能情况:

StackOverflow 文档

我们可以看到,输入选择是左侧的蓝色区域:没有相应 DOM 元素的数据点。

输入选择的结构

通常,输入选择包含以下 4 个步骤:

  1. selectAll:选择 DOM 中的元素;
  2. data:计算和解析数据;
  3. enter:将选择与数据进行比较,创建新元素;
  4. append:在 DOM 中附加实际元素;

这是一个非常基本的例子(看看 var divs 中的 4 个步骤):

var data = [40, 80, 150, 160, 230, 260];

var body = d3.select("body");

var divs = body.selectAll("div")
    .data(data)
    .enter()
    .append("div");

divs.style("width", function(d) { return d + "px"; })
    .attr("class", "divchart")
    .text(function(d) { return d; });

这就是结果( 这里jsfiddle ):

https://i.stack.imgur.com/NItFz.jpg

请注意,在这种情况下,我们使用 selectAll("div") 作为 enter 选择变量的第一行。我们有一个包含 6 个值的数据集,D3 为我们创建了 6 个 div。

占位符的作用

但是假设我们的文档中已经有了 div,就像顶部的 <div>This is my chart</div> 一样。在那种情况下,当我们写:

body.selectAll("div")

我们正在选择现有的 div。因此,我们的输入选择将只有 5 个数据而没有匹配的元素。例如,在这个 jsfiddle 中 ,HTML 中已经存在 div(这是我的图表),这将是结果:

https://i.stack.imgur.com/5XUmB.jpg

我们不再看到值 40 了:我们的第一个条形消失了,原因是我们的输入选择现在只有 5 个元素。

我们在这里要理解的是,在我们的输入选择变量 selectAll("div") 的第一行,这些 div 只是占位符。如果我们追加 divs,我们不必选择所有的 divs,如果我们追加 circle,我们不需要选择所有 circle。我们可以选择不同的东西。而且,如果我们不打算选择更新退出,我们可以选择任何内容

var divs = body.selectAll(".foo")//this class doesn't exist, and never will!
    .data(data)
    .enter()
    .append("div");

这样做,我们选择了所有的“.foo”。在这里,foo 是一个不仅不存在的类,而且它从未在代码中的任何其他地方创建过! 但没关系,这只是一个占位符。逻辑是这样的:

如果在输入选择中选择了不存在的内容,则输入选择将始终包含所有数据。

现在,选择 .foo,我们的输入选择有 6 个元素,即使我们已经在文档中有一个 div:

https://i.stack.imgur.com/X5ftR.jpg

这里是相应的 jsfiddle

选择 null

到目前为止,保证你什么都不做的最好方法就是选择 null。不仅如此,这种替代方案比其他方式更快。

因此,对于输入选择,只需:

selection.selectAll(null)
    .data(data)
    .enter()
    .append(element);

这是一个演示小提琴: https//jsfiddle.net/gerardofurtado/th6s160p/

结论

处理输入选择时,请特别注意不要选择已存在的内容。你可以在 selectAll 中使用任何内容,即使是不存在且永远不存在的内容(如果你不打算进行更新退出选择)。

示例中的代码基于 Mike Bostock 的代码: https//bl.ocks.org/mbostock/7322386