2014-01-23 2 views
2

Я рисую текстовые ярлыки на свой svg в нескольких строках. Решение, которое у меня есть, работает и хорошо, но у него есть ограничение, что он не будет рисовать больше строк, чем то, что я жестко программирую, а также немного неэффективной обработки. Есть ли лучший способ сделать это, не пересматривая строку имени каждый раз и добавляя tspan всего лишь разное количество раз?Как сделать цикл .append в d3.js?

node.append("text") 
.attr("id", function(d){ return "contact-node-label-"+d.id }) 
.style("text-anchor", "middle") 
.attr("dy", function(d) 
{ 
    // split name by space and - 
    var n = d.name.replace("-","- ").split(" ") // this expression is repeated 
    return n.length/3-(n.length-1)*0.9+'em' 
}) 
.text(function(d) 
{ 
    var n = d.name.replace("-","- ").split(" ") 
    // return first part of name 
    return n[0] 
}) 
// some kind of loop would start here 
.append("tspan").attr('x',0).attr('dy','1em').text(function(d) 
{ 
    var n = d.name.replace("-","- ").split(" "); 
    if (n.length > 1) return n[1]; 
}) 
// second round of loop would be this 
.append("tspan").attr('x',0).attr('dy','1em').text(function(d) 
{ 
    var n = d.name.replace("-","- ").split(" "); 
    if (n.length > 2) return n[2]; 
}) 

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

d3.select(this).append("tspan").attr('x',0).attr('dy','1em').text(n[i]) 

ответ

6

выглядит как работа для .each:

node.append("text") 
    .each(function(d) { 
     // split name by space and - 
     var n = d.name.replace("-","- ").split(" "); 
     // get the current element 
     var text = d3.select(this) 
      .attr("dy", n.length/3 - (n.length-1) * 0.9 + 'em') 
      .text(n[0]); 
     // now loop 
     for (var i = 1; i < n.length; i++) { 
      text.append("tspan") 
       .attr('x', 0) 
       .attr('dy', '1em') 
       .text(n[i]) 
     } 
    }); 

Одно большое преимущество .each, как показано здесь, является то, что она дает вам объем за поэлементно для работы, что делает его легким, чтобы избежать повторных вычислений, как это.

+0

Да, это сработало отлично. Благодаря! Кстати, вы используете переменные offset и firstPart? –

+0

Опасайтесь, извините, использовали их как переменные, прежде чем вставлять их в вызовы '.attr'. – nrabinowitz

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