在绘制文本之前计算文本的宽度

时间:2015-03-13 11:58:12

标签: d3.js

我希望在其旁边显示rect标签textrect的宽度应该延伸到svg容器的宽度,减去文本的宽度,这是动态的,可以是任何可变长度。

JSFiddle

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计算文本的宽度?或者我如何定位和大小取决于可变长度文本的维度的元素?

3 个答案:

答案 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作为文字,因此您不需要计算文本的开始位置(只是最后传递)