Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Line graph over time with multiple data points using SVG and d3.js
<html>
<head>
<title>Line graph over time with multiple data points using SVG and d3.js</title>
<script src="http://mbostock.github.com/d3/d3.v2.js"></script>
<style>
body {
font-family: "Helvetica Neue", Helvetica;
}
/* tell the SVG path to be a thin blue line without any area fill */
path {
stroke-width: 1;
fill: none;
}
.data1 {
stroke: green;
}
.data2 {
stroke: orange;
}
.axis {
shape-rendering: crispEdges;
}
.x.axis line {
stroke: lightgrey;
}
.x.axis .minor {
stroke-opacity: .5;
}
.x.axis path {
display: none;
}
.x.axis text {
font-size: 10px;
}
.y.axis line, .y.axis path {
fill: none;
stroke: #000;
}
.y.axis text {
font-size: 12px;
}
</style>
</head>
<body>
<div id="graph" class="aGraph" style="position:absolute;top:0px;left:0; float:left;"></div>
<script>
/* implementation heavily influenced by http://bl.ocks.org/1166403 */
// define dimensions of graph
var m = [80, 80, 80, 80]; // margins
var w = 1000 - m[1] - m[3]; // width
var h = 400 - m[0] - m[2]; // height
/*
* sample data to plot over time
* [Success, Failure]
* Start: 1335035400000
* End: 1335294600000
* Step: 300000ms
*/
var data = [[28,22],[28,21],[28,25],[28,24],[28,22],[29,21],[29,24],[29,22],[28,21],[29,24],[29,20],[29,21],[29,24],[29,24],[30,24],[28,22],[28,21],[28,22],[28,24],[29,24],[28,22],[30,26],[31,22],[32,26],[30,24],[31,22],[30,27],[30,25],
[30,20],[31,23],[31,24],[30,25],[31,23],[31,27],[31,48],[33,32],[31,28],[32,39],[31,27],[32,24],[34,28],[32,29],[34,27],[34,28],[33,29],[34,28],[34,31],[36,27],[34,28],[35,28],[35,56],[37,42],[36,34],[38,38],[37,41],[37,35],[38,35],
[38,34],[39,33],[43,34],[42,37],[41,43],[44,89],[42,50],[41,39],[43,38],[42,37],[41,45],[42,42],[43,38],[42,37],[46,37],[47,39],[45,46],[44,40],[45,36],[45,104],[45,51],[45,40],[45,42],[45,46],[44,49],[44,52],[45,53],[44,54],[43,60],
[44,56],[44,53],[44,48],[43,51],[43,46],[42,43],[42,42],[41,43],[43,48],[43,44],[42,42],[41,38],[40,36],[41,40],[39,44],[39,41],[38,41],[36,37],[37,37],[35,40],[35,36],[36,41],[34,34],[32,35],[32,31],[32,32],[32,37],[31,30],[31,31],
[30,31],[30,29],[28,28],[29,31],[29,36],[30,50],[27,30],[25,29],[24,29],[23,29],[22,25],[22,24],[21,28],[20,23],[21,23],[21,24],[20,23],[19,19],[19,22],[20,26],[17,23],[18,20],[16,21],[15,17],[17,17],[15,20],[15,17],[14,21],[14,18],
[12,17],[12,17],[12,12],[12,15],[12,12],[11,14],[11,14],[11,13],[11,12],[11,14],[10,12],[11,14],[10,12],[10,12],[10,11],[9,12],[9,13],[9,9],[9,11],[8,9],[11,10],[8,9],[9,9],[8,10],[7,9],[7,8],[7,9],[7,7],[7,7],[7,7],[7,6],[7,6],[7,6],
[7,6],[6,8],[7,7],[7,6],[7,7],[7,7],[7,6],[7,6],[7,7],[7,9],[7,8],[7,7],[7,7],[8,6],[9,7],[8,8],[9,8],[9,7],[10,7],[10,8],[10,12],[11,13],[11,9],[12,11],[11,15],[12,13],[12,11],[12,13],[14,20],[14,22],[14,13],[15,15],[15,29],[17,17],
[16,18],[18,18],[16,38],[17,27],[19,27],[18,29],[19,23],[19,33],[19,27],[20,20],[20,21],[21,32],[20,27],[20,21],[21,19],[21,19],[22,19],[22,22],[21,18],[23,20],[23,25],[24,38],[25,21],[24,44],[24,26],[24,22],[24,22],[25,46],[26,30],
[25,23],[25,24],[25,22],[25,21],[26,22],[26,20],[27,29],[27,23],[26,24],[26,23],[27,20],[28,22],[27,22],[28,29],[27,25],[27,26],[27,26],[28,27],[28,45],[27,46],[27,29],[28,44],[27,32],[29,32],[28,31],[29,28],[29,26],[28,24],[30,27],
[30,34],[30,27],[29,24],[30,25],[32,25],[32,24],[33,28],[30,26],[30,32],[30,26],[29,27],[31,56],[31,29],[31,29],[32,30],[32,26],[32,29],[33,28],[34,31],[32,29],[33,29],[32,31],[32,28],[32,28],[32,28],[33,28],[32,30],[32,29],[32,27],
[33,26],[34,30],[34,29],[33,30],[33,33],[35,55],[34,42],[34,34],[34,30],[34,33],[33,35],[34,30],[35,31],[35,34],[35,32],[35,29],[35,32],[35,30],[35,30],[35,29],[35,31],[36,30],[35,32],[36,32],[36,33],[38,34],[36,34],[37,32],[36,32],
[36,32],[37,34],[37,34],[37,40],[37,35],[38,33],[39,37],[40,34],[42,37],[39,39],[39,38],[40,35],[39,38],[41,90],[41,45],[41,39],[41,39],[42,49],[41,36],[43,41],[47,38],[46,44],[46,50],[43,55],[43,43],[44,64],[43,78],[44,48],[44,46],
[42,77],[43,82],[48,57],[48,53],[47,50],[45,54],[43,43],[45,91],[44,67],[43,40],[43,38],[41,41],[43,39],[47,45],[41,49],[44,42],[43,43],[44,62],[42,41],[39,40],[39,40],[39,57],[40,106],[39,68],[36,40],[36,39],[36,41],[39,40],[37,39],
[37,38],[35,34],[34,33],[34,41],[36,38],[33,35],[32,32],[31,33],[30,38],[30,37],[31,32],[28,30],[29,34],[27,33],[26,28],[25,28],[25,27],[24,27],[24,27],[22,24],[21,25],[20,22],[22,23],[21,26],[20,23],[19,23],[18,19],[18,19],[17,19],
[17,19],[16,17],[15,19],[15,14],[15,17],[14,18],[13,15],[13,16],[13,16],[12,14],[11,14],[13,12],[14,11],[12,14],[10,10],[10,13],[10,11],[10,13],[9,14],[9,10],[9,8],[9,11],[9,9],[8,8],[8,11],[8,10],[8,8],[8,10],[8,8],[8,9],[7,8],[7,8],
[7,7],[6,7],[6,7],[6,8],[6,6],[7,7],[9,7],[7,7],[6,7],[6,7],[6,7],[6,7],[6,7],[6,7],[5,5],[6,5],[5,6],[5,5],[6,6],[5,6],[6,6],[6,7],[6,6],[6,6],[7,6],[7,7],[7,6],[7,7],[8,7],[7,7],[7,7],[8,7],[8,7],[9,8],[8,8],[9,8],[10,8],[10,8],[10,8],
[10,8],[10,9],[10,9],[11,9],[10,10],[10,11],[10,11],[11,11],[11,10],[11,10],[12,14],[11,9],[11,10],[11,11],[12,10],[12,9],[11,9],[12,9],[12,14],[12,14],[12,10],[13,10],[13,11],[13,13],[12,23],[14,9],[13,9],[13,8],[13,11],[13,18],[14,9],
[14,8],[14,8],[15,15],[14,18],[15,10],[14,13],[14,10],[14,10],[14,11],[14,10],[14,8],[15,10],[15,12],[15,11],[15,11],[15,20],[14,15],[14,9],[14,11],[14,11],[14,11],[14,11],[16,11],[16,11],[15,10],[16,11],[16,12],[15,12],[16,24],[16,15],
[16,14],[15,12],[16,11],[16,11],[17,13],[17,12],[17,13],[16,12],[17,15],[16,31],[17,15],[17,12],[17,13],[18,14],[17,12],[17,13],[17,14],[17,14],[16,14],[17,16],[17,15],[17,14],[18,14],[17,16],[18,20],[18,26],[18,15],[19,16],[20,17],
[20,16],[19,15],[21,18],[19,14],[20,16],[20,16],[21,28],[20,34],[23,19],[24,21],[23,38],[23,27],[24,18],[24,25],[23,24],[25,24],[24,21],[25,21],[24,21],[27,24],[25,21],[25,28],[26,46],[25,25],[28,34],[27,51],[26,34],[27,30],[27,27],
[27,24],[28,26],[27,27],[26,31],[28,24],[28,22],[28,24],[30,24],[30,25],[30,25],[31,25],[30,38],[31,63],[32,37],[30,28],[30,63],[32,41],[32,33],[33,31],[34,25],[33,26],[32,27],[33,30],[34,37],[35,31],[35,31],[35,40],[35,57],[35,30],
[35,37],[38,39],[40,40],[38,36],[39,41],[39,33],[37,39],[39,74],[39,39],[40,35],[39,42],[39,45],[38,37],[39,34],[43,37],[42,32],[40,31],[40,35],[39,32],[39,36],[40,33],[40,29],[38,35],[40,36],[38,35],[39,73],[43,49],[41,43],[40,49],
[40,46],[38,38],[39,40],[38,40],[38,37],[35,33],[36,33],[35,30],[35,30],[36,31],[35,34],[35,32],[34,31],[33,35],[33,30],[33,32],[32,34],[30,32],[30,29],[29,27],[28,29],[29,32],[27,27],[26,31],[26,25],[25,27],[25,26],[24,25],[23,24],
[23,24],[21,21],[21,25],[21,21],[21,22],[21,22],[20,23],[19,20],[18,19],[17,16],[18,19],[17,21],[15,15],[15,17],[15,18],[14,15],[14,16],[13,14],[13,15],[14,13],[12,11],[12,11],[14,12],[13,12],[11,14],[10,10],[10,12],[10,10],[10,9],
[10,11],[9,8],[9,9],[9,8],[8,10],[8,10],[9,9],[8,9],[8,11],[8,9],[9,9],[8,7],[8,9],[7,7],[7,6],[7,7],[7,8],[7,6],[7,7],[7,6],[9,7],[7,5],[7,6],[6,6],[7,7],[6,6],[6,6],[6,5],[6,5],[6,6],[6,6],[6,5],[6,6],[6,5],[6,5],[6,6],[7,5],[7,5],
[7,5],[8,5],[8,5],[8,5],[8,5],[9,6],[9,7],[9,6],[9,7],[10,7],[10,6],[10,6],[10,6],[11,6],[11,7],[12,8],[12,8],[12,8],[13,9],[12,7],[13,7],[13,17],[13,10],[13,7],[12,8],[13,8],[14,10],[14,18],[13,17],[13,8],[13,8],[13,7],[13,8],[14,8],
[14,9],[14,8],[15,8],[14,8],[15,8],[14,10],[15,9],[15,7],[15,9],[15,11],[25,110],[16,9],[16,18],[25,138],[16,13],[18,25],[16,11],[16,9],[15,10],[15,9],[16,11],[16,10],[16,10],[17,11],[16,11],[16,12],[16,9],[16,11],[16,11],[17,12],
[15,11],[16,11],[16,10],[16,10],[16,9],[18,10],[16,10],[17,18],[17,17],[17,12],[18,27],[17,17],[17,16],[17,12],[17,15],[17,15],[18,13],[18,13],[17,13],[18,13],[18,15],[18,13],[18,13],[20,12],[19,13],[18,13],[18,12],[18,13],[18,13],
[19,14],[19,13],[19,13],[18,17],[19,27],[19,18],[19,16],[19,12],[20,13],[19,13],[19,13],[20,13]];
var startTime = new Date(1335035400000);
var endTime = new Date(1335294600000);
var timeStep = 300000;
// X scale starts at epoch time 1335035400000, ends at 1335294600000 with 300s increments
var x = d3.time.scale().domain([startTime, endTime]).range([0, w]);
x.tickFormat(d3.time.format("%Y-%m-%d"));
// Y scale will fit values from 0-10 within pixels h-0 (Note the inverted domain for the y-scale: bigger is up!)
var y = d3.scale.linear().domain([0, d3.max(data, function(d) { return d[1]; })]).range([h, 0]);
// create a line function that can convert data[] into x and y points
var line1 = 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(startTime.getTime() + (timeStep*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[0]); // use the 1st index of data (for example, get 20 from [20,13])
})
var line2 = 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(startTime.getTime() + (timeStep*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[1]); // use the 2nd index of data (for example, get 13 from [20,13])
})
// Add an SVG element with the desired dimensions and margin.
var graph = d3.select("#graph").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
// create yAxis
var xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(1);
// Add the x-axis.
graph.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis);
// create left yAxis
var yAxisLeft = d3.svg.axis().scale(y).ticks(6).orient("left");
// Add the y-axis to the left
graph.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(-10,0)")
.call(yAxisLeft);
// add lines
// do this AFTER the axes above so that the line is above the tick-lines
graph.append("svg:path").attr("d", line1(data)).attr("class", "data1");
graph.append("svg:path").attr("d", line2(data)).attr("class", "data2");
</script>
</body>
</html>
@benjchristensen
Copy link
Author

benjchristensen commented May 11, 2012

@0x6a68
Copy link

0x6a68 commented Feb 27, 2013

great example! cheerio!

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