D3:从头开始添加新节点的最佳方式

时间:2013-04-10 05:23:19

标签: javascript d3.js

所以我试图理解http://bl.ocks.org/mbostock/4062045上的例子并提出一些问题。

来自示例:

  var link = svg.selectAll(".link")
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

基本上做什么(据我理解)是获取“link”类的所有元素(即什么都没有),然后将“graphs.links”中的所有元素添加到该空元素列表中。所有新元素(由“enter()”表示都由“line”标记封装,具有“class”属性集并被设置为风格化。

我的问题是......如果你知道selectAll()不会得到任何东西为什么要这样做?为什么不这样做?:

  var link = svg
      .data(graph.links)
    .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", function(d) { return Math.sqrt(d.value); });

我想一个不这样做的原因是它似乎不起作用,但为什么不呢?

当然,如果你认为一切都是新的,enter()似乎也是多余的。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

如果您使用空graph.links进行操作,然后执行console.log(links),那么您将在chrome javascript控制台上获得以下内容:

  

[Array [0],选择:function,selectAll:function,attr:function,   分类:功能,风格:功能......]

所以,是的,你将有一个空数组,但你已经拥有了所有的功能,这样,当你之后添加数据时,你不必再做一切。这就是d3如何聪明。

答案 1 :(得分:0)

为了理解究竟做了什么,让我们从上到下走示例:

var link = svg.selectAll(".link")
  .data(graph.links)
.enter().append("line")
  .attr("class", "link")
  .style("stroke-width", function(d) { return Math.sqrt(d.value); });
执行

selectAll以捕获任何预先存在的链接(无法正确假设),并返回选择(为空)。然后通过data将数据分配给空选择。然后,enter根据data中假定的节点与selectAll返回的选择之间的差异返回节点选择,在此示例中是所有节点,因为没有预先存在的节点。然后使用append将这些节点附加到svg元素。

现在,必须使用selectAll的原因非常简单:svg元素是使用append创建的:

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
在这种情况下,

append(因为它来自selectreturns an d3 selection array with one element来自select。这假设返回的节点是one element only。因为Sizzle引擎返回类似于数组的对象中的所有选择,所以它的行为类似于数组,但d3假设它是一个只包含一个节点元素的数组。这就是为什么当您通过selectAllenter解除dataappend语句,one single node is drawn时。如果您尝试通过将enter重新显示到语句来更改此设置,那么您就不幸了:enter尝试进行选择,其中包含data定义的所有节点,这些节点在预先存在的情况下不存在选择。因为它假设预先存在的选择是一个节点数组it fails to do its job with a single node returned by select

另一方面,

selectAll returns the needed array of nodes。因为没有预先存在的节点you could also relieve the string selector,但它肯定更好,因为它显示了相应更新所有链接和节点的意图。如果稍后添加预先存在的节点,则容易出错。