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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With