UNPKG

d3

Version:

A small, free JavaScript library for manipulating documents based on data.

125 lines (110 loc) 2.85 kB
<!DOCTYPE html> <html> <head> <title>Donut Chart</title> <script type="text/javascript" src="../../d3.js"></script> <script type="text/javascript" src="../../d3.layout.js"></script> <style type="text/css"> body { font: 10px sans-serif; } </style> </head> <body> <script type="text/javascript"> var w = 400, h = 400, r1 = Math.min(w, h) / 2, r0 = r1 * .6, n = 10, q = 0, data0 = d3.range(n).map(Math.random), data1 = d3.range(n).map(Math.random), data, color = d3.scale.category20(), arc = d3.svg.arc(), donut = d3.layout.pie(); var vis = d3.select("body") .append("svg:svg") .attr("width", w) .attr("height", h); vis.selectAll("g.arc") .data(arcs(data0, data1)) .enter().append("svg:g") .attr("class", "arc") .attr("transform", "translate(" + r1 + "," + r1 + ")") .append("svg:path") .attr("fill", function(d, i) { return color(i); }) .attr("d", arc); window.addEventListener("keypress", swap, false); function arcs(data0, data1) { var arcs0 = donut(data0), arcs1 = donut(data1), i = -1, arc; while (++i < n) { arc = arcs0[i]; arc.innerRadius = r0; arc.outerRadius = r1; arc.next = arcs1[i]; } return arcs0; } function swap() { d3.selectAll("g.arc > path") .data(++q & 1 ? arcs(data0, data1) : arcs(data1, data0)) .each(transitionSplit); } // 1. Wedges split into two rings. function transitionSplit(d, i) { d3.select(this) .transition().duration(1000) .attrTween("d", tweenArc({ innerRadius: i & 1 ? r0 : (r0 + r1) / 2, outerRadius: i & 1 ? (r0 + r1) / 2 : r1 })) .each("end", transitionRotate); } // 2. Wedges translate to be centered on their final position. function transitionRotate(d, i) { var a0 = d.next.startAngle + d.next.endAngle, a1 = d.startAngle - d.endAngle; d3.select(this) .transition().duration(1000) .attrTween("d", tweenArc({ startAngle: (a0 + a1) / 2, endAngle: (a0 - a1) / 2 })) .each("end", transitionResize); } // 3. Wedges then update their values, changing size. function transitionResize(d, i) { d3.select(this) .transition().duration(1000) .attrTween("d", tweenArc({ startAngle: d.next.startAngle, endAngle: d.next.endAngle })) .each("end", transitionUnite); } // 4. Wedges reunite into a single ring. function transitionUnite(d, i) { d3.select(this) .transition().duration(1000) .attrTween("d", tweenArc({ innerRadius: r0, outerRadius: r1 })); } function tweenArc(b) { return function(a) { var i = d3.interpolate(a, b); for (var key in b) a[key] = b[key]; // update data return function(t) { return arc(i(t)); }; }; } </script> </body> </html>