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

mtm*_*ald 26 d3.js

我想显示一个recttext它旁边的标签.的宽度rect应该伸展到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);
Run Code Online (Sandbox Code Playgroud)

在绘制之前,如何使用D3计算文本的宽度?或者我如何定位和大小取决于可变长度文本的维度的元素?

Pyt*_*nic 18

我在复杂的图表中遇到了类似的问题,在元素和文本之间有很多交互,这需要显示任何元素之前知道文本宽度.

我使用创建一个虚拟文本来抓住它的宽度并立即将其删除.注意函数的最后一行代码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
Run Code Online (Sandbox Code Playgroud)


TxR*_*gex 15

我知道你问过D3,但这可能是你问题的原生解决方案.

HTML5画布2D上下文具有一些用于测量文本的内置功能.您可以利用它来测量SVG等其他API的文本.如果它不是100%准确,那么肯定它与正确的答案成正比.

var BrowserText = (function () {
    var canvas = document.createElement('canvas'),
        context = canvas.getContext('2d');

    /**
     * Measures the rendered width of arbitrary text given the font size and font face
     * @param {string} text The text to measure
     * @param {number} fontSize The font size in pixels
     * @param {string} fontFace The font face ("Arial", "Helvetica", etc.)
     * @returns {number} The width of the text
     **/
    function getWidth(text, fontSize, fontFace) {
        context.font = fontSize + 'px ' + fontFace;
        return context.measureText(text).width;
    }

    return {
        getWidth: getWidth
    };
})();

// Then call it like this:
console.log(BrowserText.getWidth('hello world', 22, 'Arial')); // 105.166015625
console.log(BrowserText.getWidth('hello world', 22)); // 100.8154296875
Run Code Online (Sandbox Code Playgroud)


Hen*_*y S 10

这是一个基于使用的工作示例:getBBox().width getComputedTextLength()

编辑:getComputedTextLength由于性能问题更新要使用的答案(请参阅注释)

http://jsfiddle.net/henbox/jzkj29nv/27/

var text_element = plot.select("text");
var textWidth = text_element.node().getComputedTextLength()
Run Code Online (Sandbox Code Playgroud)

我也转而使用text-anchor: end;CSS作为文本,所以你不需要计算文本的开始位置(只是传递到最后)

  • 值得注意的是getBBox()强制在浏览器中传递渲染,因此如果反复执行会导致可怕的性能问题. (2认同)