我有一个函数 buildTree 作为输入 json 数据并使用 d3.js 和 cola.js 将它们可视化。这个想法是我单击一个按钮并将 json 添加到 d3。然后通过单击另一个按钮,我添加了另一个 js 并保留了旧的,所以我最终得到了两棵树。在我的示例中,我有一个节点存在于两个 json 文件中,因此我希望最终将这两棵树连接起来,并且该节点出现一次。
我设法获取现有树,添加新树,删除两次存在的节点并更新链接,但一个链接从未连接到共存节点。
JSON 文件具有以下格式:
{
"nodes": [
{"id": "a", "name": "a", "type": "tool", "width": 60, "height": 40},
{"id": "b", "name": "b", "type": "tool", "width": 60, "height": 40},
{"id": "c", "name": "c", "type": "tool", "width": 60, "height": 40}
],
"links": [
{"source": 0, "target": 1},
{"source": 0, "target": 2}
],
"groups": []
}
第二个:
{
"nodes": [
{"id": "h", "name": "h", "type": "tool", "width": 60, "height": 40},
{"id": "i", "name": "i", "type": "tool", "width": 60, "height": 40},
{"id": "c", "name": "c", "type": "tool", "width": 60, "height": 40}
],
"links": [
{"source": 0, "target": 1},
{"source": 0, "target": 2}
],
"groups": []
}
所以 c 是一个存在于两个 JSON 文件中的节点,并且应该只出现在树中一次,但同时包含两个链接。
buildTree 类似于:
function buildTree(jsonSource) {
d3.json(jsonSource, function (error, graph) {
//get existing data if any and merge them with new data
myNodes = svg.selectAll(".node");
myLinks = svg.selectAll(".link");
//update the existing nodes with the new ones, remove duplications and store them in removedNodes
allNodes = graph.nodes.concat(myNodes.data());
var uniqueIds = [];
var allNodesUnique = [];
var removedNodes = [];
for (var i = 0; i < allNodes.length; i++) {
var id = allNodes[i].id;
if (uniqueIds.indexOf(id) == -1) {
uniqueIds.push(id);
allNodesUnique.push(allNodes[i]);
} else {
removedNodes.push(allNodes[i]);
}
}
allNodes = allNodesUnique;
//update links
allLinks = graph.links.concat(myLinks.data());
d3.selectAll("svg > *").remove();
cola
.nodes(allNodes)
.links(allLinks)
.groups(graph.groups)
.start();
...