I am trying to create a pie chart and found these two examples here https://bl.ocks.org/mbostock/7555321 and this one https://jsfiddle.net/05nezv4q/20/ which adds some text. However, I am using typescript and D3 v7.6.1 and text wrapping does not work. And another problem is that I am using arrow function in my react app and I don't know how to reference this in an arrow function: d3.select(this)
Can anyone help me with these two points: how to reference this in an arrow function, and two how to convert the wrap function below to work in typescript and d3 v7.6.1?
Thank you and please keep in mind as I am new to programming.
d3.selectAll("svg").append("text")
.text("This is a circle with some text in it.")
.attr("x", 20)
.attr("y", 20).call(wrap, 100);
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);
}
}
});
}
tried to find a solution or some explanation that will point me in the right direction, but did not find one as all of the examples referred to older version of the library.
CodePudding user response:
In the example https://bl.ocks.org/mbostock/7555321, The text elements are created by an axis generator, which set a dy attribute on these elements before calling the wrap
function. In your fiddle, the dy attribute is not set so parseFloat(text.attr("dy"))
returns NaN.
Add an dy attribute on your text element or add a default value when you parse it for example parseFloat(text.attr("dy" || "0")
Concerning the arrow functions in your react app, if you need to keep them then you can use the parameters of the function that d3 provides when calling selection.each()
:
select.each((d, i, nodes) => {
var text = d3.select(nodes[i]);
}
Take a look at the documentation here: https://github.com/d3/d3-selection
nodes[i] is the current DOM element, equivalent to this in a non-arrow function.