d3/examples/donut/donut.html

141 строка
3.2 KiB
HTML

<html>
<head>
<title>Donut Chart</title>
<script type="text/javascript" src="../../d3.js"></script>
<style type="text/css">
body {
font: 10px sans-serif;
}
</style>
</head>
<body>
<script type="text/javascript">
var w = 400,
h = 400,
r = Math.min(w, h) / 2,
n = 10,
data = normalize(d3.range(n).map(Math.random)),
color = d3.category20();
var vis = d3.select("body")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
var arcs = vis.selectAll("g.arc")
.data(data)
.enter("svg:g")
.attr("class", "arc")
.attr("transform", "translate(" + r + "," + r + ")");
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", arc);
window.addEventListener("keypress", update, false);
function update() {
var prev = data,
next = data = normalize(d3.range(n).map(Math.random)),
i = 0;
for (; i < n; ++i) prev[i].next = next[i];
d3.selectAll("g.arc > path")
.data(prev)
.each(transitionSplit);
}
// 1. Wedges split into two rings.
function transitionSplit(d, i) {
d3.select(this)
.transition()
.attrTween("d", tweenArc({
innerRadius: i & 1 ? r * .6 : r * .8,
outerRadius: i & 1 ? r * .8 : r
}))
.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()
.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()
.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()
.attrTween("d", tweenArc({
innerRadius: d.next.innerRadius,
outerRadius: d.next.outerRadius
}));
}
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));
};
};
}
function normalize(array) {
var k = (2 * Math.PI) / array.reduce(function(p, d) { return p + d; }, 0),
a = 0;
return array.map(function(d, i) {
return {
innerRadius: r * .6,
outerRadius: r,
startAngle: a,
endAngle: a += d * k
};
});
}
function arc(d) {
var r0 = d.innerRadius,
r1 = d.outerRadius,
a0 = d.startAngle - Math.PI / 2,
a1 = d.endAngle - Math.PI / 2,
da = a1 - a0,
c0 = Math.cos(a0),
s0 = Math.sin(a0),
c1 = Math.cos(a1),
s1 = Math.sin(a1);
return "M" + r1 * c0 + "," + r1 * s0
+ "A" + r1 + "," + r1 + " 0 "
+ ((da < Math.PI) ? "0" : "1") + ",1 "
+ r1 * c1 + "," + r1 * s1
+ "L" + r0 * c1 + "," + r0 * s1
+ "A" + r0 + "," + r0 + " 0 "
+ ((da < Math.PI) ? "0" : "1") + ",0 "
+ r0 * c0 + "," + r0 * s0 + "Z";
}
</script>
</body>
</html>