2016-03-19 3 views
1

Я использую комбинацию AngularJS и D3.js для динамического рисования линейных графиков на основе данных, полученных из API.Как получить размеры элемента D3.js перед его рисованием?

Ниже приведено изображение моей оси y. Как вы можете видеть, у меня есть черная вертикальная линия, представляющая от 0 до 100%. У меня есть 5 меток, обозначенных соответствующими процентами.

enter image description here

Вот код, который генерирует это:

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"); 

    } 

Как вы можете видеть, я жёстко YfontOffset и XfontOffset повторно расположить текст появляться несколько смежно с этими отметками.

Но это не то, что я действительно хочу. Я хочу, чтобы каждая текстовая метка отображалась с одинаковым количеством пикселей слева от связанных меток. И я хочу, чтобы метки были точно горизонтальны в середине текста. Таким образом, атрибуты x и y каждой метки должны вычисляться на основе ограничивающей рамки текста. Как я могу получить размеры этих ограничивающих блоков до того, как текст будет нарисован на холсте, чтобы я мог использовать их в этих атрибутах?

ответ

3

Как я могу получить размеры этих ограничивающих прямоугольников перед текстом рисуется на холсте?

Короче говоря, вы этого не сделаете. Просто измените порядок операций, сделать их, а затем переместить их:

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, спасибо за редактирование! – Mark

0

Пропустить ограничительные рамки в целом и использовать текст якорь

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

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

Но мне нужно изменить Y-позицию текста, а не только X. «text-anchor», похоже, только изменяет положение X. Кроме того, я не просто нуждаюсь в нем в позиции «конец» текста-якоря. Мне нужно сдвинуться дальше налево. –

+0

Чтобы сдвинуться дальше влево, просто сохраните небольшое значение XFontOffset. Для y-позиционирования используйте свойство css 'alignment-baseline', или если оно должно быть для IE, используйте элемент' dy' attr и 'em'. http://stackoverflow.com/questions/12250403/vertical-alignment-of-text-element-in-svg – mgraham

Смежные вопросы