Skip to content

Instantly share code, notes, and snippets.

@sym3tri
Created March 14, 2014 05:58
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 sym3tri/9542775 to your computer and use it in GitHub Desktop.
Save sym3tri/9542775 to your computer and use it in GitHub Desktop.
arc percent (incomplete)
{"editor_editor":{"coffee":false,"vim":false,"emacs":false,"width":600,"height":300,"hide":false},"description":"arc percent (incomplete)","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"inlet.svg":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/SKuNVhI.png","ajax-caching":true}
var width = 400,
height = 400,
percent = 0.25,
startAngle = 0,
//endAngle = percToRad(98),
tau = 2 * Math.PI,
endAngle = tau, // 100%
color = 'blue';
var arc = d3.svg.arc()
.innerRadius(50)
.outerRadius(80)
.startAngle(0);
var svg = d3.select("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var text = svg.append('text')
.attr('fill', color)
.text(percent * 100)
.attr('x', 0)
.attr('y', 10)
.attr('font-size', '36px')
.attr("text-anchor", "middle");
var arcs = svg.append('g')
.attr("transform", "rotate(180)");
var background = arcs.append("path")
.datum({
endAngle: endAngle
})
.style("fill", "#ccc")
.attr("d", arc);
var foreground = arcs.append("path")
.datum({
endAngle: tau * percent
})
.style("fill", color)
.style("opacity", 0.8)
.attr("d", arc);
function percToRad(perc) {
return degToRad(percToDeg(perc)) / 100;
}
function percToDeg(perc) {
return perc * 360;
}
function degToRad(deg) {
return deg * Math.PI / 180;
}
setInterval(function() {
percent = Math.random();
foreground.transition()
.duration(750)
.call(arcTween, percent * tau);
}, 1500);
function arcTween(transition, newAngle) {
text.text(Math.round(percent * 100));
// The function passed to attrTween is invoked for each selected element when
// the transition starts, and for each element returns the interpolator to use
// over the course of transition. This function is thus responsible for
// determining the starting angle of the transition (which is pulled from the
// element's bound datum, d.endAngle), and the ending angle (simply the
// newAngle argument to the enclosing function).
transition.attrTween("d", function(d) {
// To interpolate between the two angles, we use the default d3.interpolate.
// (Internally, this maps to d3.interpolateNumber, since both of the
// arguments to d3.interpolate are numbers.) The returned function takes a
// single argument t and returns a number between the starting angle and the
// ending angle. When t = 0, it returns d.endAngle; when t = 1, it returns
// newAngle; and for 0 < t < 1 it returns an angle in-between.
var interpolate = d3.interpolate(d.endAngle, newAngle);
// The return value of the attrTween is also a function: the function that
// we want to run for each tick of the transition. Because we used
// attrTween("d"), the return value of this last function will be set to the
// "d" attribute at every tick. (It's also possible to use transition.tween
// to run arbitrary code for every tick, say if you want to set multiple
// attributes from a single function.) The argument t ranges from 0, at the
// start of the transition, to 1, at the end.
return function(t) {
// Calculate the current arc angle based on the transition time, t. Since
// the t for the transition and the t for the interpolate both range from
// 0 to 1, we can pass t directly to the interpolator.
//
// Note that the interpolated angle is written into the element's bound
// data object! This is important: it means that if the transition were
// interrupted, the data bound to the element would still be consistent
// with its appearance. Whenever we start a new arc transition, the
// correct starting angle can be inferred from the data.
d.endAngle = interpolate(t);
// Lastly, compute the arc path given the updated data! In effect, this
// transition uses data-space interpolation: the data is interpolated
// (that is, the end angle) rather than the path string itself.
// Interpolating the angles in polar coordinates, rather than the raw path
// string, produces valid intermediate arcs during the transition.
return arc(d);
};
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment