Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Animated Line Graphs / Sparklines using SVG Path and d3.js
<html>
<head>
<title>Animated Sparkline using SVG Path and d3.js</title>
<script src="http://mbostock.github.com/d3/d3.v2.js"></script>
<style>
/* tell the SVG path to be a thin blue line without any area fill */
path {
stroke: steelblue;
stroke-width: 1;
fill: none;
}
</style>
</head>
<body>
<p>
<b>Size:</b> 300x30 &nbsp;&nbsp;<b>Interpolation:</b> basis &nbsp;&nbsp;<b>Animation:</b> true &nbsp;&nbsp;<b>Transition:</b> 1000ms &nbsp;&nbsp;<b>Update Frequency:</b> 1000ms
<div id="graph1" class="aGraph" style="width:300px; height:30px;"></div>
</p>
<p>
<b>Size:</b> 150x15 &nbsp;&nbsp;<b>Interpolation:</b> basis &nbsp;&nbsp;<b>Animation:</b> true &nbsp;&nbsp;<b>Transition:</b> 1000ms &nbsp;&nbsp;<b>Update Frequency:</b> 1000ms
<div id="graph2" class="aGraph" style="width:150px; height:15px;"></div>
</p>
<p>
<b>Size:</b> 150x15 &nbsp;&nbsp;<b>Interpolation:</b> linear &nbsp;&nbsp;<b>Animation:</b> true &nbsp;&nbsp;<b>Transition:</b> 1000ms &nbsp;&nbsp;<b>Update Frequency:</b> 1000ms
<div id="graph3" class="aGraph" style="width:150px; height:15px;"></div>
</p>
<p>
<b>Size:</b> 150x15 &nbsp;&nbsp;<b>Interpolation:</b> linear &nbsp;&nbsp;<b>Animation:</b> false &nbsp;&nbsp;<b>Transition:</b> 1000ms &nbsp;&nbsp;<b>Update Frequency:</b> 1000ms
<div id="graph4" class="aGraph" style="width:150px; height:15px;"></div>
</p>
<p>
<b>Size:</b> 300x30 &nbsp;&nbsp;<b>Interpolation:</b> basis &nbsp;&nbsp;<b>Animation:</b> true &nbsp;&nbsp;<b>Transition:</b> 750ms &nbsp;&nbsp;<b>Update Frequency:</b> 1500ms
<div id="graph5" class="aGraph" style="width:300px; height:30px;"></div>
</p>
<p>
<b>Size:</b> 300x30 &nbsp;&nbsp;<b>Interpolation:</b> basis &nbsp;&nbsp;<b>Animation:</b> false &nbsp;&nbsp;<b>Transition:</b> 750ms &nbsp;&nbsp;<b>Update Frequency:</b> 1500ms
<div id="graph6" class="aGraph" style="width:300px; height:30px;"></div>
</p>
<script>
function displayGraphExample(id, width, height, interpolation, animate, updateDelay, transitionDelay) {
// create an SVG element inside the #graph div that fills 100% of the div
var graph = d3.select(id).append("svg:svg").attr("width", "100%").attr("height", "100%");
// create a simple data array that we'll plot with a line (this array represents only the Y values, X will just be the index location)
var data = [3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 3, 6, 3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 9];
// X scale will fit values from 0-10 within pixels 0-100
var x = d3.scale.linear().domain([0, 48]).range([-5, width]); // starting point is -5 so the first value doesn't show and slides off the edge as part of the transition
// Y scale will fit values from 0-10 within pixels 0-100
var y = d3.scale.linear().domain([0, 10]).range([0, height]);
// create a line object that represents the SVN line we're creating
var line = d3.svg.line()
// assign the X function to plot our line as we wish
.x(function(d,i) {
// verbose logging to show what's actually being done
//console.log('Plotting X value for data point: ' + d + ' using index: ' + i + ' to be at: ' + x(i) + ' using our xScale.');
// return the X coordinate where we want to plot this datapoint
return x(i);
})
.y(function(d) {
// verbose logging to show what's actually being done
//console.log('Plotting Y value for data point: ' + d + ' to be at: ' + y(d) + " using our yScale.");
// return the Y coordinate where we want to plot this datapoint
return y(d);
})
.interpolate(interpolation)
// display the line by appending an svg:path element with the data line we created above
graph.append("svg:path").attr("d", line(data));
// or it can be done like this
//graph.selectAll("path").data([data]).enter().append("svg:path").attr("d", line);
function redrawWithAnimation() {
// update with animation
graph.selectAll("path")
.data([data]) // set the new data
.attr("transform", "translate(" + x(1) + ")") // set the transform to the right by x(1) pixels (6 for the scale we've set) to hide the new value
.attr("d", line) // apply the new data values ... but the new value is hidden at this point off the right of the canvas
.transition() // start a transition to bring the new value into view
.ease("linear")
.duration(transitionDelay) // for this demo we want a continual slide so set this to the same as the setInterval amount below
.attr("transform", "translate(" + x(0) + ")"); // animate a slide to the left back to x(0) pixels to reveal the new value
/* thanks to 'barrym' for examples of transform: https://gist.github.com/1137131 */
}
function redrawWithoutAnimation() {
// static update without animation
graph.selectAll("path")
.data([data]) // set the new data
.attr("d", line); // apply the new data values
}
setInterval(function() {
var v = data.shift(); // remove the first element of the array
data.push(v); // add a new element to the array (we're just taking the number we just shifted off the front and appending to the end)
if(animate) {
redrawWithAnimation();
} else {
redrawWithoutAnimation();
}
}, updateDelay);
}
displayGraphExample("#graph1", 300, 30, "basis", true, 1000, 1000);
displayGraphExample("#graph2", 150, 15, "basis", true, 1000, 1000);
displayGraphExample("#graph3", 150, 15, "linear", true, 1000, 1000);
displayGraphExample("#graph4", 150, 15, "linear", false, 1000, 1000);
displayGraphExample("#graph5", 300, 30, "basis", true, 1500, 750);
displayGraphExample("#graph6", 300, 30, "basis", false, 1500, 750);
</script>
</body>
</html>
@benjchristensen

