d3:创建新元素时对selectAll()的困惑

时间:2013-07-26 08:45:54

标签: javascript html d3.js

我是d3的新手,正在使用Scott Murray的“互动数据可视化网络”(这很棒),让我开始。现在我所看到的所有内容都按照描述的方式工作,但在查看创建新元素的过程时,让我感到困惑。简单的例子(来自Scott Murray):

svg.selectAll("circle")
    .data(dataset)
    .enter()
    .append("circle");

名称"circle"用于selectAll,它返回一个空的选择(这是我学到的)。然后通过将相同的名称添加到.append来附加圆圈。太好了!

现在让我感到困惑的是当你想再次做同样的事情时会发生什么。所以你有第二个数据集,并希望以相同的方式生成新的圆圈。使用相同的代码只是替换数据集显然不起作用,因为selectAll("circle")将不再返回空选择。所以我玩了一遍,发现我可以在selectAll中使用任何名称,甚至可以将其留空:selectAll()

Scott Murrays示例总是只为每个数据集使用一种类型(圆圈,文本等)。最后我在官方的例子中找到了像

这样的东西
svg.selectAll("line.left")
    .data(dataset)
    .enter()
    .append("line")
    .attr ...

svg.selectAll("line.right")
    .data(dataset)
    .enter()
    .append("line");
    .attr ...

现在我的问题:selectAll("ENTRY")中的这个条目是如何使用的?以后可以用它来再次以任何方式引用这些元素,或者它真的只是一个虚拟名称,可以以任何方式选择并只需要返回一个空选择?我不能在生成的DOM或对象结构中的任何地方找到此条目。

谢谢你让我困惑。

1 个答案:

答案 0 :(得分:5)

在调用selectAll()之前,您在.data()来电中的内容确实非常重要,只有在您更改/更新显示的内容时才会这样。想象一下,你已经有了很多圈子,你想改变他们的位置。坐标由数据决定,所以最初你会做类似

的事情
svg.selectAll("circle")
   .data(data)
   .enter()
   .append("circle")
   .attr("cx", function(d) { return d; })
   .attr("cy", function(d) { return d; });

现在您的新数据具有相同数量的元素,但坐标不同。要更新圆圈位置,您需要做的就是

svg.selectAll("circle")
   .data(newData)
   .attr("cx", function(d) { return d; })
   .attr("cy", function(d) { return d; });

D3会将newData中的元素与现有圈子(您在selectAll中选择的内容)匹配。这样你就不需要再次附加圆圈了(毕竟它们已经存在),但只更新它们的坐标。

请注意,在第一次通话中,您在技术上不需要选择circle。这样做是好的做法,只是为了弄清楚你想要做什么,并避免意外选择其他元素的问题。

例如,您可以在此更新模式here上找到更多信息。