score:3

Accepted answer

You can get the following result

enter image description here

with this code

var radiusSeparation = 5;

var texts = vis.selectAll("text")
  .data(nodes)
  .enter().append("text")
    .attr("transform", function(d) {
        if (d.depth == 0) return null;
        d.deg = 180 / Math.PI * (d.x0 + d.x1) * 0.5;
        var translate = d.depth == 1 ? Math.sqrt(d.y1)-radiusSeparation : Math.sqrt(d.y0)+radiusSeparation;
        var trans = `rotate(${(d.deg-90).toFixed(2)}) translate(${translate.toFixed(2)},0)`;
        if (d.deg > 180) {
            trans += ` rotate(180)`;
        }
        return trans;
    })
    .text( d => `${d.data.name} (${d.value})` )
    .attr("text-anchor", function(d) {
        if (d.depth == 0) return "middle";
        if (d.depth == 1) return d.deg < 180 ? "end" : "start";
        return d.deg < 180 ? "start" : "end";
    })
    .attr("dominant-baseline", "middle")
  • use the radius of your arcs to position the text. Use a small separation distance so the text does not touch the arcs

  • store the deg value in the datum so you can use it for the text anchor

  • switch text-anchor based on deg value

  • treat depth=0 as special in all cases

  • vertical align the text to the middle with dominant-baseline

  • d3.hierarchy.sum() stores the result in d.value, so use this in the text


Related Query

More Query from same tag