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

This comment has been minimized.

Copy link
Owner Author

commented May 11, 2012

@0x6a6f74726f

This comment has been minimized.

Copy link

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
You can’t perform that action at this time.