Skip to main content
 首页 » 编程设计

networking中使用 d3.js 删除网络图中的连接/圆

2025年02月15日103myhome

请看看我的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,则不应创建新连接。

如果您有任何意见、建议或想法 - 那就完美了。当然,我总是可以遍历源代码并删除不需要的圆圈并创建新的连接,但我正在寻找比这更有效的方法+我还将有一个撤消按钮,它可以恢复所做的任何更改,但一次一个问题。

谢谢!

请您参考如下方法:

这称为网络投影,您不应将其视为删除节点,而应将其视为将节点转换为边。这并不是说从 D3 的角度来看您对任务的理解是错误的 — 您需要删除并创建新节点,但使用正确的术语将引导您找到其他示例。当您采用一种类型的网络节点(例如论文)并将它们用作边缘来连接另一种类型的节点(例如人)以将人员网络及其所写的论文转变为连接到的人员网络时,就会发生多模态网络投影与他们一起写论文的人。

要使用 D3 实现这一目标,您必须做一些事情。

首先,您的链接和边缘需要有唯一的 ID,并在绑定(bind)数据时使用它们。当您想要使用 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(); 
 
 }