|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
|
|
body { |
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; |
|
margin: auto; |
|
position: relative; |
|
width: 960px; |
|
} |
|
|
|
text { |
|
font: 10px sans-serif; |
|
} |
|
|
|
form { |
|
position: absolute; |
|
right: 10px; |
|
top: 10px; |
|
} |
|
|
|
</style> |
|
<form> |
|
<label><input type="radio" name="dataset" value="apples" checked> Apples</label> |
|
<label><input type="radio" name="dataset" value="oranges"> Oranges</label> |
|
</form> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script> |
|
|
|
var dataset = { |
|
apples: [53245, 28479, 19697, 24037, 40245], |
|
oranges: [200, 200, 200, 200] // previously 5 values, now only 4 |
|
}; |
|
|
|
var width = 960, |
|
height = 500, |
|
radius = Math.min(width, height) / 2; |
|
|
|
var enterAntiClockwise = { |
|
startAngle: Math.PI * 2, |
|
endAngle: Math.PI * 2 |
|
}; |
|
|
|
var color = d3.scale.category20(); |
|
|
|
var pie = d3.layout.pie() |
|
.sort(null); |
|
|
|
var arc = d3.svg.arc() |
|
.innerRadius(radius - 100) |
|
.outerRadius(radius - 20); |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.append("g") |
|
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); |
|
|
|
var path = svg.selectAll("path") |
|
.data(pie(dataset.apples)) |
|
.enter().append("path") |
|
.attr("fill", function(d, i) { return color(i); }) |
|
.attr("d", arc) |
|
.each(function(d) { this._current = d; }); // store the initial values |
|
|
|
d3.selectAll("input").on("change", change); |
|
|
|
var timeout = setTimeout(function() { |
|
d3.select("input[value=\"oranges\"]").property("checked", true).each(change); |
|
}, 2000); |
|
|
|
function change() { |
|
clearTimeout(timeout); |
|
path = path.data(pie(dataset[this.value])); // update the data |
|
// set the start and end angles to Math.PI * 2 so we can transition |
|
// anticlockwise to the actual values later |
|
path.enter().append("path") |
|
.attr("fill", function (d, i) { |
|
return color(i); |
|
}) |
|
.attr("d", arc(enterAntiClockwise)) |
|
.each(function (d) { |
|
this._current = { |
|
data: d.data, |
|
value: d.value, |
|
startAngle: enterAntiClockwise.startAngle, |
|
endAngle: enterAntiClockwise.endAngle |
|
}; |
|
}); // store the initial values |
|
|
|
path.exit() |
|
.transition() |
|
.duration(750) |
|
.attrTween('d', arcTweenOut) |
|
.remove() // now remove the exiting arcs |
|
|
|
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs |
|
} |
|
|
|
// Store the displayed angles in _current. |
|
// Then, interpolate from _current to the new angles. |
|
// During the transition, _current is updated in-place by d3.interpolate. |
|
function arcTween(a) { |
|
var i = d3.interpolate(this._current, a); |
|
this._current = i(0); |
|
return function(t) { |
|
return arc(i(t)); |
|
}; |
|
} |
|
// Interpolate exiting arcs start and end angles to Math.PI * 2 |
|
// so that they 'exit' at the end of the data |
|
function arcTweenOut(a) { |
|
var i = d3.interpolate(this._current, {startAngle: Math.PI * 2, endAngle: Math.PI * 2, value: 0}); |
|
this._current = i(0); |
|
return function (t) { |
|
return arc(i(t)); |
|
}; |
|
} |
|
|
|
</script> |