Новые узлы D3JS Force Layout отключают существующие узлы

Когда я добавляю новые узлы в Force Layout D3, новые узлы игнорируют предыдущие узлы при позиционировании, а предыдущие узлы становятся недоступными для перетаскивания. Я чувствую, что следовал логике:

  1. Добавлять элементы в узлы и ссылки массивов
  2. Обновлены force.nodes(узлы) и force.links(ссылки)
  3. Пробежался через .data().enter() с новыми данными
  4. Вызывается force.start()

Но все равно приводит к отключению предыдущих узлов. Новые узлы можно перетаскивать, и, по-видимому, они учитывают ПОСЛЕДНИЙ НАБОР позиций добавленных узлов и избегают коллизий, все остальные предыдущие узлы по-прежнему доступны для щелчка, но их позиционирование игнорируется и не обновляется.

Вот код в 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();

person AllaPrima    schedule 13.01.2015    source источник


Ответы (1)


Обновление визуализации d3 следует за рабочим процессом входа, обновления и выхода (начните чтение здесь и здесь).

Попробуйте это вместо этого:

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();
}

Обновлен пример.

person Mark    schedule 13.01.2015