To help any one interested in creating “multi-line” or multiple line charts with D3.js, I will walk through the various steps required to create the D3 plots on The Bubble Index. There may be many places in my code which could be simplified and improved — I present the current version “as it is.”
Working version of the plot, download here.
The goal is to have the SVG plot fill the width of any screen which accesses the site. The HTML code contains a “plotarea” <div> which has its CSS width property set to: width = 100%. Note: this uses jQuery to select the <div>, but certainly there are other ways to select the <div>. Therefore, no matter how wide the screen on the device, the “areawidth” variable will store that information. This code setup means that the “plotarea” will only resize itself after a page resize and refresh F5, which is ok for my purposes. The aspect ratio and margins are set to visually appealing values.
The next lines contain the following useful functions:
- D3 date parser to extract date objects from the time-series data
- D3 scale functions to ensure that the time-series data for each time-series is always scaled with the SVG in the x and y directions
- D3 line function to draw the lines on the SVG — “basis” interpolation method
- D3 bisector function to be used in coordination with mouse-over events to determine the nearest “x” value of the current position of the cursor
var index;
var origData;
var indices;
var focus;
var margin = {
top: 20,
right: 80,
bottom: 100,
left: 50
},
aspect = 1.92,
areawidth = $("#plotarea").width(),
width = areawidth - margin.left - margin.right,
height = Math.round(areawidth / aspect) - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y-%m-%d").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var dateDisplayFormat = d3.time.format("%Y-%m-%d");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("right");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.yvalue);
});
var bisectDate = d3.bisector(function(d) {
return d.date;
}).left;