This comment has been minimized.

Show comment
Hide comment
@benjchristensen

This comment has been minimized.

Show comment
Hide comment
Owner

benjchristensen commented Apr 2, 2012

Updated the d3.js link to http://mbostock.github.com/d3/d3.v2.js

@ankitgautam

This comment has been minimized.

Show comment
Hide comment
@ankitgautam

ankitgautam Jul 8, 2013

Hi,
My project is running d3.v3 (version 3). I need to implement the first sample (#graph1) which is smooth while using v2. But, it is not running smooth when I include v3 in the sample. Can you please suggest a solution?? How can I run it smoothly under v3 ??

Hi,
My project is running d3.v3 (version 3). I need to implement the first sample (#graph1) which is smooth while using v2. But, it is not running smooth when I include v3 in the sample. Can you please suggest a solution?? How can I run it smoothly under v3 ??

@huyinghuan

This comment has been minimized.

Show comment
Hide comment
@huyinghuan

huyinghuan Jan 21, 2014

It's so cool. I am lucky to find it

It's so cool. I am lucky to find it

@KaxLon

This comment has been minimized.

Show comment
Hide comment
@KaxLon

KaxLon Feb 27, 2015

Thanks for this! I am still learning D3 and this code was awesome. =)

KaxLon commented Feb 27, 2015

Thanks for this! I am still learning D3 and this code was awesome. =)

@RichardBronosky

This comment has been minimized.

Show comment
Hide comment
@RichardBronosky

RichardBronosky Sep 5, 2016

Okay, one more. I found that slowing the duration down to 95% made it smooth. Search for 0.95 in...
https://jsfiddle.net/RichardBronosky/o0qfdaL1/4/
I also had to replace ease(d3."linear") with ease(d3.easeLinear) to better match the CHANGES.md above.

Okay, one more. I found that slowing the duration down to 95% made it smooth. Search for 0.95 in...
https://jsfiddle.net/RichardBronosky/o0qfdaL1/4/
I also had to replace ease(d3."linear") with ease(d3.easeLinear) to better match the CHANGES.md above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment