Published
Edited
Apr 29, 2021
Insert cell
Insert cell
Insert cell
style = {
const parsedFont = selectedFont.split(" ").join("+");
return html`
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=${parsedFont}:ital@0;1&display=swap">
<style>
svg {
font-family: ${selectedFont};
font-size: 10px;
}
</style>`;
}
Insert cell
Insert cell
Insert cell
Insert cell
widthsMap = {
style; // Just to trigger computation when style changes (when font changes)

const chars = [];
const widths = [];

// For "!" through "~"...
for (let i = 33; i < 127; i++) {
chars[i] = String.fromCharCode(i);
}

// Create element, measure bounding client rect, put in array
const letter = d3
.select("#calibrate")
.selectAll("text.calibrate")
.data(chars)
.enter()
.append("text")
.classed("calibrate", true)
.text((d) => d)
.each(function (d) {
console.log(d);
const bb = this.getBoundingClientRect();
widths.push(bb.width);
});

// A naked space (charCode 32) doesn't take up any space, so, special case...
const space = d3
.select("#calibrate")
.append("text")
.classed("calibrate", true)
.text("t t")
.each(function (d) {
const bb = this.getBoundingClientRect();
widths[32] = bb.width - 2 * widths["t".charCodeAt(0)];
});

// Clean up after self
d3.select("svg").selectAll("text.calibrate").remove();

// These are from 10px font; normalize to 1px, and return
return widths.map((d) => d / 10);
}
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more