Skip to content

Instantly share code, notes, and snippets.

@eSlivinski
Last active April 8, 2017 18:35
Show Gist options
  • Save eSlivinski/46bfe168a4f247ff08722cad714aefd8 to your computer and use it in GitHub Desktop.
Save eSlivinski/46bfe168a4f247ff08722cad714aefd8 to your computer and use it in GitHub Desktop.
US Highways Simplified
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<style>
.state {
fill: #aaa;
stroke: #ddd;
}
.highway {
fill: none;
stroke: cyan;
stroke-width: .1em;
stroke-opacity: 0.5;
transition: stroke-width 500ms linear,
stroke-opacity 500ms linear;
cursor: pointer;
}
.highway.highlight {
stroke-width: .3em;
stroke-opacity: 1;
}
.hub {
fill: gold;
stroke: gold;
fill-opacity: 0.7;
transition: fill-opacity 500ms linear;
cursor: pointer;
}
.hub.highlight {
fill-opacity: 1;
}
</style>
</head>
<body>
</body>
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-queue/3.0.5/d3-queue.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://d3js.org/d3.v4.js"></script>
<script>
var width = 960;
var height = 500;
var svg = d3.select("body")
.append("svg")
.attr('width', width)
.attr('height', height);
var projection = d3.geoAlbersUsa();
var path = d3.geoPath()
.projection(projection);
var radiusScale = d3.scaleLinear()
.range([1, 8]);
function simplify (features, precison) {
features.forEach(h=> {
h.geometry.coordinates = h.geometry.coordinates.map(c=> {
var x = _.round(c[0], precison);
var y = _.round(c[1], precison);
return [x, y];
});
});
return features;
}
function identifyHubs (hwyData) {
return _.chain(hwyData)
.flatMap(hwy => {
return _.chain(hwy.geometry.coordinates)
.uniqWith(_.isEqual)
.map(coord => { return { coordinates: coord, routes: hwy.properties.routes }; })
.value();
})
.groupBy('coordinates')
.map(coord => {
return {
type: 'Feature',
properties: { routes: _.uniq(_.flatMap(coord, 'routes')) },
geometry: { type: 'Point', coordinates: coord[0].coordinates }
};
})
.value();
}
function highlight(routes) {
console.log(routes)
d3.selectAll('.hub, .highway')
.classed('highlight', d => {
return _.intersection(routes, d.properties.routes).length;
});
}
d3.queue()
.defer(d3.json, "https://raw.githubusercontent.com/eSlivinski/data-bin/master/spatial/us.geojson")
.defer(d3.json, "https://raw.githubusercontent.com/eSlivinski/data-bin/master/spatial/us_highways.geojson")
.awaitAll(function(error, results) {
var hwys = simplify(results[1].features, 0)
.filter(hwy=> {
if (!hwy.properties.ROUTE) { return false; }
hwy.properties.routes = hwy.properties.ROUTE
.split(', ')
.filter(d => { return d.indexOf('SR') < 0 });
return hwy.properties.routes.length;
});
var pts = identifyHubs(hwys);
radiusScale.domain([
0, _.max(pts.map(pt => { return pt.properties.routes.length; }))
]);
states = svg.append('g')
.selectAll(".state")
.data(results[0].features)
.enter().append("path")
.attr('class', 'state')
.attr("d", path);
highways = svg.append('g')
.selectAll("path")
.data(hwys)
.enter().append("path")
.attr('class', 'highway')
.on('click', d=> { highlight(d.properties.routes); })
.attr("d", path);
hubs = svg.append('g')
.selectAll(".hub")
.data(pts)
.enter().append("circle")
.attr('class', 'hub')
.attr("cx", d=> { return _.head(projection(d.geometry.coordinates)); })
.attr("cy", d=> { return _.last(projection(d.geometry.coordinates)); })
.on('click', d=> { highlight(d.properties.routes); })
.transition().delay(500)
.attr('r', d=> { return radiusScale(d.properties.routes.length); });
});
window.addEventListener("load", function() {
document.body.onclick = function(event) {
if (!event.target.classList.contains('hub') &&
!event.target.classList.contains('highway')) {
highlight();
}
};
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment