【问题标题】:How to assign a unique id to a node in d3 collapsible tree如何为d3可折叠树中的节点分配唯一ID
【发布时间】:2023-03-08 19:39:01
【问题描述】:

作为 d3 和 javascript 的新手,我正在尝试通过查看提供的版本来了解可折叠树的工作原理

http://bl.ocks.org/mbostock/4339083

具体来说,我不明白以下语句如何以及为什么在更新节点后成功地为节点分配唯一 ID。

// 更新节点…

  var node = svg.selectAll("g.node")
            .data(nodes, function(d) { return d.id || (d.id = ++i); });

我的理解是nodes是一个数组,这个数组有一个关联的索引i。 每次更新节点时,上述语句使用从数组索引 i 派生的 id 的唯一键值将新节点(如数据)与网页上的节点(如视觉表示)绑定。如果nodes数组的一个元素没有id,就会被赋值为++i。

这就是我感到困惑的地方。假设第一个节点数组有 4 个元素,因此每个元素的 id 为 1、2、3 和 4。我折叠树,现在新节点数组有 3 个元素,它们恰好与第一个节点的前三个元素相同大批。这些元素的 id 为 1,2 和 3。到目前为止没有问题。

现在下一个更新的节点数组有 4 个元素,前 3 个元素相同,第 4 个元素不同。 上面的代码正确地为第 4 个元素分配了 5 的 id。

我的理解是

  1. 最后一个节点数组有 4 个元素,

  2. 这个新的第 4 个元素的索引 i = 3,并且

  3. ++i = 4

  4. 因此,上述语句应该为第 4 个元素分配了 4 的 id。

但是代码指定了 id=5。当我在 firebug 调试器中检查 i 的值时,i 上升到 4,保持在 4,然后在上述情况下变为 5。

有人可以解释上面的代码发生了什么以及我的错误理解在哪里吗?

谢谢。

【问题讨论】:

  • 用 i++ 得到你想要的。
  • 不确定我是否理解您的问题。 i 是一个全局变量,而不是这里的数组索引,也许这就是你的困惑所在?
  • 是的,它有一个索引——在函数声明function(d, i) 中明确表示。如果这解决了您的问题,我可以发布一个带有更多解释的答案。
  • 谢谢,这解释了我的问题。我原以为 i 是一个特殊的 d3 变量,因为它在 # selection.data([values[, key]]) 段中的github.com/mbostock/d3/wiki/Selections#wiki-data 中说“要控制数据如何连接到元素,可以指定一个键函数. 这替换了默认的按索引行为;key 函数为新数据数组中的每个元素调用一次,并为选择中的每个现有元素调用一次。在这两种情况下,key 函数都传递了数据 d 和索引一世。”这 i 与全局 i 有什么不同吗?谢谢。
  • 这是糟糕的编码风格,仅此而已,当我们习惯于在与本地索引变量类似的上下文中看到它时,使用i 作为持久计数器变量。正如@LarsKotthoff 所说,使用的i 版本取决于函数声明——如果你声明一个具有特定名称的函数参数,它将屏蔽任何具有相同名称的外部变量。但是,我建议给计数器变量一个不同的名称,以免混淆!

标签: javascript arrays d3.js


【解决方案1】:

在您所指的特定示例中使用的变量i 与几乎所有其他 D3 示例相反,是一个全局计数器,用于跟踪已看到的节点数。在许多其他情况下,您会看到类似

的代码
.attr("something", function(d, i) { ... })

.data(data, function(d, i) { ... })

在所有这些情况下,i 指的是函数的局部变量——数据元素在其数组中的索引。这是由 D3 传递的,并且 与您所指的示例中的 i 完全不同

如果您将所有出现的i 替换为counter,可能有助于更好地理解该示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-02
    • 1970-01-01
    • 2018-11-19
    相关资源
    最近更新 更多