2013-03-22 41 views
7

Tôi hiện có biểu đồ có giá trị thanh được liên kết hiển thị phía trên mỗi thanh, nhưng tôi gặp khó khăn khi căn giữa nhãn giá trị, do không thể tìm nạp chiều rộng của từng phần tử văn bản.Làm thế nào để có được chiều rộng văn bản chính xác đến các nhãn trung tâm phía trên các thanh đồ thị?

Đây là cách biểu đồ của tôi được vẽ vào lúc này:

enter image description here

Tất cả tôi cần làm là trừ một nửa chiều rộng mỗi yếu tố văn bản, nhưng tôi dường như không thể làm như vậy với sau 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)) 

Có cách nào để tôi có thể truy nhập thuộc tính chiều rộng của từng phần tử văn bản để đặt giá trị để bù không?

Trả lời

4

Bạn có thể nhận được hộp giới hạn của văn bản và sử dụng các giá trị đó để áp dụng biến đổi để căn giữa nó. Ví dụ để nhận được hộp giới hạn là here. Mã này sẽ giống như

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

trình hoàn hảo . Cảm ơn bạn! – SCS

+0

Ứng dụng có hoạt động giống nhau trên tất cả các yếu tố văn bản không? Tôi hiện đang cố gắng làm tương tự với nhãn trục y của tôi, nhưng tôi tiếp tục nhận được chiều rộng là 0, mặc dù tôi nhận được phần tử văn bản trả về. Đây là những gì tôi có cho đến nay: http://pastebin.com/VzyT2btq – SCS

+1

Nó sẽ làm việc tương tự cho tất cả các phần tử, nhưng bạn phải gọi '.getBBox()' cho mỗi phần tử. –

6

Một cách có lẽ đơn giản hơn là sử dụng một text-anchor của middle với x bộ về phía bên trái của thanh cộng với một nửa chiều rộng của thanh:

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)