Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
923 views
in Technique[技术] by (71.8m points)

d3.js - Calculate width of text before drawing the text

I want to display a rect with a text label next to it. The width of the rect should stretch to the width of the svg container, less the width of the the text, which is dynamic and can be of any variable length.

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

How do I calculate the width of the text using D3, before it is drawn? Or how do I otherwise position and size elements that depend on the dimensions of variable length text?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...