在节点点击时接收D3力布局图

时间:2013-12-31 16:55:13

标签: d3.js force-layout

我正在尝试创建一个强制图表,该图表会在点击时重新集中。

我关注this作为基础:

enter image description here

我尝试调整点击功能以设置d.fixed=true,并为d.xd.y分配固定点。

但是,我需要为所有其他节点转为d.fixed=false。此外,节点在点击时不会转换到中心。

我的问题是如何将所有其他固定属性设置为false,然后使用新中心重绘力图?

我准备了一个示例here

enter image description here

点击功能相当简单:

  function click(d) {
        d.fixed=true;
        d.x=10;
        d.y=10;
        update();
    }

我尝试将其添加到函数中:

root.forEach(function (d) { d.fixed = false; });

2 个答案:

答案 0 :(得分:6)

您可以使用force.nodes()访问节点并进行迭代,将fixed属性设置为false

force.nodes().forEach(function(d) { d.fixed = false; });

然后更新图表。我分叉你的例子here并添加了一个双击监听器,重启强制布局。的问候,

答案 1 :(得分:4)

一些事情,按照我接近问题的顺序。如果你想跟随,那么这是final fiddle

首先,您的update()方法不仅仅是更新节点的位置;它重新计算整棵树。对于你正在尝试做的事情来说这太过分了,虽然最终结果却不是问题的根源,但我仍然建议你只使用force.resume()让计时器滴答作响并且节点再次移动

其次,您在正确的轨道上添加了forEach语句来关闭以前的固定节点。但是forEach适用于数组,root是一个对象。因此要么重用flatten方法(慢),要么像@Pablo建议那样做,并使用force.nodes()将节点作为数组(更好)。

第三,这需要一点思考:一旦你将一个节点设置为“固定”,强制布局会忽略任何新的dx和dy值,将它们重置为d.px和d.py(之前的值)。 (我假设这样,如果节点被拖动,它将自动跳回到其固定位置)。因此,要将其移动到您想要的位置,您必须设置“先前”值,而不是新值。唯一的问题是,这会导致立即跳跃,而不是平稳运动。在调用force.resume()之前,您可能希望为该一个节点添加转换(使其看起来像被拖到中心)。