2014-01-23 69 views
2

我在多行中繪製出我的svg文本標籤。我擁有的解決方案正在工作,但是它有一個侷限性,即它不會繪製比我硬編碼更多的行,並且還存在一些低效的處理。有沒有更好的方法來實現這一點,而不必每次重新解析名稱字符串,並將tspan追加到適當的時間?如何做d3.js中的.append循環?

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 append方法):

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

回答

6

看起來像工作爲.each:中.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]) 
     } 
    }); 

一個很大的優勢,如下圖所示,是可以讓你在每個元素範圍的工作,因此很容易避免重複計算是這樣的。

+0

是的,它工作完美。謝謝!順便說一句,你使用偏移和firstPart變量? –

+0

哎呀,對不起,在'.attr'調用之前將它們作爲變量使用。 – nrabinowitz