假设我们有一个没有子节点的svg元素:
<svg id="bargraph" width="400" height="90" ></svg>
假设我们还有一个数据数组:
var data = [10,20,30,40,50];
此代码正确地将新的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");
下面的代码将新的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");
答案 0 :(得分:2)
每当附加元素时,D3会将它们附加到选定的父元素。您没有选择父元素,而只选择具有指定父元素的元素。
在您的示例中,您选择了父ID为rect
的所有bargraph
,而您可以成功更新这些节点:
d3.selectAll(#bargraph rect).data(data).attr(...)
但是,使用以下内容不会将项目附加到#bargraph
(如您所述):
d3.selectAll("#bargraph rect).data(data).enter()
这里,D3将扫描整个文档,即父元素(d3.selectAll()
),并返回与选择标准匹配的每个匹配元素。然后,输入选择将为数据数组中不存在的每个元素创建一个占位符节点。这些节点是根据父元素选择创建的:
从概念上讲,输入选择的占位符是指向的位置 父元素(documentation)
就像我们可以选择矩形并输入圆圈一样,没有任何东西可以连接选择器和我们想要输入的元素的类型/位置。
在下面的示例中,我使用d3.selectAll("svg circle")
选择(并更新)SVG圈,但是我输入了一个div - 我们可以看到div被附加到父选择的元素中,在d3.selectAll()
的情况是文档本身,而不是SVG(而不是正文),尽管我的选择器:
var svg = d3.select("body").append("svg");
svg.append("circle")
.attr("cx",40)
.attr("cy",40)
.attr("r",20)
.attr("fill","orange");
var circles = d3.selectAll("svg circle")
.data(["steelblue","yellow"])
.attr("fill",function(d) { return d; });
circles.enter().append("div")
.html(function(d) { return d; });
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
&#13;
好的,但为什么D3会那样?最终,我无法回答为什么,因为这是由我自己以外的人做出的决定的结果。我担心一些推理可能是这样的:
如果(#bargraph rect)
等选择器确定了要输入元素的位置,那么根据选择器可能存在某些挑战:
bargraph
的元素,或者您希望在其他地方输入元素(但仍需要选择ID为{{1的元素的特定子元素),该怎么办? }})。 当前最后两个是关于类而不是ID,但无论选择器字符串如何,行为应该是相似的(选择器字符串中的ID,类和元素的不同行为可能会令人困惑)。选择的方法可能被那些决定选为最干净,最清晰的程序员。