Public
Edited
Aug 30, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function wrapAndMinimiseWidth(text, width, dyAdjust, options) {
const NUM_ITERS = 8;
text.each(function () {
const thisText = d3.select(this);
const textString = thisText.text();
wrapOne(thisText, width, dyAdjust, options);
const tspanCount = thisText.selectAll("tspan").size();
let maxTspanWidth = getMaxTspanWidth(thisText);
let lo = width / 5,
hi = width;
for (let i = 0; i < NUM_ITERS; i++) {
thisText.text(textString);
let midpoint = (lo + hi) / 2;
wrapOne(thisText, midpoint, dyAdjust, options);
if (thisText.selectAll("tspan").size() === tspanCount) {
hi = midpoint;
} else {
lo = midpoint;
}
}
thisText.text(textString);
wrapOne(thisText, hi, dyAdjust, options);
});
}
Insert cell
function getMaxTspanWidth(text) {
let maxWidth = 0;
text.selectAll("tspan").each(function () {
let tspan = d3.select(this);
let width = tspan.node().getComputedTextLength();
if (width > maxWidth) maxWidth = width;
});
return maxWidth;
}
Insert cell
function wrap(text, width, dyAdjust, options) {
text.each(function () {
wrapOne(d3.select(this), width, dyAdjust, options);
});
}
Insert cell
function wrapOne(
text,
width,
dyAdjust,
{
lineHeightEms = 1.05,
lineHeightSquishFactor = 1,
splitOnHyphen = true,
centreVertically = true
}
) {
text.each(function () {
var text = d3.select(this),
x = text.attr("x"),
y = text.attr("y");

var words = [];
text
.text()
.split(/\s+/)
.forEach(function (w) {
if (splitOnHyphen) {
var subWords = w.split("-");
for (var i = 0; i < subWords.length - 1; i++)
words.push(subWords[i] + "-");
words.push(subWords[subWords.length - 1] + " ");
} else {
words.push(w + " ");
}
});

text.text(null); // Empty the text element

// `tspan` is the tspan element that is currently being added to
var tspan = text.append("tspan");

var line = ""; // The current value of the line
var prevLine = ""; // The value of the line before the last word (or sub-word) was added
var nWordsInLine = 0; // Number of words in the line
for (var i = 0; i < words.length; i++) {
var word = words[i];
prevLine = line;
line = line + word;
++nWordsInLine;
tspan.text(line.trim());
if (tspan.node().getComputedTextLength() > width && nWordsInLine > 1) {
// The tspan is too long, and it contains more than one word.
// Remove the last word and add it to a new tspan.
tspan.text(prevLine.trim());
prevLine = "";
line = word;
nWordsInLine = 1;
tspan = text.append("tspan").text(word.trim());
}
}

var tspans = text.selectAll("tspan");

var h = lineHeightEms;
// Reduce the line height a bit if there are more than 2 lines.
if (tspans.size() > 2)
for (var i = 0; i < tspans.size(); i++) h *= lineHeightSquishFactor;

tspans.each(function (d, i) {
// Calculate the y offset (dy) for each tspan so that the vertical centre
// of the tspans roughly aligns with the text element's y position.
var dy = i * h + dyAdjust;
if (centreVertically) dy -= ((tspans.size() - 1) * h) / 2;
d3.select(this)
.attr("y", y)
.attr("x", x)
.attr("dy", dy + "em");
});
});
}
Insert cell
alignment = alignmentOptions[0]
Insert cell
Insert cell
Insert cell
x = d3
.scaleLinear()
.domain([-.3, 1.3])
.range([margin.left, width - margin.right])
Insert cell
y = d3
.scaleLinear()
.domain([-0.02, 1.02])
.range([height - margin.bottom, margin.top])
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y))
Insert cell
margin = ({top: 20, right: 30, bottom: 30, left: 40})
Insert cell
height = 1000
Insert cell
d3 = require("d3@6")
Insert cell
chartData = allData
.slice(0, 10)
.concat(allData.filter((d) => d.LAD21NM.length > 20))
Insert cell
allData = FileAttachment("fake_data.csv").csv()
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