我不确定是否可以这样做但我觉得逻辑上我已经编程了功能。我试图让它成为用户可以选择多个节点,然后点击merge
按钮,所有这些节点合并(进入一个名为MergedNode#
的新节点)。此新节点将继承已合并的所有节点的所有链接。此节点还应该unmerge
能够销毁MergedNode
并恢复其中的所有节点/链接。
以下是我正在执行大部分merge
处理的代码段(暂时忽略unmerge
)。
function mergeNode() {
mergedNodesStore = [];
console.log("Attempting to merge nodes.");
// Check if at least 2 nodes are selected.
if (selectedNodes.length < 2) {
alert("Must select at least 2 or more nodes.");
}
else {
// Iterating through each of the selected nodes.
for (var i = 0; i < selectedNodes.length; i++) {
mergedNodesStore.push[selectedNodes[i]];
// Iterates through each of the edges to apply the old links to new merged node.
for (var j = 0; j < edges.length; j++) {
var mergedEdge;
if (selectedNodes[i].data.id === edges[j].data.source) {
mergedEdge = edges[j].data.target;
edges.push({
source: "MergedNode" + mnCount,
target: mergedEdge,
data: selectedNodes[i].data
});
}
else if (selectedNodes[i].data.id === edges[j].data.target) {
mergedEdge = edges[j].data.source;
edges.push({
source: "MergedNode" + mnCount,
target: mergedEdge,
data: selectedNodes[i].data
});
}
}
// Remove the merge nodes from the nodes array.
selectedNodes[i].removed = true;
nodes.splice(nodes.indexOf(selectedNodes[i]), 1);
spliceLinksForNode(selectedNodes[i]);
}
// Push the "MergeNode" to the mergeNodes array.
mergedNodes.push({
id: "MergedNode" + mnCount,
label: "MergedNode" + mnCount,
childrenNodes: mergedNodesStore
});
mnCount++;
}
insertMergeNodes();
}
function insertMergeNodes() {
// pushes the NODE attributes in the JSON to the nodes array.
mergedNodes.forEach(function(n) {
// if node already exists it does not get pushed to the nodes array.e
if (!(n.data.id in nodesHash)) {
nodesHash[n.data['id']] = n;
nodes.push({
data: n.data,
selected: n.selected,
removed: n.removed
});
}
else console.log(n.data.id + "already exists.");
})
// sets the source and target to use id instead of index
edges.forEach(function(e) {
var sourceNode = nodes.filter(function(n) {
return n.data.id === e.data.source;
})[0],
targetNode = nodes.filter(function(n) {
return n.data.id === e.data.target;
})[0];
// push the EDGE attributes in the JSON to the edges array.
edges.push({
source: sourceNode,
target: targetNode,
data: e.data
});
});
force
.nodes(mergeNodes)
.links(edges)
update();
}
但是,在选择然后合并节点时,不会创建新节点,但会成功删除所选节点。此外,我在执行此操作时会在标签中收到奇怪的文字覆盖(单独的问题但暂时忽略 - Remove Text from Nodes in d3)。
我的代码可以在这里找到:http://bl.ocks.org/joeycf/f021e60bb38846dcfaf2
双击Select
/ Deselect
,点击按钮即可完成合并。
感谢您的帮助!