I am using a tutorial from Tutorialink Wrapping Text in D3 which along with every other online resource, references Mike Bostock’s “Wrapping Long Labels” example as it seems to be the only way to wrap labels in d3.
This is the result of my wrapping which is not ideal as I want them to be aligned to the centre. Please help as I am a noob in d3, any help would be appreciated!
This is my function wrap, and its implementation is found below it:
function wrap(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(" ").reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 0.7, // ems
x = text.attr("x"),
y = text.attr("y"),
dy = 0, //parseFloat(text.attr("dy")),
tspan = text.text(null)
.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", ++lineNumber * lineHeight + dy + "em")
.text(word);
}
}
});
}
Implementation of the node label on the 5th last line:
let nodeLabel = svg
.selectAll(".nodeLabel")
.data(nodes)
.enter()
.append("text")
.text((d) => {
if (d.label === "Company" && d.properties.name.length > 10)
return d.properties.name.substring(0, 10) + "...";
else if (d.label === "Story" && d.properties.name.length > 20)
return d.properties.name.substring(0, 20) + "...";
else return d.properties.name.substring(0, 10) + "...";
})
.attr("dx", 0)
.attr("dy", "1.8em")
.attr("class", () => "label")
.attr("text-anchor", "middle")
.attr("fill", (f) => {
if (f.label === "Company" || f.label === "Story") return "white";
else return "black";
})
.call(wrap, 30) // wrap the text in <= 30 pixels
.style("font-size", "10px")
.on("mouseover", (d) => {
handleMouseover(d);
});