|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<body> |
|
<svg width="960" height="500"></svg> |
|
<script src="https://d3js.org/d3.v4.min.js"></script> |
|
<script> |
|
var svg = d3.select("svg").append("g"), |
|
width = 960, |
|
height = 500, |
|
r = 150; |
|
|
|
// Chrome rendering issue with arc radii above ~17,000 |
|
var perimeterDifference = d3.scaleLinear() |
|
.range([r * 2 * Math.PI, 8]); |
|
|
|
var radius = d3.scaleSqrt(), |
|
angle = d3.scaleLinear(), |
|
color = d3.scaleOrdinal(d3.schemeCategory20), |
|
partition = d3.partition(); |
|
|
|
var arc = d3.arc() |
|
.startAngle(d => angle(d.x0)) |
|
.endAngle(d => angle(d.x1)) |
|
.innerRadius(d => radius(d.y0)) |
|
.outerRadius(d => radius(d.y1)); |
|
|
|
d3.json("https://gist.githubusercontent.com/mbostock/4348373/raw/85f18ac90409caa5529b32156aa6e71cf985263f/flare.json", function(err, root) { |
|
var hierarchy = d3.hierarchy(root).sum(d => d.size), |
|
data = partition(hierarchy).descendants(); |
|
|
|
svg.selectAll("path") |
|
.data(data) |
|
.enter() |
|
.append("path") |
|
.attr("stroke", "#fff") |
|
.attr("fill", node => color((node.children ? node : node.parent).data.name)) |
|
.call(animate); |
|
}); |
|
|
|
function animate(slices) { |
|
d3.transition() |
|
.delay(1000) |
|
.duration(2000) |
|
.tween("unroll", function(){ |
|
return function(t){ |
|
var diff = perimeterDifference(t), |
|
innerRadius = r * r * 2 * Math.PI / diff - r, |
|
wedgeAngle = diff / r; |
|
|
|
svg.attr("transform", "translate(" + (width / 2) + " " + (height / 2 - innerRadius) + ")") |
|
radius.range([innerRadius, innerRadius + r]); |
|
angle.range([Math.PI + wedgeAngle / 2, Math.PI - wedgeAngle / 2]); |
|
slices.attr("d", arc); |
|
}; |
|
}) |
|
.on("end", function(){ |
|
perimeterDifference.range(perimeterDifference.range().reverse()); |
|
slices.call(animate); |
|
}); |
|
} |
|
</script> |