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

Pau*_*gel 6 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(); });
Run Code Online (Sandbox Code Playgroud)

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

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

alt*_*lus 6

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

你的陈述完全是这样的:

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

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

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

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

看看Mike Bostock 撰写的优秀文章Thinking with Joins,可以更深入地解释发生了什么.