Public
Edited
Feb 24, 2022
2 forks
Importers
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function wrap(
text,
width,
dyAdjust,
lineHeightEms,
lineHeightSquishFactor,
splitOnHyphen,
centreVertically
) {
// Use default values for the last three parameters if values are not provided.
if (!lineHeightEms) lineHeightEms = 1.05;
if (!lineHeightSquishFactor) lineHeightSquishFactor = 1;
if (splitOnHyphen == null) splitOnHyphen = true;
if (centreVertically == null) 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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more