Question

In the code below the donut chart is animated, so as to start forming from a start
angle and end at an end angle. How do i make the text labels for the donut also animated to flow along with the chart(i.e from the start angle to the end angle)? Currently all the text labels are clustered at the center and then move out to the center of the corresponding arcs.

var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;
var grad=Math.PI/180;

var color = d3.scale.ordinal().range(["#24b4d1", "#b1da42", "#fede17", "#d0164a","#ef5822"]);

var segmentVal=[20,20,20,20,20];
//this is the label i want to flow along with the donut chart
var segments=["1","2","3","4","long one"];
var name="center>>>";

var arc = d3.svg.arc().outerRadius(radius - 5).innerRadius(radius - 150);

var pie=d3.layout.pie().startAngle(-30*grad).endAngle(330*grad);     

var svg = d3.select("body")
         .append("svg")
         .attr("width", width)
         .attr("height", height)
         .append("g")
         .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");



var g = svg.selectAll(".arc")
            .data(pie(SegmentVal))
        .enter().append("g")
        .attr("class", "arc");


 g.append("path")
     .attr("fill", function(d, i) { return color(i); })
     .transition()
     .ease("exp")
     .ease("bounce")
     .duration(2500)
     .delay(function(d,i) { return i*10;})
     .attrTween("d", tweenPie);

function tweenPie(b) 
{
  var i = d3.interpolate({startAngle: -30*grad, endAngle:  -31*grad}, b);
  return function(t) { return arc(i(t)); };
 }

var text=g.append("text")
    .transition()
    .duration(1500)
    .attr("transform",function(d){return "translate("+arc.centroid(d) +")";})
    .text(function(d,i) { return beepSegments[i] })
    .attr("dy",10)
    .attr("text-anchor", "middle");





var holder=svg.selectAll("text")
    .data(name)
    .enter()
        .append("text")
    .attr("x","-350")
    .attr("y","-200")
    .style("text-anchor","middle")
    .text(name);
   holder.transition().attr("y","5");

   holder.transition()
     .delay(500)
     .ease("bounce")
     .duration(1000)
     .attr("x","0")
     .attr("y","5");
Was it helpful?

Solution

You would do this in exactly the same way as you're animating the arcs themselves:

var text=g.append("text")
  .text(function(d,i) { return segments[i] })
  .attr("dy",10)
  .attr("text-anchor", "middle")
  .transition()
  .ease("exp")
  .ease("bounce")
  .duration(2500)
  .delay(function(d,i) { return i*10;})
  .attrTween("transform", tweenText);

function tweenText(b) 
{
  var i = d3.interpolate({startAngle: -30*grad, endAngle:  -31*grad}, b);
  return function(t) { return "translate(" + arc.centroid(i(t)) + ")"; };
}

The only difference is that you're setting the transform and not the d attribute. Complete example here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top