2013-03-22 11 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)) 

有沒有一種方法,我可以訪問每個文本元素的寬度屬性設置值來抵消?

回答

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 2013-03-22 18:53:00

+0

它應該在所有文本元素上都一樣嗎?我目前正在試圖對我的y軸標籤做同樣的事情,但我仍然得到0的寬度,即使我得到一個返回的文本元素。這是我到目前爲止:http://pastebin.com/VzyT2btq – SCS 2013-03-25 21:05:44

+1

它對所有元素都是一樣的,但你必須爲每個元素調用'.getBBox()'。 – 2013-03-26 08:32:12

6

一個也許更簡單的方法是使用middle一個text-anchorx集酒吧的左側加欄的寬度的一半:

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)