基本d3:为什么你可以选择不存在的东西?

时间:2015-10-28 19:51:26

标签: javascript d3.js

我一直在学习d3,我对选择感到有些困惑。请考虑以下示例:

http://bl.ocks.org/mbostock/1021841

具体来说,让我们来看看这一行:

var node = svg.selectAll(".node")
    .data(nodes)
  .enter().append("circle")
    .attr("class", "node")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", 8)
    .style("fill", function(d, i) { return fill(i & 3); })
    .style("stroke", function(d, i) { return d3.rgb(fill(i & 3)).darker(2); })
    .call(force.drag)
    .on("mousedown", function() { d3.event.stopPropagation(); });

在它所说的documentation中,“选择是从当前文档中提取的一系列元素。”我将此解释为svg.selectAll(.node)创建了从当前文档中提取的类.node的元素数组,但据我所知,没有这样的元素!除非我感到困惑 - 而且我几乎可以肯定我是 - 文档中唯一给出了某个东西的地方“节点”是在选择已经发生之后(当我们写.attr("class", "node")时)。

那么这里发生了什么? svg.selectAll(".node")实际选择了什么?

1 个答案:

答案 0 :(得分:5)

虽然乍一看,这可能看起来像一个简单而愚蠢的问题,但对于每个试图与D3.js做一些认真工作的人来说,答案可能是最重要的。请记住,D3.js是关于将数据绑定到某些DOM结构并提供保持数据和文档同步的方法。

你的陈述完全是这样的:

  1. 选择所有具有类node的元素。这可能很好地返回一个空的选择,就像你的情况一样,但它仍然是d3.selection

  2. 将数据绑定到此选择。基于上面提到的选择,这将基于每个元素计算连接检查,如果新数据是a)尚未绑定到此选择,b)之前已被绑定,或c)之前绑定但未绑定包含在新数据中。根据此检查的结果,选择将分别分为输入,更新或退出选择。

  3. 因为您的选择首先是空的。所有数据都将在输入选择中结束,该选择通过调用selection.enter()来检索。

  4. 现在,您可以通过在输入选择上调用selection.append()来附加与新绑定数据相对应的新元素。

  5. 请看看Mike Bostock撰写的优秀文章Thinking with Joins,以便对正在发生的事情进行更深入的解释。