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

D3: best way to add new nodes from scratch

本文关键字:节点 最佳 方法 从头开始 添加 新节点 D3      更新时间:2023-09-26

所以我试图理解 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()似乎也是多余的。

有什么想法吗?

如果你用空graph.links应用它,然后console.log(links),这是你将在chrome javascript控制台上得到的:

[数组[0], 选择: 函数, 选择全部: 函数,

属性: 函数, 分类:函数,样式:函数...]

所以,是的,你将有一个空数组,但你已经拥有所有函数,这样,当你之后添加数据时,你不必再做所有事情。这就是 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); });

执行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 之后(通过 select 返回一个带有一个元素的 d3 选择数组。这假定返回的节点只是一个元素。由于 Sizzle 引擎返回类似数组对象中的所有选择,因此它的行为类似于数组,但 d3 假定它是一个只有一个节点元素的数组。这就是为什么当你解除selectAllenter语句时,dataappend绘制了一个节点。如果您尝试通过将enter重新附加到语句来更改此设置,那么您就不走运了:enter尝试使其选择包含由data定义的所有节点,这些节点在预先存在的选择中不存在。因为它假定预先存在的选择是一个节点数组,所以它无法用 select 返回的单个节点完成其工作。

另一方面,selectAll 返回所需的节点数组。因为没有预先存在的节点,你也可以减轻字符串选择器,但最好把它放在那里,因为它显示了相应地更新所有链接和节点的意图。如果您稍后添加预先存在的节点,则很容易出现错误。