Skip to content

Instantly share code, notes, and snippets.

@pjsier
Created November 13, 2017 02:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjsier/41f5e06b46e4ed69fd1c27d5ee9cce94 to your computer and use it in GitHub Desktop.
Save pjsier/41f5e06b46e4ed69fd1c27d5ee9cce94 to your computer and use it in GitHub Desktop.
Donut Chart, Text Transition
license: mit
<!DOCTYPE html>
<html>
<head>
<title>Donut Chart, Text Transition</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta charset='utf-8' />
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
#chart {
max-width: 600px;
max-height: 400px;
}
</style>
</head>
<body>
<div id="chart"></div>
<script src="script.js"></script>
<script>
function randNumberBounds(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
var donut = donutChart();
var data = [
{ data: 5000, fill: true },
{ data: 5000, fill: false }
];
function resize() {
if (d3.select("#chart svg").empty()) {
return;
}
donut.width(+d3.select("#chart").style("width").replace(/(px)/g, ""))
.height(+d3.select("#chart").style("height").replace(/(px)/g, ""));
d3.select("#chart").call(donut);
}
document.addEventListener("DOMContentLoaded", function () {
d3.select("#chart").datum(data).call(donut);
d3.select(window).on('resize', resize);
resize();
});
window.setInterval(function() {
var randNum = randNumberBounds(0, 10000);
var emptyNum = 10000 - randNum;
var data = [
{ data: randNum, fill: true},
{ data: emptyNum, fill: false }
];
d3.select("#chart").datum(data).call(donut);
}, 2000);
</script>
</body>
</html>
function donutChart() {
var margin = { top: 10, right: 10, bottom: 40, left: 10 },
width = 400,
height = 400,
donutWidth = 60,
format = d3.format(",d"),
dataValue = function (d) { return +d.data; },
fillValue = function(d) { return d.fill; },
color = "steelblue";
function chart(selection) {
selection.each(function (data) {
data = data.map(function (d, i) {
return { data: dataValue(d), fill: fillValue(d) };
});
var pie = d3.pie()
.value(dataValue)
.sort(null);
var radius = Math.min(width - margin.left - margin.right, height - margin.top - margin.bottom) / 2;
var arc = d3.arc()
.innerRadius(radius - donutWidth)
.outerRadius(radius);
// https://bl.ocks.org/mbostock/1346410
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function (t) {
return arc(i(t));
};
}
var svg = d3.select(this).selectAll("svg").data([data]);
var gEnter = svg.enter().append("svg").append("g");
gEnter.selectAll().data(pie).enter().append("path")
.attr("d", arc)
.each(function (d) { this._current = d; });
var fillData = data.filter(function(d) { return d.fill; });
gEnter.selectAll().data(fillData)
.enter().append("text")
.attr("id", "text-val")
.attr("text-anchor", "middle")
.attr("font-size", "24px")
.attr("x", 0)
.attr("y", 0)
.text(function(d) { return format(d.data); });
var svg = selection.select("svg");
svg.attr('width', width).attr('height', height)
var g = svg.select("g")
.attr("transform", "translate(" +
((width - margin.left - margin.right) / 2) + "," +
((height - margin.top - margin.bottom) / 2) + ")");
var donutPath = g.selectAll("path")
.data(pie)
.attr("fill", function (d) { return d.data.fill ? color : "transparent"; })
.transition()
.duration(1000)
.attrTween("d", arcTween);
d3.select("#text-val")
.transition()
.duration(1000)
.tween("text", function () {
var that = d3.select(this),
i = d3.interpolateNumber(that.text().replace(/,/g, ""), fillData[0].data);
return function (t) { that.text(format(i(t))); };
});
});
}
chart.margin = function (_) {
if (!arguments.length) return margin;
margin = _;
return chart;
};
chart.width = function (_) {
if (!arguments.length) return width;
width = _;
return chart;
};
chart.height = function (_) {
if (!arguments.length) return height;
height = _;
return chart;
};
chart.donutWidth = function (_) {
if (!arguments.length) return donutWidth;
donutWidth = _;
return chart;
};
chart.dataValue = function (_) {
if (!arguments.length) return dataValue;
dataValue = _;
return chart;
};
return chart;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment