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

时间:2014-09-17 06:29:27

标签: networking d3.js geometry diagram

请查看我的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也有和撤消按钮可以恢复所做的任何更改,但是在一个问题上时间。

谢谢!

1 个答案:

答案 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();

 }