2013-03-22 3 views
7

Ich habe derzeit ein Diagramm, das über jedem Balken Balkenwerte zugeordnet hat, aber ich habe Schwierigkeiten, die Wertelabels zu zentrieren, da ich nicht in der Lage bin, die Breite jedes Textelements abzurufen. DieseWie bekomme ich die Textbreite richtig zu den mittleren Beschriftungen oberhalb der Grafikbalken?

ist, wie mein Graph ist zur Zeit Zeichnung:

enter image description here

Alles, was ich tun muß, ist die Hälfte jeden Textelementes der Breite zu subtrahieren, aber ich kann nicht so mit dem zu tun, scheint folgende Coffee:

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

gibt es eine Möglichkeit, dass ich jede Breite Attribut des Textelement zugreifen kann einen Wert einzustellen ausgleichen?

Antwort

4

Sie können die Bounding Box des Textes abrufen und diese Werte verwenden, um eine Transformation anzuwenden, um sie zu zentrieren. Ein Beispiel für das Abrufen der Bounding Box ist here. Der Code würde so etwas wie

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

funktioniert perfekt . Vielen Dank! – SCS

+0

Soll es bei allen Textelementen gleich funktionieren? Ich versuche derzeit, dasselbe mit meiner y-Achsen-Beschriftung zu erreichen, aber ich bekomme immer eine Breite von 0, obwohl ich ein zurückgegebenes Textelement erhalte. Das ist, was ich bis jetzt habe: http://pastebin.com/VzyT2btq – SCS

+1

Es wird das gleiche für alle Elemente funktionieren, aber Sie müssen '.getBBox()' für jedes Element aufrufen. –

6

aussehen Eine vielleicht einfacher Weg ist, ein text-anchor von middle mit x Satz auf der linken Seite der Bar zu nutzen und die halbe Breite der Bar:

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)