占位符在输入选择中的作用
什么是输入选择?
在 D3.js 中,当一个数据绑定到 DOM 元素时,可能有三种情况:
- 元素数量和数据点数量相同;
- 元素多于数据点;
- 数据点多于元素;
在情况#3 中,没有相应 DOM 元素的所有数据点都属于输入选择。因此,在 D3.js 中,输入选择是在将元素连接到数据之后包含与任何 DOM 元素不匹配的所有数据的选择。如果我们在输入选择中使用 append
函数,D3 将为我们创建绑定该数据的新元素。
这是一个维恩图,解释了有关数据点数/ DOM 元素数量的可能情况:
我们可以看到,输入选择是左侧的蓝色区域:没有相应 DOM 元素的数据点。
输入选择的结构
通常,输入选择包含以下 4 个步骤:
selectAll
:选择 DOM 中的元素;data
:计算和解析数据;enter
:将选择与数据进行比较,创建新元素;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; });
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