D3.js Force Layout: динамически добавленный узел не перемещается вместе с остальной частью графика

Я работаю над созданием генератора молекул в D3, используя оригинальный пример, созданный Майком Бостоком: http://bl.ocks.org/mbostock/3037015

Я использую силовой макет, как в примере. Моя проблема в том, что когда я динамически добавляю новый узел/атом, он не перемещается вместе с остальной частью графика. Я прочитал другие вопросы и реализовал все, что было предложено, и убедился, что я следую правильной процедуре обновления / присоединения, которую требует D3, и все же добавленный углерод отказывается перемещаться с остальной частью графика.

Вот моя функция обновления/создания:

function buildMolecule () {
    // Update link data
    link = link.data(links);

      // Create new links
    link.enter().append("g")
          .attr("class", "link")
          .each(function(d) {
            d3.select(this)
              .insert("line", ".node")
              .style("stroke-width", function(d) { return (d.bond * 2 - 1) * 2 + "px"; });

            d3.select(this)
              .filter(function(d) { return d.bond > 1; }).append("line")
              .attr("class", "separator");

            d3.select(this)
              .on("click", bondClicked);
    });

    // Delete removed links
    link.exit().remove();    

    // Update node data

    node = node.data(nodes);

    // Create new nodes
    node.enter().append("g")
          .attr("class", "node")
          .on("click", atomClicked)
          .each(function(d) {
            console.log('d:', d);
            // Add node circle
              d3.select(this)
                .append("circle")
                .attr("r", function(d) { return radius(d.size); })
                .style("fill", function(d) { return color(d.atom); });

            // Add atom symbol
              d3.select(this)
                .append("text")
                .attr("dy", ".35em")
                .attr("text-anchor", "middle")
                .text(function(d) { return d.atom; });

                d3.select(this).call(force.drag);
            });

      // Delete removed nodes
    node.exit().remove();

    force.start();
}

JsFiddle: http://jsfiddle.net/2dPMF/1/

Любая помощь будет принята с благодарностью!


person Emil Stolarsky    schedule 13.12.2013    source источник


Ответы (1)


Вы изменяете структуры данных узлов и ссылок, помимо добавления и удаления узлов, что портит силовой макет. Я говорю именно об этих строках.

function bigBang () {
    links = links.concat(linksList);
    nodes = nodes.concat(nodesList);
    buildMolecule();
  }

Я говорю о первых двух строках этой функции. Рабочий jsfiddle здесь.

person Lars Kotthoff    schedule 13.12.2013
comment
Не могу поверить, что пропустил это, большое спасибо! :D - person Emil Stolarsky; 14.12.2013