yccteam
yccteam

Reputation: 2311

Centering text inside an arc with d3

Here's my use case: I'm creating a sun burst using d3. Inside each node, I would like to center the text. It doesn't seem to work. I've tried using the method mentioned here: d3js - how to add the text each of the arc's centre, after animation end? But it doesn't seem to work: https://codepen.io/yonatankra/pen/awEYgR?editors=0010

More specifically:

    var text = svg.selectAll(".node").append("text")
.attr("text-anchor","middle")
 .attr("x", function(d) {
    const middleRadius = d.y1 - d.y0;
    arc = d3.arc().innerRadius( middleRadius - 1 ).outerRadius( middleRadius + 1 );
    const x =  arc.centroid(d);

    return x[0]*Math.cos(x[1]);
})
.attr("y", function(d) {
    const middleRadius = d.y1 - d.y0;
    arc = d3.arc().innerRadius( middleRadius - 1 ).outerRadius( middleRadius + 1 );
    const x =  arc.centroid(d);

    return middleRadius*Math.sin(x[1]);
}) 
/* .attr("dy", "-28") */
                    // .attr("dx", "6") // margin
                    // .attr("dy", ".35em") // vertical-align
                        .text(function(d) { 
                        return d.data.name
                })

I've been trying in various ways and have ready multiple guides on how to do this but nothing works as expected.

How would you change the code to enter the text in the center of the arc? And another theoretical question - why does the arc.centroid return the same values for different arcs?

Upvotes: 3

Views: 2118

Answers (1)

Gunner
Gunner

Reputation: 746

var text = svg.selectAll(".node").append("text").attr("transform", function(d){
                let angle = ((d.startAngle + d.endAngle)/2);
                let hyp = (d.depth * 50) + 25;
                let x = Math.sin(angle) * hyp;
                let y = Math.cos(angle) * hyp;
                .attr("text-anchor", "middle")
                .text(function(d) { 
                        return d.data.name
                })

To find the center of the arc, calculate the angle bisector for the arc let angle = ((d.startAngle + d.endAngle)/2);

The hypotenuse will be current depth * 50 50 being the (outer radius - inner radius)/2

Once we have the hypotenuse and the angle then x and y positions can be calculated with pythagoras theorem.

Set text anchor middle to align at the center of the arc.

-y is used instead of y as the graph is going upwards (which is -ve y scale)

Upvotes: 3

Related Questions