2013-03-22 15 views
7

Şu anda her çubuğun üstünde görünen ilişkili bar değerlerine sahip bir grafik var, ancak her bir metin öğesinin genişliğini getirememem nedeniyle, değer etiketlerini ortalamakta güçlük çekiyorum. Benim grafik anda çizim nasılGrafik genişliğini grafik çubuklarının üstünde ortalamak için metin genişliği nasıl doğru şekilde alınır?

budur:

enter image description here

yapmam gereken tek şey her metin eleman genişliğinin yarısı çıkarmak, ama birlikte bunu gibi olamaz CoffeeScript aşağıdadır:

#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)) 

Ben dengelemek için bir değer ayarlamak için her metin elementin genişlik özelliğini erişebileceği bir yolu var mı?

cevap

4

Metnin sınırlayıcı kutusunu alabilir ve ortalamak için dönüştürmeyi uygulamak için bu değerleri kullanabilirsiniz. Sınırlama kutusunu elde etmek için bir örnek here'dur. Kod

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

İşleri mükemmel . Teşekkür ederim! – SCS

+0

Tüm metin öğelerinde aynı şekilde çalışması gerekiyor mu? Şu anda y ekseni etiketimle aynı şeyi yapmaya çalışıyorum, ancak döndürülen bir metin öğesi alıyorum bile, 0 genişliğini almaya devam ediyorum. Şimdiye kadar sahip olduğum şey şu: http://pastebin.com/VzyT2btq – SCS

+1

Tüm öğeler için aynı şekilde çalışacak, ancak her öğe için '.getBBox()' ı çağırmalısınız. –

6

bir belki daha basit bir yolu çubuğunun sol tarafına x set ile middle bir text-anchor kullanmaktır artı çubuğun yarısı genişliği gibi görünecektir:

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) 
İlgili konular