Created
February 24, 2012 21:46
-
-
Save scameron/1903969 to your computer and use it in GitHub Desktop.
Animated sparkline in D3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Animated Sparkline</title> | |
<script src="http://bost.ocks.org/mike/d3.v2.min.js"></script> | |
<style type="text/css"> | |
path { | |
stroke: steelblue; | |
stroke-width: 1; | |
fill: none; | |
} | |
circle { | |
fill: red; | |
stroke: white; | |
stroke-width: .75; | |
} | |
button { | |
margin-top: 20px; | |
margin-bottom: 20px; | |
} | |
</style> | |
<script type="text/javascript"> | |
var ballRadius = 2; // need to take radius into account so we don't dip below or above visible area | |
var duration = 10000; | |
var data = [3, 6, 2, 7, 0, 2, 1, 3, 8, 9, 2, 5, 9, 3, 6, 3, 6, 2, 7, 5, 2, 0, 3, 10, 8, 9, 2, 5, 9, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 3, 10, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9]; | |
function refreshData() { | |
d3.range(data.length).forEach(function(d, i) { data[i] = Math.random() * 10; }); | |
} | |
function refreshLine() { | |
d3.selectAll("path") | |
.data([data]) | |
.transition() | |
.duration(duration / 2) | |
.ease("linear") | |
.attr("d", line); | |
} | |
function refresh() { | |
refreshData(); | |
refreshLine(); | |
} | |
</script> | |
</head> | |
<body> | |
<button onclick="refresh();">Refresh</button> | |
<script> | |
var x = d3.scale.linear().domain([0, 1]).range([0, 300 / (data.length - 1)]); | |
var y = d3.scale.linear().domain([0, 10]).range([ballRadius, 20 - ballRadius]); | |
var line = d3.svg.line() | |
.interpolate("linear") | |
.x(function(d,i) { return x(i); }) | |
.y(function(d) { return 20 - y(d); }); | |
var graph = d3.select("body").append("svg") | |
.attr("width", "100%") | |
.attr("height", "100%"); | |
graph.append("clipPath") | |
.attr("id", "clippy") | |
.append("rect"); | |
var path = graph.append("g").attr("clip-path", "url(#clippy)") | |
.selectAll("path") | |
.data([data]) | |
.enter().append("path") | |
.attr("class", "path") | |
.attr("d", line); | |
var y_start = y(data[0]); | |
var circle = graph.append("circle") | |
.attr("class", "circle") | |
.attr("cy", y_start) | |
.attr("r", ballRadius); | |
graph.selectAll("rect").attr("height", 20); | |
var currentX = 0; | |
var transition = graph.transition() | |
.duration(duration) | |
.ease("linear"); | |
transition.selectAll("rect") | |
.attrTween("width", function() { | |
return function(t) { | |
return currentX; | |
}; | |
}); | |
transition.selectAll("circle") | |
.attrTween("transform", function() { | |
return function(t) { | |
return followPath(path.node(), t); | |
}; | |
}) | |
.each("end", function() { this.style.display = "none"; }); | |
function followPath(pathElement, t) { | |
var l = pathElement.getTotalLength(); | |
var p = pathElement.getPointAtLength(t * l); | |
currentX = p.x; | |
return "translate(" + p.x + ", " + (p.y - y_start) + ")"; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Initial line based on hard-coded data. Hit refresh to generate new data and transition vertically.