2

I'm attempting to modify the D3 sunburst example here (http://bl.ocks.org/mbostock/4063423) to add labels to the arcs.

I've added code to compute the angle and generate the text (taken from this example: http://jsfiddle.net/4PS53/6/) but it's not working. The text just doesn't show up, and when I try to inspect the <text> elements using the inspector, they appear not to be in the DOM.

Any help is much appreciated! The JS code is below (modified from the original D3 gallery example), the JSON data is the same. I'm showing the parts of the code that I modified; the rest is the same.

d3.json("data.json", function(error, root) {
  console.log(root);
  var path = svg.datum(root).selectAll("path")
      .data(partition.nodes)
      .enter().append("path")
      .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
      .attr("d", arc)
      .style("stroke", "#fff")
      .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
      .style("fill-rule", "evenodd")
      .each(stash);

  path.append("text")
        .text(function(d) { return d.name})
        .classed("label", true)
        .attr("x", function(d) { return d.x; })
        .attr("text-anchor", "middle")
        // translate to the desired point and set the rotation
        .attr("transform", function(d) {
            if (d.depth > 0) {
                return "translate(" + arc.centroid(d) + ")" +
                       "rotate(" + getAngle(d) + ")";
            }  else {
                return null;
            }
        })
        .attr("dx", "6") // margin
        .attr("dy", ".35em") // vertical-align
        .attr("pointer-events", "none");

});

function getAngle(d) {
    // Offset the angle by 90 deg since the '0' degree axis for arc is Y axis, while
    // for text it is the X axis.
    var thetaDeg = (180 / Math.PI * (arc.startAngle()(d) + arc.endAngle()(d)) / 2 - 90);
    // If we are rotating the text by more than 90 deg, then "flip" it.
    // This is why "text-anchor", "middle" is important, otherwise, this "flip" would
    // a little harder.
    return (thetaDeg > 90) ? thetaDeg - 180 : thetaDeg;
}
Elisabeth
  • 2,972
  • 6
  • 35
  • 39
  • There's an example for this [here](http://bl.ocks.org/metmajer/5480307) and relevant questions [here](http://stackoverflow.com/questions/13958929/how-to-properly-rotate-text-labels-in-a-d3-sunburst-diagram) and [here](http://stackoverflow.com/questions/22622381/how-to-position-text-labels-on-a-sunburst-chart-with-d3-js). – Lars Kotthoff Apr 27 '15 at 00:32

1 Answers1

4

You need g group element to add text, so you can just change:

var path = svg.datum(root).selectAll("path")
  .data(partition.nodes)
  .enter().append("path")
  .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
  .attr("d", arc)
  .style("stroke", "#fff")
  .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
  .style("fill-rule", "evenodd")
  .each(stash);

to

var path = svg.datum(root).selectAll("path")
  .data(partition.nodes)
  .enter().append("g")

path.append("path")
  .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
  .attr("d", arc)
  .style("stroke", "#fff")
  .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
  .style("fill-rule", "evenodd")
  .each(stash);

Check this jsFiddle: http://jsfiddle.net/5d0zd2s7/

Marek
  • 559
  • 2
  • 15