Skip to content

Instantly share code, notes, and snippets.

@cool-Blue
Last active March 31, 2018 08:21
Show Gist options
  • Save cool-Blue/e6e2e04bd55a1d2904c2 to your computer and use it in GitHub Desktop.
Save cool-Blue/e6e2e04bd55a1d2904c2 to your computer and use it in GitHub Desktop.
dynamic pie chart with proper label orientation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>http://stackoverflow.com/questions/32510101/d3-why-is-enter-selection-not-showing-any-transition-for-a-donut-chart?noredirect=1#comment52896340_32510101</title>
<style>
.chart text {
font: 16px sans-serif;
}
.chart {
position: relative;
/* top: 2em;*/
}
</style>
</head>
<body>
<svg class="chart"></svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="https://gitcdn.xyz/repo/cool-Blue/d3-lib/master/transitions/end-all/endAll.js"></script>
<script>
var crm = (function() {
var prevData = [];
return function crm(f) {
var max = 10000;
oldPieData = JSON.parse(JSON.stringify(prevData));
prevData = f([
{name: 'SMR', value: Math.random() * max},
{name: 'PSF', value: Math.random() * max},
{name: 'Insurance', value: Math.random() * max},
{name: 'Other', value: Math.random() * max}
])
}
})();
pieTween = function(d, i) {
var s0;
var e0;
if(oldPieData[i]){
s0 = oldPieData[i].startAngle;
e0 = oldPieData[i].endAngle;
} else if (!(oldPieData[i]) && oldPieData[i-1]) {
s0 = oldPieData[i-1].endAngle;
e0 = oldPieData[i-1].endAngle;
} else if(!(oldPieData[i-1]) && oldPieData.length > 0){
s0 = oldPieData[oldPieData.length-1].endAngle;
e0 = oldPieData[oldPieData.length-1].endAngle;
} else {
s0 = 0;
e0 = 0;
}
var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});
return function(t) {
var b = i(t);
return arc(b);
};
};
var pie = Math.PI * 2;
var w = 960,
h = 500;
var duration = 750;
var chart = d3.select('.chart')
.attr('width', w)
.attr('height',h)
.append('g')
.attr('transform', 'translate('+w/2+','+ h/2 + ')'),
pieChart = d3.layout.pie()
.value(function(d){ return d.value; })
.sort(null),
oldPieData = [],
groups = chart.append ("g")
.attr("class", "groups"),
// group at the center of donut
center_group = chart.append('g')
.attr("class", "center_group")
.append('text')
.attr({'text-anchor': 'middle', dy: "0.35em"});
createPieChart = function(data){
var radius = 200, innerRadius = radius - 100;
var pieData,
color = d3.scale.ordinal()
.range(['#469AB2', '#F0AD4E', '#5CB85C', '#D9534F'])
.domain(data.map(function(d){return d.name}));
// displaying total calls at the center
center_group.text(d3.format(",.1f")(d3.sum(data, function(d){return d.value})));
arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(radius);
var arcs = groups.selectAll('path')
.data((pieData = pieChart(data)), function(d){return d.data.name});
arcs.enter().append('path')
.attr('class', 'arc');
arcs.attr('fill', function(d){ return color(d.data.name)})
.transition()
.duration(duration)
.attrTween("d", pieTween)
.ease("bounce");
function computeTextRotation(d) {
var rotation = (d.startAngle + d.endAngle)/2 * 180 / Math.PI - 90;
return {
global: rotation,
correction: rotation > 90 ? 180 : 0
};
}
var labels = groups.selectAll("text")
.data(pieData);
labels.enter().append("text")
.attr({"text-anchor": "middle"})
.text(function(d) {
return d.data.name
})
.attr("dy", ".35em") // vertical-align
.style("font-size", 14);
labels
.transition()
.duration(duration)
.attr("transform", function(d) {
var r = computeTextRotation(d);
return "rotate(" + r.global + ")" + "translate(" + (radius + innerRadius) / 2 + ",0)" + "rotate(" + -r.correction + ")";
})
.call(endAll, function(){
window.requestAnimationFrame(
function(){crm(createPieChart)}
)
});
return pieData;
};
crm(createPieChart);
// window.setInterval(function(){crm(createPieChart)}, duration + 0)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment