Last active
December 18, 2015 11:19
-
-
Save philgyford/5774449 to your computer and use it in GitHub Desktop.
An adaptation of this example <http://bost.ocks.org/mike/chart/> of drawing multiple d3 charts on one page. I've altered it so that each chart can include more than one dataset.
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> | |
<meta charset="utf-8"> | |
<html> | |
<head> | |
<title>d3 - multiple charts with multiple lines</title> | |
<!-- | |
Based on this example of drawing multiple d3 charts on one page: | |
http://bost.ocks.org/mike/chart/ | |
With pointers from Lars Kotthof on Stack Overflow: | |
http://stackoverflow.com/questions/16316829/multiple-multi-series-d3-line-charts-on-one-page | |
You'll need a copy of d3.v3.min.js as well as these two files. | |
--> | |
<style type="text/css"> | |
.line { | |
fill: none; | |
stroke-width: 1.5px; | |
} | |
/* Each line on a chart will have a number from 1 upwards. */ | |
.line-1 { | |
stroke: #000; | |
} | |
.line-2 { | |
stroke: #0c0; | |
} | |
</style> | |
<!-- You'll have to download and include a copy of d3.v3.min.js. --> | |
<script src="d3.v3.min.js"></script> | |
<script src="chart.js"></script> | |
<script> | |
window.onload = function() { | |
// Two sets of data for the first chart: | |
var data_1a = [ | |
{'date': 'Jan 2000', 'price': '1394.46' }, | |
{'date': 'Feb 2000', 'price': '1366.42' }, | |
{'date': 'Mar 2000', 'price': '1498.58' }, | |
{'date': 'Apr 2000', 'price': '1452.43' }, | |
{'date': 'May 2000', 'price': '1420.6' }, | |
{'date': 'Jun 2000', 'price': '1454.6' }, | |
{'date': 'Jul 2000', 'price': '1430.83' }, | |
{'date': 'Aug 2000', 'price': '1517.68' } | |
]; | |
var data_1b = [ | |
{'date': 'May 2000', 'price': '1094.46' }, | |
{'date': 'Jun 2000', 'price': '1366.42' }, | |
{'date': 'Jul 2000', 'price': '1598.58' }, | |
{'date': 'Aug 2000', 'price': '1752.43' }, | |
{'date': 'Sep 2000', 'price': '1420.6' }, | |
{'date': 'Oct 2000', 'price': '1454.6' }, | |
{'date': 'Nov 2000', 'price': '1430.83' }, | |
{'date': 'Dec 2000', 'price': '1817.68' } | |
]; | |
// One set of data for the second chart: | |
var data2 = [ | |
{'date': 'Jan 2012', 'price': '1394.46' }, | |
{'date': 'Feb 2012', 'price': '366.42' }, | |
{'date': 'Mar 2012', 'price': '1598.58' }, | |
{'date': 'Apr 2012', 'price': '952.43' }, | |
{'date': 'May 2012', 'price': '1420.6' }, | |
{'date': 'Jun 2012', 'price': '454.6' }, | |
{'date': 'Jul 2012', 'price': '1430.83' }, | |
{'date': 'Aug 2012', 'price': '817.68' } | |
]; | |
// Set up the chart instance: | |
var chart = timeSeriesChart() | |
.x(function(d) { return formatDate.parse(d.date); }) | |
.y(function(d) { return +d.price; }); | |
var formatDate = d3.time.format("%b %Y"); | |
// Draw each chart in turn. | |
// The datasets are passed in in an array. | |
// Both use the same chart instance. | |
d3.select("#chart1") | |
.datum([data_1a, data_1b]) | |
.call(chart); | |
d3.select("#chart2") | |
.datum([data2]) | |
.call(chart); | |
}; | |
</script> | |
</head> | |
<body> | |
<div id="chart1"></div> | |
<div id="chart2"></div> | |
</body> | |
</html> |
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
function timeSeriesChart() { | |
var margin = {top: 20, right: 20, bottom: 20, left: 20}, | |
width = 760, | |
height = 120, | |
xValue = function(d) { return d[0]; }, | |
yValue = function(d) { return d[1]; }, | |
xScale = d3.time.scale(), | |
yScale = d3.scale.linear(), | |
xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickSize(6, 0), | |
line = d3.svg.line().x(X).y(Y); | |
function chart(selection) { | |
selection.each(function(orig_datasets) { | |
// orig_datasets is an array of datasets. | |
// Each dataset is an array of objects. | |
// This will be a new version of the array of datasets, | |
// but now each of which will be an array of arrays: | |
var datasets = []; | |
orig_datasets.forEach(function(data) { | |
// Convert data to standard representation greedily; | |
// this is needed for nondeterministic accessors. | |
data = data.map(function(d, i) { | |
return [xValue.call(data, d, i), yValue.call(data, d, i)]; | |
}); | |
datasets.push(data); | |
}); | |
// Update the x-scale. | |
// Set the domains to go from min to max of all the datasets' x values. | |
xScale | |
.domain([ | |
d3.min(datasets, function(ds) { | |
return d3.min(ds, function(d) { return d[0]; }) | |
}), | |
d3.max(datasets, function(ds) { | |
return d3.max(ds, function(d) { return d[0]; }) | |
}) | |
]) | |
.range([0, width - margin.left - margin.right]); | |
// Update the y-scale. | |
// Set the domains to go from min to max of all the datasets' y values. | |
yScale | |
.domain([ | |
0, | |
d3.max(datasets, function(ds) { | |
return d3.max(ds, function(d) { return d[1]; }) | |
}) | |
]) | |
.range([height - margin.top - margin.bottom, 0]); | |
// Select the svg element, if it exists. | |
var svg = d3.select(this).selectAll("svg").data([datasets]); | |
// Otherwise, create the skeletal chart. | |
var gEnter = svg.enter().append("svg").append("g"); | |
gEnter.append("g").attr("class", "x axis"); | |
// Update the outer dimensions. | |
svg .attr("width", width) | |
.attr("height", height); | |
// Update the inner dimensions. | |
var g = svg.select("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
// Update the line paths. | |
g.selectAll(".line").data(datasets) | |
.enter() | |
.append("path") | |
.attr("class", function(d,i) { return "line line-"+(i+1); }) | |
.attr("d", line); | |
// Update the x-axis. | |
g.select(".x.axis") | |
.attr("transform", "translate(0," + yScale.range()[0] + ")") | |
.call(xAxis); | |
}); | |
} | |
// The x-accessor for the path generator; xScale ∘ xValue. | |
function X(d) { | |
return xScale(d[0]); | |
} | |
// The x-accessor for the path generator; yScale ∘ yValue. | |
function Y(d) { | |
return yScale(d[1]); | |
} | |
chart.margin = function(_) { | |
if (!arguments.length) return margin; | |
margin = _; | |
return chart; | |
}; | |
chart.width = function(_) { | |
if (!arguments.length) return width; | |
width = _; | |
return chart; | |
}; | |
chart.height = function(_) { | |
if (!arguments.length) return height; | |
height = _; | |
return chart; | |
}; | |
chart.x = function(_) { | |
if (!arguments.length) return xValue; | |
xValue = _; | |
return chart; | |
}; | |
chart.y = function(_) { | |
if (!arguments.length) return yValue; | |
yValue = _; | |
return chart; | |
}; | |
return chart; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment