script.js
var impexp = {};
impexp.dataManager = function module() {
var exports = {},
dispatch = d3.dispatch('dataReady', 'dataLoading'),
data;
exports.loadCsvData = function(_file, _cleaningFunc) {
var loadCsv = d3.csv(_file);
loadCsv.on('progress', function() {
dispatch.dataLoading(d3.event.loaded); });
loadCsv.get(function(_error, _response) {
_response.forEach(function(d) {
_cleaningFunc(d);
});
data = _response;
dispatch.dataReady(_response);
});
};
exports.getCleanedData = function() {
return data;
};
d3.rebind(exports, dispatch, 'on');
return exports;
};
impexp.dataCombiner = function module() {
var exports = {};
exports.combine = function(imports_data, exports_data) {
combined_data = keyByCountryWithArrays('imports', imports_data);
exports_by_country = keyByCountry(exports_data);
d3.keys(combined_data).forEach(function(country) {
if (country in exports_by_country) {
combined_data[country].forEach(function(year_data, n) {
var year = year_data['year'];
if (year in exports_by_country[country]) {
combined_data[country][n]['exports'] = exports_by_country[country][year];
};
});
};
});
return combined_data;
};
keyByCountryWithArrays = function(kind, rows) {
var countries = {};
rows.forEach(function(row) {
var years = [];
d3.keys(row).forEach(function(k) {
if (k !== 'Country') {
var year = {year: +k};
year[kind] = +row[k];
years.push(year);
};
});
countries[row['Country']] = years;
});
return countries;
};
keyByCountry = function(rows) {
var countries = {};
rows.forEach(function(row) {
var country = row['Country'];
delete row['Country'];
var year_data = {};
d3.keys(row).forEach(function(k) {
var year = +k;
year_data[year] = +row[k];
});
countries[country] = year_data;
})
return countries;
};
return exports;
};
impexp.chart = function module() {
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 400,
height = 300,
xValue = function(d) { return d[0]; },
yValue = function(d) { return d[1]; },
xScale = d3.scale.linear(),
yScale = d3.scale.linear(),
xAxis = d3.svg.axis().scale(xScale).orient('bottom'),
yAxis = d3.svg.axis().scale(yScale).orient('left'),
line = d3.svg.area().x(X).y(Y);
var dispatch = d3.dispatch('customHover');
function exports(_selection) {
_selection.each(function(data) {
var inner_width = width - margin.left - margin.right,
inner_height = height - margin.top - margin.bottom;
xScale.domain(d3.extent(data, function(d) { return d.year; }))
.range([0, inner_width]);
yScale.domain([
d3.min(data, function(d) { return Math.min(d['imports'], d['exports']); }),
d3.max(data, function(d) { return Math.max(d['imports'], d['exports']); })
]).range([inner_height, 0]);
var svg = d3.select(this)
.selectAll('svg')
.data([data]);
var gEnter = svg.enter().append('svg').append('g');
gEnter.append('path').attr('class', 'line');
gEnter.append('g').attr('class', 'x axis');
gEnter.append('g').attr('class', 'y axis');
svg.transition()
.attr({ width: width, height: height });
var g = svg.select('g')
.attr('transform',
'translate(' + margin.left + ',' + margin.right + ')');
console.log(xScale.range(), xScale.domain(), yScale.range(), yScale.domain(), JSON.stringify(data));
g.select('.line').attr('d', line);
g.select('.x.axis')
.attr('transform', 'translate(0,' + yScale.range()[0] + ')')
.call(xAxis);
g.select('.y.axis')
.call(yAxis);
});
};
function X(d) {
return xScale(d.year);
}
function Y(d) {
return yScale(d.imports);
}
exports.margin = function(_) {
if (!arguments.length) return margin;
margin = _;
return this;
};
exports.width = function(_) {
if (!arguments.length) return width;
width = _;
return this;
};
exports.height = function(_) {
if (!arguments.length) return height;
height = _;
return this;
};
exports.x = function(_) {
if (!arguments.length) return xValue;
xValue = _;
return chart;
};
exports.y = function(_) {
if (!arguments.length) return yValue;
yValue = _;
return chart;
};
d3.rebind(exports, dispatch, "on");
return exports;
};
var draw_chart = function() {
d3.select('#wait').style('visibility', 'hidden');
d3.select('#ready').style('visibility', 'visible');
var combiner = impexp.dataCombiner();
var data = combiner.combine(importsDataManager.getCleanedData(),
exportsDataManager.getCleanedData());
var chart = impexp.chart()
.width(600).height(400)
.margin({top: 50, right: 50, bottom: 50, left: 50});
var container = d3.select('#container')
.data([data['France']])
.call(chart);
};
var importsDataManager = impexp.dataManager(),
exportsDataManager = impexp.dataManager();
var csvCleaner = function(d){};
importsDataManager.loadCsvData('imports.csv', csvCleaner);
exportsDataManager.loadCsvData('exports.csv', csvCleaner);
var loaded = 0;
importsDataManager.on('dataReady', function() {
loaded++;
if (loaded == 2) {
draw_chart();
};
});
exportsDataManager.on('dataReady', function() {
loaded++;
if (loaded == 2) {
draw_chart();
};
});
exports.csv
Country,1999,2000,2001,2002,2003
France,19,20,30,32,9
UK,15,22,25,20,21
imports.csv
Country,1999,2000,2001,2002,2003
France,15,18,17,20,25
UK,10,20,30,25,28