var demo function startDemo() { var samples = [ 'Hello world', 'No DOM measurements in this demo', 'The quick brown hare trailed the tortoise in the limit', 'I am at the office eating a bagel', 'Toph', 'Notice the kerning-induced error above', 'That\'s my given name to myself by myself, see I see movies', 'ASCII only :(', 'The moré ‘Unicöde’ the worse the åpprøxîmátioñ' ] var g = d3.select('#demo') .selectAll('g') .data(samples) var gEnter = g.enter() .append('g') .each(function(str) { var g = d3.select(this) g.append('text') .classed('str', true) .text(str) g.append('line') .attr('marker-end', 'url(#mark)') .attr('marker-start', 'url(#mark)') g.append('text') .classed('px', true) .attr('dx', 5) .attr('dy', 3.5) }) g = g.merge(gEnter) .attr('transform', (d,i) => `translate(30,${i * 50 + 50})`) render() clearInterval(demo) demo = setInterval(render, 750) function render() { g.each(function(str) { var randomSize = Math.random() * 40 + 10 var measure = measureText(str, randomSize) var g = d3.select(this) g.select("text.str") .style('font-size', `${randomSize}px`) g.select('line') .attr('y1', -randomSize/3) .attr('y2', -randomSize/3) .attr('x2', measure) g.select("text.px") .attr('x', measure) .attr('y', -randomSize/3) .text(`${measure.toFixed(0)}px`) }) } } function stopDemo() { clearInterval(demo) }