请查看我的jsFiddle,其中包含以下相关数据:
rules = [['L5', 'L2'], ['L5', 'L2'], ['L4', 'L2'], ['L2', 'L1'], ['L3', 'L1'], ['L1', 'C1'], ['C1', 'R2'], ['C1', 'R3'], ['R2', 'R4'], ['R3', 'R6'], ['R3', 'R7']];
,我的目标是有一个按钮,我可以用来删除图中的圆圈。例如,当我按下e按钮时,我删除R3,R2,L5。当这样做时,我需要在以下之间建立新的联系: 如果删除R3,则R7和R6应指向C1 如果R2被删除,那么R5应该连接到C1 如果L5则不应创建新连接。
如果您有任何建议或意见或建议,那将是完美的。当然,我总是可以遍历源并删除不需要的圈子并创建新的连接,但我正在寻找比这更有效的方式+ Ill也有和撤消按钮可以恢复所做的任何更改,但是在一个问题上时间。
谢谢!
答案 0 :(得分:2)
这称为网络投影,您不应将其视为删除节点,而应将其视为将节点转换为边缘。这并不是说从D3的角度来看你的任务是错的 - 你需要删除并创建新节点,但是使用正确的术语会引导你进入其他例子。当您采用一种类型的网络节点(比如纸张)并将它们用作边缘来连接另一种类型的节点(如人)时,会发生多模式网络投影,以将人们的网络和他们写入的论文转换为连接到的人的网络。他们用文章写的人。
要使用D3完成此操作,您必须做一些事情。
首先,您需要为链接和边缘提供唯一ID,并在绑定数据时使用它们。当您想要使用D3进行复杂更新和删除元素时,通常需要这样做:
d3.selectAll(".link")
.data(links, function (d) {return d.id})
d3.selectAll(".node")
.data(nodes, function (d) {return d.id})
在您的情况下,这些唯一ID可以是节点的节点名称和链接的已连接节点的连接节点名称。
有了这个,你就可以构建一个这样的简单函数,当你点击一个节点时会激活它:
function collapseNode(d,i) {
force.stop();
removedLinks = links.filter(function (p) {return p.source == d.id || p.target == d.id});
filteredLinks = links.filter(function (p) {return p.source != d.id && p.target != d.id});
filteredNodes = nodes.filter(function (p) {return p.id != d.id});
//create new links
//this will have problems with parallel edges
for (x in removedLinks) {
for (y in removedLinks) {
if (removedLinks[x].source != d && removedLinks[y].source != d) {
filteredLinks.push({source: removedLinks[x].source, target: removedLinks[y].source,
id: generateAnID})
}
else if (removedLinks[x].target != d && removedLinks[y].source != d) {
filteredLinks.push({source: removedLinks[x].target, target: removedLinks[y].source,
id: generateAnID})
}
else if (removedLinks[x].source != d && removedLinks[y].target != d) {
filteredLinks.push({source: removedLinks[x].source, target: removedLinks[y].target,
id: generateAnID})
}
else if (removedLinks[x].target != d && removedLinks[y].target != d) {
filteredLinks.push({source: removedLinks[x].target, target: removedLinks[y].target,
id: generateAnID})
}
}
}
d3.selectAll(".node").data(filteredNodes, function(d) {return d.id})
.exit()
.remove();
d3.selectAll(".link").data(filteredLinks, function(d) {return d.id})
.exit()
.remove();
d3.selectAll(".link").data(filteredLinks, function(d) {return d.id})
.enter()
.append("line)
.attr("class", "line")
force.start();
}