如何为d3可折叠树中的节点分配唯一ID

时间:2014-01-30 08:33:28

标签: javascript arrays d3.js

作为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); });

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

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

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

我的理解是

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

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

  3. ++ i = 4

  4. 因此,上述陈述应该为第4个元素指定了4的id。

  5. 但代码指定了id = 5。当我在firebug调试器中检查i的值时,我上升到4,保持在4,然后在上面的场景中变为5。

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

    谢谢。

2 个答案:

答案 0 :(得分:1)

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

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

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

在所有这些情况下,i引用函数的局部变量 - 其数组中的数据元素的索引。这是由D3和完全不同的 i传递的,而不是您所指的示例中的。{/ p>

如果将所有i替换为counter,可能会更好地理解该示例。

答案 1 :(得分:0)

您可以使用以下内容为可折叠树中的节点分配唯一ID

.attr('id', function() { return('node_' + makeid()) })

这里我使用Azle中的az.makeid()函数,但你可以使用你喜欢的任何东西来生成唯一的id。

我们将此添加到nodeEnter.append('circle')函数中,如下所示:

// Add Circle for the nodes
 nodeEnter.append('circle').
    attr('class', 'node').
    attr('r', 10).
    style("fill", function(d) {return "#33AADE"})
    .attr('id', function() { return('node_' + makeid()) }) // add id here

在每个节点上使用唯一ID,我们释放各种附加功能,允许我们将其他库与D3一起使用。例如,当用户点击节点时,我们可以使用Azle颜色并为特定节点制作动画

svg.selectAll("circle")
    .on("click", function(d) {
        var selected_circles = d3.select(this);
        selected_id = selected_circles._groups[0][0].id;
        az.animate_element('node', get_target_instance(selected_id), {
            "type" : "rubberBand"
        })
        az.delay_event({
            "function" : "$('#' + selected_id).css('fill', 'hotpink')"
        })
    });

结果

enter image description here

飞走动画:

enter image description here