Skip to content

Instantly share code, notes, and snippets.

@hrbrmstr
Created August 27, 2015 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hrbrmstr/a860fdb6e149601d0c44 to your computer and use it in GitHub Desktop.
Save hrbrmstr/a860fdb6e149601d0c44 to your computer and use it in GitHub Desktop.
nice straightforward D3 example from NPR
var $graphic = $('#graphic');
var fmt_year_abbr = d3.time.format('%y');
var fmt_year_full = d3.time.format('%Y');
var graphic_data;
var graphic_data_url = 'data.csv';
var graphic_default_width = 600;
var is_mobile;
var mobile_threshold = 540;
var pymChild = null;
var colors = {
'red1': '#6C2315', 'red2': '#A23520', 'red3': '#D8472B', 'red4': '#E27560', 'red5': '#ECA395', 'red6': '#F5D1CA',
'orange1': '#714616', 'orange2': '#AA6A21', 'orange3': '#E38D2C', 'orange4': '#EAAA61', 'orange5': '#F1C696', 'orange6': '#F8E2CA',
'yellow1': '#77631B', 'yellow2': '#B39429', 'yellow3': '#EFC637', 'yellow4': '#F3D469', 'yellow5': '#F7E39B', 'yellow6': '#FBF1CD',
'teal1': '#0B403F', 'teal2': '#11605E', 'teal3': '#17807E', 'teal4': '#51A09E', 'teal5': '#8BC0BF', 'teal6': '#C5DFDF',
'blue1': '#28556F', 'blue2': '#3D7FA6', 'blue3': '#51AADE', 'blue4': '#7DBFE6', 'blue5': '#A8D5EF', 'blue6': '#D3EAF7'
};
/*
* Render the graphic
*/
function render(container_width) {
var graphic_width;
if (!container_width) {
container_width = graphic_default_width;
}
if (container_width <= mobile_threshold) {
is_mobile = true;
} else {
is_mobile = false;
}
// clear out existing graphics
$graphic.empty();
draw_graph(container_width);
if (pymChild) {
pymChild.sendHeightToParent();
}
}
function draw_graph(width) {
var color = d3.scale.ordinal()
.range([ colors['teal2'], colors['teal3'], colors['teal5'], colors['red3'], colors['teal3'] ]);
var graphic_aspect_height;
var graphic_aspect_width;
var height;
var margin = { top: 5, right: 15, bottom: 30, left: 40 };
var num_x_ticks;
var num_y_ticks;
if (is_mobile) {
graphic_aspect_width = 4;
graphic_aspect_height = 3;
num_x_ticks = 5;
num_y_ticks = 5;
} else {
graphic_aspect_width = 16;
graphic_aspect_height = 9;
num_x_ticks = 10;
num_y_ticks = 10;
}
width = width - margin['left'] - margin['right'];
height = Math.ceil((width * graphic_aspect_height) / graphic_aspect_width) - margin['top'] - margin['bottom'];
var x = d3.time.scale()
.range([0, width])
var y = d3.scale.linear()
.range([ height, 0 ]);
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom')
.ticks(num_x_ticks)
.tickFormat(function(d,i) {
if (is_mobile) {
return '\u2019' + fmt_year_abbr(d);
} else {
return fmt_year_full(d);
}
});
var x_axis_grid = function() { return xAxis; };
var yAxis = d3.svg.axis()
.orient('left')
.scale(y)
.ticks(num_y_ticks)
.tickFormat(function(d) {
return d + '%';
});
var y_axis_grid = function() { return yAxis; };
var line = d3.svg.line()
.interpolate('basis')
.defined(function(d) { return d['amt'] != 'tk'; })
.x(function(d) {
return x(d['date']);
})
.y(function(d) {
return y(d['amt']);
});
color.domain(d3.keys(graphic_data[0]).filter(function(key) {
return key !== 'date';
}));
console.log(graphic_data)
// parse data into columns
var formatted_data = {};
for (var column in graphic_data[0]) {
if (column == 'date') continue;
formatted_data[column] = graphic_data.map(function(d) {
return { 'date': d['date'], 'amt': d[column]*100 };
});
// filter(function(d) {
// return d['amt'].length > 0;
// });
}
// set the data domain
x.domain(d3.extent(graphic_data, function(d) {
return d['date'];
}));
y.domain([ 0, d3.max(d3.entries(formatted_data), function(c) {
return d3.max(c['value'], function(v) {
var n = v['amt'];
return Math.ceil(n/5) * 5; // round to next 5
});
})
]);
// draw the legend
var legend = d3.select('#graphic')
.append('ul')
.attr('class', 'key')
.selectAll('g')
.data(d3.entries(formatted_data))
.enter().append('li')
.attr('class', function(d, i) {
return 'key-item key-' + i + ' ' + classify(d['key']);
});
legend.append('b')
.style('background-color', function(d) {
return color(d['key']);
});
legend.append('label')
.text(function(d) {
return d['key'];
});
// draw the chart
var svg = d3.select('#graphic')
.append('svg')
.attr('width', width + margin['left'] + margin['right'])
.attr('height', height + margin['top'] + margin['bottom'])
.append('g')
.attr('transform', 'translate(' + margin['left'] + ',' + margin['top'] + ')');
var xBottom = svg.append('g') // Add the X Axis
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
var yTop = svg.append('g') // Add the Y Axis
.attr('class', 'y axis')
.call(yAxis);
var xGrid = svg.append('g')
.attr('class', 'x grid')
.attr('transform', 'translate(0,' + height + ')')
.call(x_axis_grid()
.tickSize(-height, 0, 0)
.tickFormat('')
);
var yGrid = svg.append('g')
.attr('class', 'y grid')
.call(y_axis_grid()
.tickSize(-width, 0, 0)
.tickFormat('')
);
var parity = svg.append('line')
.attr('class', 'lines')
.attr('x1', x(graphic_data[0]['date']))
.attr('x2', x(graphic_data[0]['date']))
.attr('y1', y(50))
.attr('y2', y(50));
var lines = svg.append('g')
.attr('class', 'lines')
.selectAll('path')
.data(d3.entries(formatted_data))
.enter()
.append('path')
.attr('class', function(d, i) {
return 'line line-' + i + ' ' + classify(d['key']);
})
.attr('stroke', function(d) {
return color(d['key']);
})
.attr('d', function(d) {
return line(d['value']);
});
}
/*
* Helper functions
*/
function classify(str) { // clean up strings to use as CSS classes
return str.replace(/\s+/g, '-').toLowerCase();
}
/*
* Initially load the graphic
* (NB: Use window.load instead of document.ready
* to ensure all images have loaded)
*/
$(window).load(function() {
if (Modernizr.svg) {
$graphic = $('#graphic');
console.log(graphic_data)
d3.csv(graphic_data_url, function(error, data) {
graphic_data = data;
graphic_data.forEach(function(d) {
d['date'] = d3.time.format('%Y').parse(d['date']);
});
var pymChild = new pym.Child({
renderCallback: render
});
});
} else {
pymChild = new pym.Child({ });
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment