D3.js 在d3画布中动态添加节点

D3.js 在d3画布中动态添加节点,d3.js,force-layout,D3.js,Force Layout,我是d3新手。我尝试了几个JSON节点的例子,得到了一个很好的工作网络图 但是,当我尝试动态添加额外节点时,它不会显示在屏幕上 我从开始,然后尝试添加以下代码,但它不起作用;我怎样才能解决这个问题,请帮忙 graph.addNode("NewNode"); function addNode (id) { nodes.push({"id":id}); restart(); } function restart() { node = node.data(nodes);

我是d3新手。我尝试了几个JSON节点的例子,得到了一个很好的工作网络图

但是,当我尝试动态添加额外节点时,它不会显示在屏幕上

我从开始,然后尝试添加以下代码,但它不起作用;我怎样才能解决这个问题,请帮忙

graph.addNode("NewNode");

function addNode (id) {
    nodes.push({"id":id});
    restart();

}


function restart() {
  node = node.data(nodes);

  node.enter().insert("circle", ".cursor")
      .attr("class", "node")
      .attr("r", 5);


  node.exit()
      .remove();

  link = link.data(links);

  link.enter().insert("line", ".node")
      .attr("class", "link");
  link.exit()
      .remove();

  force.start();
}

有几件事与不太明显的力有关:

  • 初始化时,原始数据数组中的节点将获得一系列新属性
  • 初始化后,原始数据数组中的链接将转换为新形式
此外,如果您遵循链接的示例,则不需要输入/更新/退出样式循环-部队使用的是原始数据数组,而不是任何DOM元素

节点

在参考示例中,节点仅以id和组开始:

{"source": "Montparnasse", "target": "Babet", "value": 2}
但是,在使用
simulation.nodes(nodes)
初始化后,它们会获得一些附加参数:

group: 1
id: "Myriel"
index: 0
vx: 0.0026819653036056477
vy: -0.0005005454729913666
x: 306.003096668046
y: 359.07887474183434
这四个附加属性跟踪节点。每个勾号都要求这些属性已经存在,如果它们不存在,我们就会遇到问题。因此,如果我们提供一个新节点,我们可以给它x、y、vy、vx属性,以便无缝地添加它(,在所有示例中单击以添加节点)。这提供了一个简单的addNode函数:

  function addNode () {
    var id = graph.nodes.length;
    graph.nodes.push({"id":id, index: id, x: width/2, y: height/2, vx: 0, vy: 0});
  }
或者,我们可以使用
simulation.nodes()
()重新初始化节点,力将自动放置节点,同时为其提供所需的位置。但是,除非指定x和y坐标(),否则这是跳跃的

最后一个函数也为我们提供了一个非常直接的addNode函数:

  function addNode () {
    var id = graph.nodes.length;
    graph.nodes.push({"id":id, group: 12, x: width/2, y: height/2});
    simulation.nodes(graph.nodes)
  }
这将有助于向力添加节点

链接

对于链接,参考示例中的原始数据在加载时如下所示:

{ source: "Napoleon", target: "Myriel", value: 1 }
但是,在初始化链接后,将采用以下形式:

index: 0
source: Object { id: "Napoleon", group: 1, index: 1, … } 
target: Object { id: "Myriel", group: 1, index: 0, … }
value: 1
源特性和目标特性将转换为表示每个点的对象。与节点一样,勾选函数要求节点采用后一种形式。与上面一样,我们可以尝试复制格式,或者使用强制设置格式本身,我选择后者作为链接,同时为新节点设置x,y。这是用于以下内容的addNode函数:

  function addNode () {
    var id = graph.nodes.length;
    graph.nodes.push({"id": id, x: width/2, y: height/2});
    graph.links.push({source: "Javert", target: id });

  simulation
      .nodes(graph.nodes)
      .force("link")
      .links(graph.links);  
  }

作为一个更复杂但理论性较低的示例,这可能很有趣(和(单击以添加/删除节点,用左上角的按钮切换哪个操作)),其中添加/删除节点,这反过来会影响force和voronoi

我在您的“force add Node and Link”(强制添加节点和链接)块中看到的,但我很好奇您是如何如此顺利地添加新节点的。我知道那个方块是用来画画布的,但你能解释一下,不使用画布怎么能做同样的事情吗?