Skip to content

Instantly share code, notes, and snippets.

@duhaime
Last active May 29, 2019 20:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save duhaime/f1b98aa733300c909e56f0d65d8b4039 to your computer and use it in GitHub Desktop.
Save duhaime/f1b98aa733300c909e56f0d65d8b4039 to your computer and use it in GitHub Desktop.
Map Timeline
license: MIT
height: 500
scrolling: no
border: yes
(function() {
var exp,
data,
state = { year: 1600, },
// elems
container = '#selected-county-container',
yearElem = document.querySelector('#county-year'),
countyElem = document.querySelector('#selected-county'),
nameElem = document.querySelector('#county-name'),
countElem = document.querySelector('#county-count'),
body = document.querySelector('body');
var colors = d3.scaleLinear()
.domain([0, 1])
.range(['yellow', 'red']);
var projection = d3
.geoMercator()
.scale(1600) // zoom
.center([0.0, 54.8]); // starting lat,lng
var path = d3.geoPath().projection(projection);
var graticule = d3.geoGraticule()
.step([2,2])
var map = d3.select(container)
.append('svg')
.attr('width', 700)
.attr('height', 500);
map.append('path')
.datum(graticule)
.attr('class', 'graticule')
.attr('d', path);
body.addEventListener('click', handleBodyClick)
d3.json('county_publication_counts.geojson', function(json) {
data = json;
exp = d3.scaleLog().domain(getDomain(data))
draw();
})
setInterval(function() {
state.year = state.year >= 1780 ? 1600 : state.year + 20;
draw()
}, 2000)
function draw() {
setTimeout(updateYear, 300)
// draw the paths
var paths = map.selectAll('path').data(data.features)
paths.enter()
.append('path')
.attr('class', 'terrain')
.attr('d', path)
.attr('stroke', '#4a4a4a')
.attr('stroke-width', ' 0.01em')
.attr('fill', getFill)
.on('click', handleClick);
paths.transition()
.duration(1000)
.attr('fill', getFill)
};
// find the min and max publication counts
function getDomain(data) {
var min = Number.POSITIVE_INFINITY,
max = Number.NEGATIVE_INFINITY;
data.features.map(function(feature) {
feature.data.map(function(o) {
if (o.year === state.year) {
if (o.val < min) min = o.val;
if (o.val > max) max = o.val;
}
})
})
return [min, max];
}
// get the fill attribute for a path
function getFill(d) {
var datum = d.data.filter(function(i) {
return i.year == state.year;
});
return datum.length
? colors( exp(datum[0].val) )
: '#F5F5F3';
}
// callback for when mouse enters path
function handleClick(d) {
state.selected = d;
var val = d.data.filter(function(i) {
return i.year === state.year;
});
countElem.innerHTML = val.length ? val[0].val : 0;
nameElem.innerHTML = d.properties.ISO === 'GBR'
? d.properties.NAME_2
: d.properties.NAME_1;
d3.select(container).selectAll('path').classed('inactive', true);
d3.select(this).classed('inactive', false);
countyElem.style.display = 'block';
}
function handleBodyClick(e) {
if (e.target.nodeName === 'svg') {
d3.select(container).selectAll('path').classed('inactive', false);
state.selected = null;
countElem.innerHTML = '';
nameElem.innerHTML = '';
countyElem.style.display = 'none';
}
}
function updateYear() {
yearElem.innerHTML = state.year;
// change the number of pubs in the selected county (if any)
if (state.selected) {
var d = data.features.filter(function(i) {
return state.selected.properties.NAME_2
? i.properties.NAME_2 == state.selected.properties.NAME_2
: i.properties.NAME_1 == state.selected.properties.NAME_1
})[0];
var val = d.data.filter(function(i) {
return i.year === state.year;
});
if (val.length) countElem.innerHTML = val[0].val;
}
}
})()
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment