2013-03-22 3 views
7

私は現在、それぞれのバーの上にバー値が表示されているグラフを持っていますが、各テキスト要素の幅をフェッチすることができないため、値ラベルを中央に配置するのが困難です。グラフバーの上にラベルを中央に配置するには、テキスト幅を正しく取得するにはどうすればよいですか?

これは私のグラフは、現時点で描画される方法である:私がする必要があるのは、各テキスト要素の幅の半分を減算することですが、私がそうするように見えることはできません

enter image description here

Coffeescriptに続く:

#Drawing value labels 
    svg.selectAll("rect") 
     .data(data) 
     .enter() 
     .append("text") 
     .text((d)-> d.Total) 
     .attr("width", x.rangeBand()) 
     .attr("x", (d)-> 
      textWidth = d3.selectAll("text").attr("width") 

      x(d.Year) + (x.rangeBand()/2) - (textWidth/2) 
     ) 
     .attr("y", (d)-> y(d.Total) - 5) 
     .attr("font-size", "10px") 
     .attr("font-family", "sans-serif") 

    #Drawing bars  
    svg.selectAll("rect") 
     .data(data) 
     .enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", (d)-> x(d.Year)) 
     .attr("width", x.rangeBand()) 
     .attr("y", (d)-> y(d.Total)) 
     .attr("height", (d)-> height - y(d.Total)) 

各テキスト要素のwidth属性にアクセスして値をオフセットに設定する方法はありますか?

答えて

4

テキストの境界ボックスを取得し、その値を使用してトランスフォームを適用して中央に配置することができます。境界ボックスを取得する例はhereです。コードは

.text(function(d) { return d.Total; }) 
.attr("x", function(d) { 
    return x(d.Year) + (x.rangeBand()/2) - (this.getBBox().width/2); 
} 
... 
+0

作品完璧。ありがとうございました! – SCS

+0

すべてのテキスト要素で同じことをする必要がありますか?私は現在、私のy軸ラベルで同じことをしようとしていますが、返されたテキスト要素を取得していても、幅は0です。これは私が今まで持っているものです:http://pastebin.com/VzyT2btq – SCS

+1

これはすべての要素で同じように動作しますが、各要素に対して '.getBBox()'を呼び出さなければなりません。 –

6

おそらく簡単な方法は、バーの左側にxセットでmiddletext-anchorを使用することでプラスバーの幅の半分のようになります。

svg.selectAll(".bar-label") 
    .data(data) 
.enter().append("text") 
    .text((d)-> d.Total) 
    .attr("class", "bar-label") 
    .attr("text-anchor", "middle") 
    .attr("x", (d)-> x(d.Year) + x.rangeBand()/2) 
    .attr("y", (d)-> y(d.Total) - 5) 
関連する問題