使用d3.js时,为什么在将新元素添加到条目选择时,我必须在select之后调用selectAll?

时间:2018-03-10 19:06:55

标签: select d3.js enter selectall

假设我们有一个没有子节点的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");

1 个答案:

答案 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(而不是正文),尽管我的选择器:

&#13;
&#13;
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;
&#13;
&#13;

好的,但为什么D3会那样?最终,我无法回答为什么,因为这是由我自己以外的人做出的决定的结果。我担心一些推理可能是这样的:

如果(#bargraph rect)等选择器确定了要输入元素的位置,那么根据选择器可能存在某些挑战:

  • 如果您不想将元​​素输入到标识为bargraph的元素,或者您希望在其他地方输入元素(但仍需要选择ID为{{1的元素的特定子元素),该怎么办? }})。
  • 如果您选择了一个类,或每个div / p / etc,哪个父元素会将新输入的元素追加到?
  • 如果选择一个元素类,您可能希望将兄弟节点而不是子节点附加到该类。

当前最后两个是关于类而不是ID,但无论选择器字符串如何,行为应该是相似的(选择器字符串中的ID,类和元素的不同行为可能会令人困惑)。选择的方法可能被那些决定选为最干净,最清晰的程序员。