Обновление текстовых меток в D3JS

Я боролся с этой проблемой в течение последних нескольких дней: у меня есть граф, ориентированный на силу, который помечает свои ребра так же, как этот пример делает это. Проблема, с которой я сталкиваюсь, заключается в том, что когда график обновляется (то есть: узел на графике добавляется по щелчку пользователя), он обновляет график, но оставляет старые метки ребер, которые я написал ранее:

ДО И ПОСЛЕ ДОБАВЛЕНИЯ НОВОГО ГРАФИКА: ДОПОСЛЕ

Как видите, мои метки на краях висят после обновления. У меня есть функция, которая вызывается каждый раз, когда приходят новые данные, и в этой функции у меня есть следующий код, рисующий метки:

path_text = svg.selectAll(".path")
.data(force.links(), function(d){ return d.name;})
.enter().append("svg:g");
path_text.append("svg:text")
.attr("class","path-text")
.text(function(d) { return d.data.label; });

Переменная svg объявляется один раз при закрытии верхнего уровня следующим образом:

var svg = d3.select("body").append("svg:svg")
        .attr("viewBox", "0 0 " + width + " " + height)
        .attr("preserveAspectRatio", "xMidYMid meet");

На моем графике есть функция tick(), которая вычисляет расположение каждой метки следующим образом:

function tick()
    {
            // Line label           
            path_text.attr("transform", function(d) 
            {
                var dx = (d.target.x - d.source.x),
                dy = (d.target.y - d.source.y);
                var dr = Math.sqrt(dx * dx + dy * dy);
                var sinus = dy/dr;
                var cosinus = dx/dr;
                var l = d.data.label.length * 6;
                var offset = (1 - (l / dr )) / 2;
                var x=(d.source.x + dx*offset);
                var y=(d.source.y + dy*offset);
                return "translate(" + x + "," + y + ") matrix("+cosinus+", "+sinus+", 

"+-sinus+", "+cosinus+", 0 , 0)";
                });
.
.
.

Я попытался переместить это объявление svg в функцию обновления, чтобы оно создавалось каждый раз при изменении графика. Это действительно работает, но создает полную копию всего графика. Первая, оригинальная копия по-прежнему сохраняет старые ярлыки, но вторая копия действует именно так, как я хочу. Есть ли способ, возможно, вместо добавления svg есть способ замены? Я также безуспешно пытался вызвать exit().remove().

Большое вам спасибо за ваше время. Это убивало меня относительно того, как я должен это делать.


person John Russell    schedule 18.08.2012    source источник
comment
Вы читали руководство Размышление об объединении? Вы связываете выбор enter() непосредственно с объединением данных, поэтому вы игнорируете выбор обновления и выхода. Вам нужно обработать все три состояния, как описано в руководстве.   -  person mbostock    schedule 19.08.2012
comment
bl.ocks.org/MoritzStefaner/1377729   -  person Jordan    schedule 12.05.2015


Ответы (1)


Я поместил объявление svg в свою функцию обновления графа, прикрепил его к div и очистил div, прежде чем добавлять его снова:

jQuery('#v').empty();
var svg = d3.select("#v").append("svg:svg")
.attr("viewBox", "0 0 " + width + " " + height)
.attr("preserveAspectRatio", "xMidYMid meet");

На мой взгляд, не самое чистое решение, но оно подойдет, если у вас всех нет лучшего решения!

person John Russell    schedule 18.08.2012