2016-03-19 6 views
1

Ich verwende eine Kombination aus AngularJS und D3.js, um dynamisch Liniendiagramme basierend auf Daten aus einer API zu zeichnen.Wie erhält man die Abmessungen eines D3.js-Elements, bevor es gezeichnet wird?

Unten ist ein Bild von meiner Y-Achse. Wie Sie sehen können, habe ich eine schwarze vertikale Linie gezeichnet, die 0 bis 100% darstellt. Ich habe 5 Häkchen mit den entsprechenden Prozentsätzen markiert.

enter image description here

Hier ist der Code, der dies erzeugt:

var yScaleIntervals = 4; 
    var yMaxlabel = 100; 
    for (var i = 0; i <= yScaleIntervals; i++) { 
     var tickY = self.yBottom - (self.yPixSpan * (i/yScaleIntervals)); 
     var tickLabel = ((100 * i)/yScaleIntervals).toString() + '%'; 
     console.log("tickY = ", tickY); 
     self.svgContainer.append("line") 
     .attr("x1", self.yScaleX - 2) 
     .attr("y1", tickY) 
     .attr("x2", self.yScaleX) 
     .attr("y2", tickY) 
     .attr("stroke-width", 1) 
     .attr("stroke", "black"); 

     var YfontOffset = 30; 
     var XfontOffset = 4; 
     var label = self.svgContainer.append("text") 
     .attr("x", yScaleX - YfontOffset) 
     .attr("y", tickY + XfontOffset) 
     .text(tickLabel) 
     .attr("font-family", "Courier New") 
     .attr("font-weight", "bold") 
     .attr("font-size", "10px"); 
     .attr("fill", "black"); 

    } 

Wie Sie YfontOffset und XfontOffset neu zu positionieren, den Text zu erscheinen etwas neben diesen Strichmarkierungen fest einprogrammiert sehen können, habe ich.

Aber das ist nicht das, was ich wirklich will. Ich möchte, dass jedes Textlabel links neben den zugehörigen Teilstrichen die gleiche Anzahl von Pixeln anzeigt. Und ich möchte, dass die Teilstriche genau in der Mitte des Textes stehen. Daher müssen die Attribute x und y jedes Etiketts basierend auf der Bounding Box des Texts berechnet werden. Wie kann ich die Abmessungen dieser Begrenzungsrahmen erhalten, bevor der Text auf der Leinwand gezeichnet wird, damit ich sie in diesen Attributen verwenden kann?

Antwort

3

Wie kann ich die Abmessungen dieser Begrenzungsrahmen erhalten, bevor der Text auf der Zeichenfläche gezeichnet wird?

Kurz gesagt, Sie nicht. Ändern Sie einfach Ihre Bestellung von Operationen, sie ziehen und sie dann bewegen:

var YfontOffset = 30; 
    var XfontOffset = 4; 
    var label = self.svgContainer.append("text") 
    .text(tickLabel) 
    .attr("font-family", "Courier New") 
    .attr("font-weight", "bold") 
    .attr("font-size", "10px"); 
    .attr("fill", "black") 
    // using translate, so I can set the 
    // x/y in one attr call 
    .attr("transform", function(d){ 
     var bb = this.getBBox(); 
     return "translate(" + fancyCalcX() + "," + fancyCalcY() + ")"; 
    }); 
+0

@saqibali, danke für die Bearbeitung! – Mark

0

überspringen Begrenzungsboxen zusammen und verwenden, um Text-Anker

https://developer.mozilla.org/en/docs/Web/SVG/Attribute/text-anchor

.style("text-anchor", "end"); 
+0

Aber ich muss die Y-Position des Textes ändern, nicht nur die X. "Text-Anker" scheint nur die X-Positionierung zu ändern. Außerdem brauche ich es nicht nur an der Textankerposition "Ende". Ich muss weiter nach links verschoben werden. –

+0

Um weiter nach links verschoben zu werden, behalten Sie einfach Ihren kleinen XFontOffset-Wert bei. Verwenden Sie für die Y-Positionierung die css-Eigenschaft 'alignment-baseline' oder, wenn es auch für den IE sein soll, die' dy'attr- und eine 'em'-Unit. http://stackoverflow.com/questions/12250403/vertical-alignment-of-text-element-in-svg – mgraham

Verwandte Themen