21

I have a donut chart with five different arcs inside of it. The data will not be updated but I want to have a transition of the whole graph being drawn as a circle when the page loads, starting at the selected angle (in my case 1.1*PI). Here is the jsfiddle of the graph: http://jsfiddle.net/Nw62g/

var data = [
    {name: "one", value: 10375},
    {name: "two", value:  7615},
    {name: "three", value:  832},
    {name: "four", value:  516},
    {name: "five", value:  491}
];

var margin = {top: 20, right: 20, bottom: 20, left: 20};
    width = 400 - margin.left - margin.right;
    height = width - margin.top - margin.bottom;

var chart = d3.select("body")
    .append('svg')
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", "translate(" + ((width/2)+margin.left) + "," +
                                      ((height/2)+margin.top) + ")");

var radius = Math.min(width, height) / 2;

var color = d3.scale.ordinal()
    .range(["#3399FF", "#5DAEF8", "#86C3FA", "#ADD6FB", "#D6EBFD"]);

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

var pie = d3.layout.pie()
    .sort(null)
    .startAngle(1.1*Math.PI)
    .endAngle(3.1*Math.PI)
    .value(function(d) { return d.value; });

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

g.append("path")
    .style("fill", function(d) { return color(d.data.name); })
    .attr("d", arc);

How would I go about achieving this result?

VividD
  • 10,456
  • 6
  • 64
  • 111
KobeBryant
  • 1,341
  • 3
  • 10
  • 13

1 Answers1

32

You can do this with an attribute tween:

.attrTween('d', function(d) {
   var i = d3.interpolate(d.startAngle+0.1, d.endAngle);
   return function(t) {
       d.endAngle = i(t);
     return arc(d);
   }
});

This animates the segment from start to end angle. To do this across the entire circle, you can use delayed transitions:

.transition().delay(function(d, i) { return i * 500; }).duration(500)

Complete example here. You can adjust start segment, duration, etc to your liking.

Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • 6
    Thanks for the answer! After trying your way I came by another solution that is more of what I was looking for, but your example definitely helped! Here's my final code:http://jsfiddle.net/Nw62g/3/ – KobeBryant Dec 10 '13 at 19:51
  • Oh I see what you were looking for now. Glad it helped anyway. – Lars Kotthoff Dec 10 '13 at 19:54
  • @LarsKotthoff if you wanted to change the direction of the animation, how would you do that? – thetallweeks Dec 17 '14 at 21:17
  • 1
    The easiest is probably to simply reverse the [easing](https://github.com/mbostock/d3/wiki/Transitions#d3_ease) (`out-in`). – Lars Kotthoff Dec 18 '14 at 10:27