Skip to content

Instantly share code, notes, and snippets.

@lorenzopub
Created November 1, 2018 13:51
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 lorenzopub/f9d9a611518d3fc708082faddfe0e35c to your computer and use it in GitHub Desktop.
Save lorenzopub/f9d9a611518d3fc708082faddfe0e35c to your computer and use it in GitHub Desktop.
Arc Tween Percent Rings
license: gpl-3.0
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
text {
font-family: Georgia, Arial, sans-serif;
font-size: 25px;
fill: black;
}
.gold {
fill: gold;
}
.blue {
fill: blue;
}
.red {
fill: red;
}
</style>
<script src="https://d3js.org/d3.v5.min.js">
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
<script>
var width = 500,
height = 300,
τ = 2 * Math.PI; // http://tauday.com/tau-manifesto
// An arc function with all values bound except the endAngle. So, to compute an
// SVG path string for a given angle, we pass an object with an endAngle
// property to the `arc` function, and it will return the corresponding string.
var arc = d3.arc()
.innerRadius(40)
.outerRadius(45)
.startAngle(0);
// Create the SVG container, and apply a transform such that the origin is the
// center of the canvas. This way, we don't need to position arcs individually.
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var rings = [{id:"gold", percent: 80},
{id:"red", percent: 40},
{id:"blue", percent: 10}];
var d3Rings = [];
var convertPercentToAngle = (percent) => { return ( percent / 100 ) * τ };
var createRings = function(){
rings.map(function(ring,index){
var d3Ring = svg
.append("g")
.attr("transform", "translate(" + width / 2 + "," + ( ( 100 * index ) + 50 ) + ")")
.attr("id",ring.id);
// background
d3Ring
.append("path")
.datum({endAngle: τ})
.style("fill", "#ddd")
.attr("d", arc);
// foreground
var foreground = d3Ring
.append("path")
.datum({endAngle: 0})
.style("fill", ring.id)
.style("stroke", "none")
.style("stroke-width", "0px")
.style("opacity", 1)
.attr("d", arc);
// text
d3Ring
.append("text")
.attr("x", -22)
.attr("y", 8)
.text(ring.percent + "%")
.attr("class", ring.id);
var angle = convertPercentToAngle(ring.percent);
foreground
.transition()
.duration(1500)
.delay(500 * index)
.call(arcTween, angle);
d3Rings.push(d3Ring);
});
}
createRings();
function arcTween(transition, newAngle) {
transition.attrTween("d", function(d) {
var interpolate = d3.interpolate(d.endAngle, newAngle);
return function(t) {
d.endAngle = interpolate(t);
return arc(d);
};
});
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment