eri*_*gor 6 select enter selectall d3.js
假设我们有一个没有子节点的 svg 元素:
<svg id="bargraph" width="400" height="90" ></svg>
Run Code Online (Sandbox Code Playgroud)
假设我们还有一个数据数组:
var data = [10,20,30,40,50];
Run Code Online (Sandbox Code Playgroud)
此代码正确地将新的 rect 元素附加到 svg 元素。
d3.select("#bargraph")
.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("height", 10)
.attr("width", function(d) { return d; })
.attr("x", 0)
.attr("y", function (d, i) { return i * 20; })
.attr("fill", "blue");
Run Code Online (Sandbox Code Playgroud)
下面的代码不会将新的 rect 元素附加到 svg 元素。你能告诉我为什么吗?
d3.selectAll("#bargraph rect")
.data(data)
.enter()
.append("rect")
.attr("height", 10)
.attr("width", function(d) { return d; })
.attr("x", 0)
.attr("y", function (d, i) { return i * 20; })
.attr("fill", "blue");
Run Code Online (Sandbox Code Playgroud)
每当您附加元素时,D3 都会将它们附加到选定的父元素。您没有选择父元素,而是仅选择具有指定父元素的元素。
\n在您的示例中,您选择所有rect具有 id 的父项bargraph,同时您可以使用以下命令成功更新这些节点:
d3.selectAll("#bargraph rect").data(data).attr(...)\nRun Code Online (Sandbox Code Playgroud)\n但是,使用以下内容不会将项目附加到#bargraph(如您所述):
d3.selectAll("#bargraph rect").data(data).enter()\nRun Code Online (Sandbox Code Playgroud)\n这里,D3将扫描整个文档,父元素,(d3.selectAll() ) 并返回与选择器条件匹配的每个匹配元素。然后,输入选择将为数据数组中不存在的每个元素创建一个占位符节点。这些节点是根据父元素选择创建的:
\n\n从概念上讲,输入选择\xe2\x80\x99s 占位符是指向\n父元素的指针(文档)
\n
正如我们可以选择矩形并输入圆形一样,没有任何东西将选择器和我们希望输入的元素的类型/位置联系起来。
\n在下面的示例中,我使用 选择(并更新)SVG 圆d3.selectAll("svg circle"),但输入了一个 div - 我们可以看到该 div 附加到父选择的元素,在这种情况下d3.selectAll()是文档本身,而不是尽管我选择了 SVG(而不是主体):
d3.selectAll("#bargraph rect").data(data).attr(...)\nRun Code Online (Sandbox Code Playgroud)\r\nd3.selectAll("#bargraph rect").data(data).enter()\nRun Code Online (Sandbox Code Playgroud)\r\n好吧,但是为什么 D3 会这样呢?最终,我无法回答为什么,因为这是我以外的人做出的决定的结果。我敢打赌,其中一些推理可能是这样的:
\n如果诸如此类的选择器(#bargraph rect)确定了元素的输入位置,那么根据选择器的不同,可能会遇到某些挑战:
bargraph?也许您想在其他地方输入元素(但仍然需要仅选择具有 id 的元素的特定子元素bargraph)。当然,最后两个是关于类而不是 ID,但无论选择器字符串如何,行为都应该相似(选择器字符串中的 ID、类和元素的不同行为可能会令人困惑)。所选择的方法可能被那些决定者选为对程序员来说最干净、最清晰的方法。
\n