Snippet 1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
</head>
<body>
<script type="text/javascript">
var data = [];
for (i = 0; i < 3; i += 1) {
data.push(i);
}
d3.select('body')
// .selectAll('p')
.data(data)
.enter()
.append('p')
.text(function(d) {
return d;
});
</script>
</body>
</html>
Snippet 2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
</head>
<body>
<script type="text/javascript">
var data = [];
for (i = 0; i < 3; i += 1) {
data.push(i);
}
d3.select('body')
.selectAll('p')
.data(data)
.enter()
.append('p')
.text(function(d) {
return d;
});
</script>
</body>
</html>
代码.selectAll('p')
在第一个代码段中发表了评论。由于这个原因,我无法弄清楚为什么忽略第一个数据。
我是d3.js的新手以及我理解的内容,因为我的HTML中没有p
标记,.selectAll('p')
会返回一个空选项并附加p
根据我的数据计算。
提前致谢。
答案 0 :(得分:2)
要了解发生了什么,你必须了解什么是&#34;输入&#34;选择。本文底部的例子简要解释了&#34;输入&#34;选择以及为什么必须在第二个代码段中selectAll("p")
,即使您在文档中没有<p>
。
现在,让我们看一下你的片段:
您的第一个代码:
在您的第一个代码段中,data
为[0, 1, 2]
。所以,你有3个元素。选择正文时,DOM中显然有body
。因此,您将第一个数据(0)与此元素(正文)相关联。现在,您有2个与任何DOM元素无关的数据:1
和2
。这两个数据是你的&#34;输入&#34;选择。当您追加<p>
时,您的输入选择只包含这两个数字。
您的第二个代码段
在您的第二个代码段中,数据再次为[0, 1, 2]
。不同的是,现在您选择了所有<p>
...但没有。这是&#34;占位符&#34;在我链接的示例中。由于DOM中没有<p>
与数据相关联,因此您的输入选择包含所有3个数据:0
,1
和2
。
正如我在例子中写的那样:
如果在你的&#34;输入&#34;选择你选择的东西,你的&#34;输入&#34;选择将始终包含您的所有数据。
占位符在&#34;输入&#34;选择强>
什么是输入选择?
在D3.js中,当一个人将数据绑定到DOM元素时,有三种情况可能:
在情况#3中,没有相应DOM元素的所有数据点都属于 enter 选择。因此,在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; });
这是结果(jsfiddle here):
请注意,在这种情况下,我们使用selectAll("div")
作为我们&#34;输入&#34;的第一行。选择变量。我们有一个包含6个值的数据集,D3为我们创建了6个div。
占位符的作用
但是假设我们的文档中已经有一个div,顶部是<div>This is my chart</div>
。在那种情况下,当我们写:
body.selectAll("div")
我们正在选择现有的div。因此,我们的输入选择将只有5个数据而没有匹配的元素。例如,in this jsfiddle,HTML中已有div(&#34;这是我的图表&#34;),这将是结果:
我们没有看到价值&#34; 40&#34;再来一次:我们的第一个&#34;酒吧&#34;消失了,其原因是我们进入&#34;进入&#34;现在选择只有5个元素。
我们在这里要理解的是,在我们的输入选择变量的第一行selectAll("div")
中,这些div只是占位符。如果我们要追加divs
,则我们不必选择所有divs
,如果我们追加circle
,则不必选择所有circle
。我们可以选择不同的东西。并且,如果我们不打算进行更新&#34;或者退出&#34;退出&#34;选择,我们可以选择任何:
var divs = body.selectAll(".foo")//this class doesn't exist, and never will!
.data(data)
.enter()
.append("div");
这样做,我们选择所有&#34; .foo&#34;。在这里,&#34; foo&#34;是一个不仅不存在的类,而且它从未在代码中的任何其他地方创建过!但这并不重要,这只是一个占位符。逻辑是:
如果在你的&#34;输入&#34;选择你选择的东西,你的&#34;输入&#34;选择将始终包含您的所有数据。
现在,选择.foo
,我们的&#34;输入&#34;选择有6个元素,即使我们已经在文档中有一个div:
选择null
到目前为止,保证您不做任何选择的最佳方法是选择null
。不仅如此,这种替代方案比其他方式更快。</ p>
因此,对于输入选择,只需执行:
selection.selectAll(null)
.data(data)
.enter()
.append(element);
这是一个演示小提琴:https://jsfiddle.net/gerardofurtado/th6s160p/
<强>结论强>
处理&#34;输入&#34;选择时,要特别注意不要选择已经存在的东西。您可以使用selectAll
中的任何内容,即使是不存在且永远不存在的内容(如果您不打算进行&#34;更新&#34;或者&#34)退出&#34;选择)。
示例中的代码基于Mike Bostock的代码:https://bl.ocks.org/mbostock/7322386