D3可折叠力布局动态地将节点添加到布局

时间:2016-06-22 18:53:18

标签: javascript d3.js graph visualization

我在可折叠力布局中动态添加节点时遇到了一些问题。我的数据集将动态创建,因此每次创建强制布局时对象都会更改,因此我使用D3 mbostock中的示例,他们使用本地对象而不是加载JSON作为我的初始起点。

我添加了pan + zoom但添加节点似乎不起作用。我有一个静态对象(用于测试目的),点击一个节点时调用我的addNode函数。我试图通过以下方式添加节点: var childrenTest=[ {"name": "Title", "size": 3938}, {"name": "Title", "size": 3938}, {"name": "Title", "size": 3938} ];

g.data.children[1].children = childrenTest;然后运行update();,它应该展平数据以进行折叠,并在更新之前在节点之间创建链接。

不幸的是,当我这样做时,它完全打破了我的图形,从我的主图创建了一个浮动簇偏移,并且链接和节点丢失了。我想知道我是否可以得到一些帮助,找出它为什么不能正确添加节点。

以下是我的代码示例:https://jsfiddle.net/Diffusion_net/hu6t2ywb/9/

(注意:addnode函数只会在无子节点上添加一次点击节点,因为只检查测试用途)

谢谢

1 个答案:

答案 0 :(得分:0)

在动态添加新节点时,关键是映射id(查看你的flatten函数,它将id分配给这样的节点 - > nodes.id = ++ i;)新创建的节点的方式应该是唯一的,并且不应该与节点的现有id(已经存在于布局上)重叠。不这样做会导致不可预测的行为,如你的情况。

处理此问题的一种方法是记住布局中已存在多少个节点,以便您可以为新创建的节点分配新的id值。请参阅下面的修改后的展平功能。

var alreadyNodes = 0; //no of nodes already present on the layout
   function flatten(data) {
    console.log(data);
    var nodes = [],
    i = alreadyNodes; //offset to the node id
    var flattenNodes = 0; //no of nodes flatten under the current node
       //count only children (not _children)
       //note that it doesn't count any descendents of collapsed _children
       //rather elegant?
    function recurse(node) {
           if (node.children) node.children.forEach(recurse);
           if (!node.id) {
              node.id = ++i;
              flattenNodes++;
           }
           nodes.push(node);
    }
    recurse(data);
       //Done:
    alreadyNodes = alreadyNodes + flattenNodes;
    return nodes;
}

此处 alreadyNodes 存储布局中已存在的节点数, flattenNodes 计算要添加到布局的节点数。在返回节点(最后一行)之前, alreadyNodes 会更新。检查每次调用flatten时如何给出id的偏移量,以确保新节点获得新的id。

我希望这会有所帮助。