Объединение узлов в D3 Force Layout
Я не уверен, что это можно сделать, но я чувствую, что логически у меня запрограммирована функциональность. Я пытаюсь сделать так, чтобы пользователь мог выбрать несколько узлов, а затем нажать 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();
}
Однако при выборе и последующем объединении узлов новые узлы не создаются, а выбранные узлы успешно удаляются. Кроме того, я получаю нечетный текст, перезаписываемый в метках, когда делаю это (отдельная проблема, но пока игнорируюсь - Удалить текст из узлов в d3).
Мой код можно найти здесь: http://bl.ocks.org/joeycf/f021e60bb38846dcfaf2 Дважды нажмите, чтобы Select
/Deselect
и объединение осуществляется нажатием на кнопку.
Спасибо за помощь!