I think it is a bit easier to follow with the transitions simplified a bit.
For a simpler approach, see the Pie Chart Update series of examples.
I think it is a bit easier to follow with the transitions simplified a bit.
For a simpler approach, see the Pie Chart Update series of examples.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <body> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script> | |
| var width = 960, | |
| height = 500, | |
| outerRadius = Math.min(width, height) * .5 - 10, | |
| innerRadius = outerRadius * .6; | |
| var n = 10, | |
| data0 = d3.range(n).map(Math.random), | |
| data1 = d3.range(n).map(Math.random), | |
| data; | |
| var color = d3.scale.category20(); | |
| var arc = d3.svg.arc(); | |
| var pie = d3.layout.pie() | |
| .sort(d3.descending); | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width) | |
| .attr("height", height); | |
| svg.selectAll(".arc") | |
| .data(arcs(data0, data1)) | |
| .enter().append("g") | |
| .attr("class", "arc") | |
| .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") | |
| .append("path") | |
| .attr("fill", function(d, i) { return color(i); }) | |
| .attr("d", arc); | |
| transition(1); | |
| function arcs(data0, data1) { | |
| var arcs0 = pie(data0), | |
| arcs1 = pie(data1), | |
| i = -1, | |
| arc; | |
| while (++i < n) { | |
| arc = arcs0[i]; | |
| arc.innerRadius = innerRadius; | |
| arc.outerRadius = outerRadius; | |
| arc.next = arcs1[i]; | |
| } | |
| return arcs0; | |
| } | |
| function transition(state) { | |
| var path = d3.selectAll(".arc > path") | |
| .data(state ? arcs(data0, data1) : arcs(data1, data0)); | |
| // Wedges split into two rings. | |
| var t0 = path.transition() | |
| .duration(1000) | |
| .attrTween("d", tweenArc(function(d, i) { | |
| var nextr = d.next.startAngle - d.next.endAngle, | |
| currr = d.startAngle - d.endAngle; | |
| return { | |
| innerRadius: nextr > currr ? innerRadius : (innerRadius + outerRadius) / 2, | |
| outerRadius: nextr > currr ? (innerRadius + outerRadius) / 2 : outerRadius | |
| }; | |
| })); | |
| // Wedges translate to be centered on their final position. | |
| var t1 = t0.transition() | |
| .attrTween("d", tweenArc(function(d, i) { | |
| return { | |
| startAngle: d.next.startAngle, | |
| endAngle: d.next.endAngle | |
| }; | |
| })); | |
| // Wedges then update their values, changing size. | |
| /* | |
| var t2 = t1.transition() | |
| .attrTween("d", tweenArc(function(d, i) { | |
| return { | |
| startAngle: d.next.startAngle, | |
| endAngle: d.next.endAngle | |
| }; | |
| })); | |
| */ | |
| // Wedges reunite into a single ring. | |
| var t3 = t1.transition() | |
| .attrTween("d", tweenArc(function(d, i) { | |
| return { | |
| innerRadius: innerRadius, | |
| outerRadius: outerRadius | |
| }; | |
| })); | |
| setTimeout(function() { transition(!state); }, 5000); | |
| } | |
| function tweenArc(b) { | |
| return function(a, i) { | |
| var d = b.call(this, a, i), i = d3.interpolate(a, d); | |
| for (var k in d) a[k] = d[k]; // update data | |
| return function(t) { return arc(i(t)); }; | |
| }; | |
| } | |
| </script> |