Reputation: 55
I've searched the current topics in this site, but no solution solved my problem.
How can I show text in two line for long length texts in D3 circle packing. I'm using following code to show labels on circles:
const label = svg.append("g")
.style("font-weight", "bold")
.attr("pointer-events", "none")
.attr("text-anchor", "middle")
.selectAll("text")
.data(root.descendants())
.join("text")
.style("fill-opacity", d => d.parent === root ? 1 : 0)
.style("text-shadow", "0px 0px 11px #FFF")
.style("display", d => d.parent === root ? "inline" : "none")
.attr("dy", "0.3em")
.text(d => d.data.name);
Upvotes: 0
Views: 585
Reputation: 3142
SVG does not have a built in wrap text option to automatically split lines for long texts. There is a wrap function described here https://bl.ocks.org/mbostock/7555321 by Mike Bostock which splits the text into appropriate lines when you provide the text
and the width
attributes.
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).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", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
You can invoke it by calling it on the selection using selectAll(".textclass").call(wrap,textwidth)
where textclass
is the class of the text you want to wrap and textwidth
is the width of the text allowed.
Upvotes: 1