2013-08-08 2 views
0

В настоящее время я использую d3.layout.tree() для вычисления позиций моих данных.Обновление координат в d3js для макета дерева

var tree = d3.layout.tree() 
     .sort(null) 
     .size([size.height, size.width - maxLabelLength * options.fontSize]) 
     .children(function(d) 
     { 
      return (!d.contents || d.contents.length === 0) ? null : d.contents; 
     }); 

Сначала я вычислить и добавить свои узлы, как это:

var nodes = tree.nodes(treeData); 
var nodeGroup = layoutRoot.selectAll("g.node") 
    .data(nodes, function (d) { return d.name }) 
    .enter() 
    .append("svg:g") 
    .attr("class", "node") 
    .attr("transform", function(d) 
     { 
      return "translate(" + d.y + "," + d.x + ")"; 
     }); 
nodeGroup.append("svg:circle") 
    .attr("class", "node-dot") 
    .attr("r", options.nodeRadius); 

Теперь я добавить новый узел в treeData, а также к LayoutRoot:

var grp = layoutRoot.selectAll("g.node") 
    .data(nodes, function (d) { return d.name }) 
    .enter() 
    .append('svg:g') 
    .attr("transform", function (d) 
    { 
     return "translate(" + d.y + "," + d.x + ")"; 
    }) 

grp.append("svg:circle") 
    .attr("class", "node-dot") 
    .attr("r", options.nodeRadius) 

Проблема сейчас , что вновь вычисленные узлы, которые уже присутствуют в корневом каталоге, имеют разные координаты x, y после добавления нового узла. Но они не входят в выбор enter() или exit() и поэтому не перерисовываются в правильном положении. Как это должно быть обработано, т.е. как должно быть обновлено/обновлено положение узлов, которые ничего не изменили, кроме их координат?

I a noob to d3js. Так что не быть слишком жесткими: D

ответ

1

Я бы отделить выбор enter() от обновления узлов, как это:

var nodeGroup = layoutRoot.selectAll("g.node") 
.data(nodes, function (d) { return d.name }); 

// Enter selection 
nodeGroup.enter() 
.append("svg:g") 
.attr("class", "node") 

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

var nodeDots = layoutRoot.selectAll("g.node-dot") 
.data(nodes, function (d) { return d.name }); 

// Enter 
nodeDots.enter() 
.append("circle") 
.attr("class", "node-dot") 

// Update 
nodeDots.attr("r", options.nodeRadius); 

Надеется, что это помогает, но в общем виде речи, это, пожалуй, проще (см. here для получения дополнительной информации)

+1

Переменные «nodeGroup» и «nodeDots» все еще указывают на выбор enter(). Если вам нужен полный выбор обновлений, вам нужно назначить результат данных(), например, nodeGroup, а затем использовать nodeGroup.enter(), чтобы получить выбор входа и nodeGroup, чтобы получить выбор для обновления. –

+0

Да, действительно! Просто отредактировал его, чтобы это выглядело –

Смежные вопросы