Example drawing multiple geometries from GeoJSON to a D3.js map.
Last active
June 30, 2019 05:55
-
-
Save rgdonohue/366468f3f5f19a83303d7b2fbbfa2ece to your computer and use it in GitHub Desktop.
Atlanta Urban Geographies
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> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Atlanta Urban Geographies</title> | |
<style> | |
body, | |
#map { | |
position: absolute; | |
width: 100%; | |
top: 0; | |
bottom: 0; | |
margin: 0; | |
padding: 0; | |
background: rgba(0, 0, 0, .6); | |
font-family: sans-serif; | |
} | |
.tooltip { | |
color: white; | |
background: #295b97; | |
border: 0; | |
font-size: .8em; | |
} | |
.urban { | |
fill: '#295b97'; | |
} | |
.city-limits { | |
fill: none; | |
stroke: #040d18; | |
stroke-width: 3; | |
} | |
.neighborhoods { | |
fill: #e0ecf9; | |
fill-opacity: .3; | |
stroke: #151f2b; | |
stroke-width: .7; | |
} | |
.subways { | |
fill: none; | |
stroke: #ff6e00; | |
stroke-width: 2; | |
} | |
.buses { | |
stroke: #f0f062; | |
stroke-width: .2; | |
fill: none; | |
} | |
.trams { | |
fill: none; | |
stroke: #ff6e00; | |
stroke-width: 3; | |
} | |
.other { | |
stroke: #ff6e00; | |
fill: none; | |
} | |
div.tooltip { | |
position: absolute; | |
padding: 4px 8px; | |
border-radius: 3px; | |
pointer-events: none; | |
color: white; | |
background: #295b97; | |
font-size: 1.3em; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script src="https://d3js.org/d3.v5.min.js"></script> | |
<script> | |
// select our div element | |
var mapContainer = d3.select('#map') | |
// derive the width and height | |
var width = mapContainer.node().getBoundingClientRect().width, | |
height = mapContainer.node().getBoundingClientRect().height | |
// attach a new SVG element and enable pan/zooming | |
var map = mapContainer.append('svg') | |
.attr('width', width) | |
.attr('height', height) | |
.call(d3.zoom().on("zoom", function () { | |
map.attr("transform", d3.event.transform) | |
})) | |
.on("dblclick.zoom", null) | |
.append("g") | |
// deferred requests for all the data files | |
var urbanAreasJson = d3.json('atlanta-urban.json'), | |
cityLimitsJson = d3.json('city-limits.json'), | |
neighborhoodsJson = d3.json('neighborhoods.json'), | |
transitRoutesJson = d3.json('transit-routes-simplified.json') | |
// when they're all loaded and available, send data to drawMap function | |
Promise.all([urbanAreasJson, cityLimitsJson, neighborhoodsJson, transitRoutesJson]).then(drawMap) | |
function drawMap(data) { | |
// transverse mercator projection for Atlanta | |
var projection = d3.geoTransverseMercator() | |
.rotate([83 + 10 / 60, -32]) | |
.fitSize([width, height], data[1]) // fit the extend to the urban area data | |
// create a path generator | |
var geoPath = d3.geoPath() | |
.projection(projection) | |
// append an empty div to the body with class tooltip | |
var div = d3.select("body").append("div") | |
.attr("class", "tooltip") | |
.style("opacity", 0) // hide visibility | |
// append a new group element | |
// and draw paths for the urban footprint | |
map.append('g') | |
.selectAll('path') | |
.data(data[0].features) | |
.enter() | |
.append('path') | |
.attr('d', geoPath) | |
.attr('class', 'urban') | |
// add the city limits | |
map.append('g') | |
.selectAll('path') | |
.data(data[1].features) | |
.enter() | |
.append('path') | |
.attr('d', geoPath) | |
.attr('class', 'city-limits') | |
// add the neighborhoods | |
map.append('g') | |
.selectAll('path') | |
.data(data[2].features) | |
.enter() | |
.append('path') | |
.attr('d', geoPath) | |
.attr('class', 'neighborhoods') | |
.on('mouseover', function(d) { | |
// provide visual affordance of target neighborhood | |
d3.select(this).style('fill-opacity', 1) | |
// populate the tooltip with info and position near the event | |
div.html(d.properties.NAME) | |
.style("left", (d3.event.pageX) + "px") | |
.style("top", (d3.event.pageY - 28) + "px") | |
// fade in the opacity | |
div.transition().style("opacity", 1) | |
}) | |
.on('mouseout', function() { | |
// return opacity of SVG to original | |
d3.select(this).style('fill-opacity', .3) | |
// fade out the tooltip | |
div.transition().style("opacity", 0) | |
}) | |
// add the transit | |
map.append('g') | |
.selectAll('path') | |
.data(data[3].features) | |
.enter() | |
.append('path') | |
.attr('d', geoPath) | |
.attr('class', function (d) { | |
// apply a particular class name based on the type | |
var type = d.properties.type | |
return type === 'Bus' ? 'buses' : | |
type === 'SUBWAY' ? 'subways' : | |
type === 'TRAM' ? 'trams' : 'other' | |
}) | |
} | |
</script> | |
</body> | |
</html> |
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