D3JS Force Layout新节点断开现有节点

时间:2015-01-13 20:21:29

标签: javascript d3.js force-layout

当我向D3的强制布局中添加新节点时,新节点在定位自身时忽略先前的节点,并且先前的节点变得不可拖动。我觉得我遵循了以下逻辑:

  1. 向阵列节点和链接添加元素
  2. 更新了force.nodes(nodes)和force.links(links)
  3. 通过.data()。输入()新数据
  4. 名为force.start()
  5. 但仍导致先前的节点断开连接。新节点是可拖动的,并且似乎考虑了添加节点位置的最后一组并避免了碰撞,所有其他先前节点仍然可以点击,但是它们的定位被忽略并且没有更新。

    以下是PLNKR中的代码:http://plnkr.co/edit/5fXZf63s73cTO37zLjNQ?p=preview

    var width = 1000;
    var height = 600;
    var node_w = 30;
    var node_h = 30;
    var text_dx = -20;
    var text_dy = 20;
    var new_id = 9;
    var nodes = [],
        links = [],
        links_line,
        node_circles;   
    
    var svg = d3.select("body").append("svg")
        .attr("width",width)
        .attr("height",height);     
    
    var nodes = [
                    { "name": "Nucleus" , "size" : 25, "id" : 0 , "color":"#ac0000"},
                    { "name": "one"     , "size" : 5 , "id": 1  , "color": "#ac0"},
                    { "name": "two"     , "size" : 15 , "id": 2 , "color": "#ac0"},
                    { "name": "three"   , "size" : 25 , "id": 3 , "color": "#ac0"},
                    { "name": "four"    , "size" : 9 , "id": 4  , "color": "#ac0"},
                    { "name": "five"    , "size" : 12 , "id": 5 , "color": "#ac0"},
                    { "name": "six"     , "size" : 15 , "id": 6 , "color": "#ac0"},
                    { "name": "seven"   , "size" : 41 , "id": 7 , "color": "#ac0"},
                    { "name": "eight"   , "size" : 5 , "id": 8  , "color": "#ac0"}
                ];
    var links = [
                    { "source": 0 , "target": 1 , "link_info":"r01" },
                    { "source": 1 , "target": 2 , "link_info":"r31" },
                    { "source": 1 , "target": 3 , "link_info":"r02" },
                    { "source": 1 , "target": 4 , "link_info":"r04" },
                    { "source": 0 , "target": 5 , "link_info":"r05" },
                    { "source": 0 , "target": 6 , "link_info":"r06" },
                    { "source": 0 , "target": 7 , "link_info":"r87" },
                    { "source": 0 , "target": 8 , "link_info":"r87" }
                ];
    
    var force = d3.layout.force()
          .nodes(nodes)
          .links(links)
          .size([width, height])
          .linkDistance(150)
          .charge(-1400);
    
    var drag = force.drag();
    
    
    init();
    
    function init() {
    
        force.start();  
    
        links_line = svg.selectAll("line")
          .data(links)
          .enter()
          .append("line")
          .style("stroke", "#ac0")
          .style("stroke-width", 1);
    
        node_circles = svg.selectAll("circle")
          .data(nodes)
          .enter()
          .append("circle")
          .style("fill", function(d) {return d.color;})
          .on("dblclick", function(d, i) {
            addNodes(i);                
          })
          .call(drag);
    
        draw();
    }
    
    
    function addNodes(i) {
        for (c=0; c < Math.floor(Math.random() * 20) + 4; c++) {
            nodes.push({"name": "new " + new_id,"size": (Math.floor(Math.random() * 20) + 10),"id": new_id,"color": "#333"})
            links.push({"source": i,"target": new_id,"link_info": "r"+i+new_id});
            new_id++;
        }
    
        // Update force.nodes
        force.nodes(nodes);
    
        // Update force.links
        force.links(links);
    
        // exec init()
        init();         
    }
    
    
    function draw() {
    
        var ticksPerRender = 1;
    
        requestAnimationFrame(function render() {
            force.tick();
            //Update nodes
            node_circles.attr("cx", function(d) {return d.x - d.size / 6;});
            node_circles.attr("cy", function(d) {return d.y - d.size / 6;});
            node_circles.attr("r", function(d) {return d.size});
    
            //Update Location line
            links_line.attr("x1", function(d) {return d.source.x;});
            links_line.attr("y1", function(d) {return d.source.y;});
            links_line.attr("x2", function(d) {return d.target.x;});
            links_line.attr("y2", function(d) {return d.target.y;});
    
            requestAnimationFrame(render)
    
        });
    
    } // draw();
    

1 个答案:

答案 0 :(得分:-1)

更新d3可视化文件遵循输入,更新和退出工作流程(开始阅读herehere)。

请改为尝试:

function init() {

    force.start();  

    links_line = svg.selectAll("line")
      .data(links);

    links_line
      .enter()
      .append("line")
      .style("stroke", "#ac0")
      .style("stroke-width", 1);

    links_line.exit().remove();

    node_circles = svg.selectAll("circle")
        .data(nodes);

    node_circles
        .enter()
        .append("circle")
        .style("fill", function(d) {return d.color;})
        .on("dblclick", function(d, i) {
            addNodes(i);                
        })
        .call(drag);

        draw();
}

更新了example