我希望在其旁边显示rect
标签text
。 rect
的宽度应该延伸到svg容器的宽度,减去文本的宽度,这是动态的,可以是任何可变长度。
var text = 'Foobar';
var textWidth = 50; //how to calculate this?
var plotWidth = 400;
var barWidth = plotWidth-textWidth;
var plot = d3.select(container)
.insert("svg")
.attr('width', plotWidth)
.attr('height', 50);
plot.append("rect")
.style("fill", "steelblue")
.attr("x", 0)
.attr("width", barWidth)
.attr("y", 0)
.attr("height", 50);
plot.append("text")
.attr("x", barWidth)
.attr("y", 28)
.text(text);
在绘制之前,如何使用D3计算文本的宽度?或者我如何定位和大小取决于可变长度文本的维度的元素?
答案 0 :(得分:17)
我在一个复杂的图表中遇到了类似的问题,在元素和文本之间有很多交互,这需要在显示任何元素之前知道文本宽度。
我使用创建一个虚拟文本来抓取它的宽度并立即将其删除。请注意each
中函数的最后一行代码。
var textData = ['a', 'b', 'c'] // your text here
var textWidth = []
svg.append('g')
.selectAll('.dummyText')
.data(textData)
.enter()
.append("text")
.attr("font-family", "sans-serif")
.attr("font-size", "14px")
//.attr("opacity", 0.0) // not really necessary
.text(function(d) { return d})
.each(function(d,i) {
var thisWidth = this.getComputedTextLength()
textWidth.push(thisWidth)
this.remove() // remove them just after displaying them
})
console.log(textWidth) // this array contains the on-screen width of each text element
答案 1 :(得分:13)
I know you asked about D3, but this might be a native solution to your issue.
The HTML5 canvas 2D context has some built-in functionality to measure text. You might be able to tap into that to measure text for other APIs like SVG. If it's not 100% accurate, surely it's proportional to the correct answer.
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 2563/java
tcp 0 0 :::8080 :::* LISTEN 2563/java
答案 2 :(得分:11)
以下是基于使用 getBBox().width
getComputedTextLength()
的工作示例:
修改:由于性能问题,请更新使用getComputedTextLength
的答案(请参阅评论)
http://jsfiddle.net/henbox/jzkj29nv/27/
var text_element = plot.select("text");
var textWidth = text_element.node().getComputedTextLength()
我已经切换到使用text-anchor: end;
CSS作为文字,因此您不需要计算文本的开始位置(只是最后传递)