所以我试图理解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()
似乎也是多余的。
有什么想法吗?
答案 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
(因为它来自select
)returns an d3 selection array with one element来自select
。这假设返回的节点是one element only。因为Sizzle引擎返回类似于数组的对象中的所有选择,所以它的行为类似于数组,但d3假设它是一个只包含一个节点元素的数组。这就是为什么当您通过selectAll
和enter
解除data
和append
语句,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,但它肯定更好,因为它显示了相应更新所有链接和节点的意图。如果稍后添加预先存在的节点,则容易出错。