2013-04-10 65 views
1

所以我想了解http://bl.ocks.org/mbostock/4062045的例子,并且有几个问题。D3:从头开始添加新节点的最佳方式

从例如:

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

那是什么基本上是做(据我所知)越来越(即无)“链接”类的所有元素,然后从“graphs.links”,并称一切到那个空的元素列表。所有新的元素(如“enter()”所表示的都被一个“行”标签封装,并且具有“class”属性集并被程式化。是不会得到任何东西为什么都做呢?为什么不这样做?:

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

我想一个理由不这样做的是,它似乎并没有工作,但笑为什么不呢?

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

有什么想法?

回答

1

如果APPY这个空graph.links,然后做console.log(links),这里是你将得到的铬什么JavaScript控制台:

[数组[0],选择:功能,全选:功能,ATTR:功能, 归类:功能,款式:函数...]

所以,是的,你将有一个空数组,但你有所有的功能已经存在,这样,当您添加数据之后,你不必须再做一切。这就是d3的智能。

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必须使用的理由很简单:在这种情况下,通过select

var svg = d3.select("body").append("svg") 
.attr("width", width) 
.attr("height", height); 

append(因为它是select后)returns an d3 selection array with one element:SVG的元素创建使用append这里。这假定返回的节点是one element only。因为Sizzle引擎在类似数组的对象中返回所有选择,所以它的行为就像一个数组,但是d3假定它是一个只有一个节点元素的数组。这就是为什么当你解除selectAllenter声明时,one single node is drawndataappend。如果您试图通过将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,但它肯定更好,因为它显示了相应地更新所有链接和节点的意图。如果您稍后添加预先存在的节点,则很容易出现错误。