动态添加节点到d3.js强制有向图 [英] Dynamically adding nodes to d3.js Force directed graph

查看:233
本文介绍了动态添加节点到d3.js强制有向图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将动态添加节点添加到d3.js强制定向图时遇到问题,我想知道这里的任何人是否可以为该主题留出一些光。

I am having trouble with dynamically adding nodes on to a d3.js force directed graph and I was wondering if anyone here could shed some light on the subject.

我遇到的问题是,我想让tick函数转换图形上的所有节点,而不只是新添加的节点。

The problem I am having is that I want the tick function to transform all nodes on the graph and not just the newly added ones.

下面是用于添加节点和处理转换的函数:

Below are the functions I use for adding nodes and handling the transformation:

// Function to handle tick event
function tick() {
     tick_path.attr("d", function(d) {
     var dx = d.target.x - d.source.x,
     dy = d.target.y - d.source.y,
     dr = Math.sqrt(dx * dx + dy * dy);
    return "M" + 
        d.source.x + "," + 
        d.source.y + "L" + 
        d.target.x + "," + 
        d.target.y;
     });

     tick_node.attr("transform", function(d) { 
          return "translate(" + d.x + "," + d.y + ")"; });
 }


 /**
   * Append nodes to graph.
   */
 function addNodes2Graph(){

    // define the nodes
       // selection will return none in the first insert
       // enter() removes duplicates (assigning nodes = nodes.enter() returns only the non-duplicates)
    var nodes = viz.selectAll(".node") 
    .data(g_nodes)
    .enter().append("g") 
    .on("click", nodeClick)
    .call(force.drag);

    // From here on, only non-duplicates are left
    nodes
        .append("circle")
        .attr("r", 12)
        .attr("class", "node");

    nodes.append("svg:image")
    .attr("class", "circle")
    .attr("xlink:href", "img/computer.svg")
    .attr("x", "-8px")
    .attr("y", "-8px")
    .attr("width", "16px")
    .attr("height", "16px");

   // add the text 
    nodes.append("text")
    .attr("x", 12)
    .attr("dy", ".35em")
        .text(function(d) { return d.ip; });


     return nodes;
 }

 // Execution (snippet)

 // Add new nodes
 tick_node = addNodes2Graph();
 // Add new paths
 tick_path = addPaths2Graph();


 // Restart graph
 force
.nodes(g_nodes) // g_nodes is an array which stores unique nodes
.links(g_edges) // g_edges stores unique edges
.size([width, height])
.gravity(0.05)
.charge(-700)
.friction(0.3)
.linkDistance(150)
.on("tick", tick)
.start();

我认为问题是,我只得到从addNodes2Graph返回的非重复的结果, tick 函数,但我不知道如何在不向图形添加重复节点的情况下实现这一点。

I think the problem is that I only get non-duplicated results returned from addNodes2Graph which I then use in the tick function but I'm not sure how I could achieve this without adding duplicated nodes on to the graph.

现在,它要么在图表上添加重复的元素,要么只转换 tick 上的新节点。

At the moment, it's either adding duplicated elements on to the graph or transform only the new nodes on tick.

非常感谢您的帮助。

推荐答案

看起来您只是将节点添加到DOM,而不是强制布局。总结一下,你需要做的是将节点添加到强制布局中。

It looks like you're adding nodes only to the DOM, not to the force layout. To recap, here's what you need to do to add nodes to the force layout.


  • 向强制布局使用的数组添加元素其节点。这需要是最初传递的相同的数组,即如果你想要平滑的行为,你不能创建一个新的数组和传递它。修改 force.nodes()应该可以正常工作。

  • 对链接也一样。

  • 使用 .data()。enter()为新数据添加新的DOM元素。


  • Add elements to the array that the force layout uses for its nodes. This needs to be the same array that you passed in initially, i.e. you can't create a new array and pass that it if you want smooth behaviour. Modifying force.nodes() should work fine.
  • Do the same for the links.
  • Add the new DOM elements using .data().enter() with the new data.
  • No change to the tick function should be required as adding the nodes and DOM elements is done elsewhere.

code> code> tick >添加新的节点/链接后,您需要再次调用 force.start(),以便将它们考虑在内。

After adding the new nodes/links, you need to call force.start() again to have it take them into account.

这篇关于动态添加节点到d3.js强制有向图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