To view the responsive attributes of the map, open it in a new window.
Last active
June 1, 2017 17:02
-
-
Save aholachek/700f930820f2704a957c070173327789 to your computer and use it in GitHub Desktop.
Very simple responsive map of Asia
This file contains 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
// load the data, find the svg container in the dom, | |
// and call createMap | |
d3.json('map-data.json', function(error, data){ | |
var svg = d3.select('svg') | |
createMap(svg, data) | |
}) | |
// put all logic in a nice reusable function | |
function createMap(svg, data) { | |
// use viewBox attributes instead of width + height | |
var params = svg.attr('viewBox').split(' ').map(function (n) { return parseInt(n, 10); }) | |
var width = params[2] | |
var height = params[3] | |
var mapContainer = svg.append('g') | |
var projection = d3.geoMercator() | |
// d3's 'fitSize' magically sizes and positions the map for you | |
.fitSize([width, height], data); | |
// this is the function that generates position data from the projection | |
var path = d3.geoPath() | |
.projection(projection); | |
// append country outlines | |
var countries = mapContainer.selectAll('.country') | |
.data(data.features) | |
.enter() | |
.append('path') | |
.attr('class', 'country') | |
.attr('d', path) | |
.on('click', function(d){ | |
var d3this = d3.select(this) | |
if (d3this.classed('active')){ | |
d3.selectAll('.country').classed('active', false); | |
return | |
} | |
d3.selectAll('.country').classed('active', false); | |
d3.select(this).classed('active', true); | |
}); | |
// append labels | |
mapContainer | |
.selectAll('.label') | |
.data(data.features) | |
.enter() | |
.append('text') | |
.attr('class', 'label') | |
.text(function (d){ return d.properties.admin; }) | |
.attr('transform', function (d){ | |
var centroid = path.centroid(d) | |
return ("translate(" + (centroid[0]) + ", " + (centroid[1]) + ")") | |
}) | |
} | |
This file contains 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"> | |
<style> | |
body { | |
/* system font stack*/ | |
font-family: -apple-system, | |
system-ui, | |
BlinkMacSystemFont, | |
"Segoe UI", | |
"Roboto", | |
"Helvetica Neue", | |
Arial, | |
sans-serif; | |
color: hsl(0, 0%, 20%); | |
} | |
.country { | |
fill : hsla(0, 0%, 50%, 0.4); | |
stroke:white; | |
stroke-width: 1.5px; | |
cursor: pointer; | |
} | |
.country:hover { | |
fill : hsla(0, 0%, 50%, .6); | |
} | |
.country.active { | |
fill: hsl(0, 100%, 75%); | |
} | |
.country.active:hover { | |
fill: hsl(0, 100%, 75%); | |
} | |
.label { | |
font-size: .8rem; | |
text-anchor: middle; | |
fill: hsl(0, 0%, 20%); | |
/* don't allow labels to interfere with country clicks and hovers */ | |
pointer-events: none; | |
} | |
/* responsive set up */ | |
.svg-container { | |
display:inline-block; | |
position:relative; | |
width:100%; | |
padding-bottom:52%; | |
vertical-align:middle; | |
overflow: hidden; | |
} | |
.svg { | |
display:inline-block; | |
position:absolute; | |
top:0; | |
left: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="svg-container"> | |
<svg viewBox='0 0 960 500' preserveAspectRatio='xMinYMin'/> | |
</div> | |
<script src="//d3js.org/d3.v4.min.js"></script> | |
<script src=".script-compiled.js"></script> | |
</body> | |
</html> |
This file contains 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
// load the data, find the svg container in the dom, | |
// and call createMap | |
d3.json('map-data.json', function(error, data){ | |
const svg = d3.select('svg') | |
createMap(svg, data) | |
}) | |
// put all logic in a nice reusable function | |
function createMap(svg, data) { | |
// use viewBox attributes instead of width + height | |
const params = svg.attr('viewBox').split(' ').map((n) => parseInt(n, 10)) | |
const width = params[2] | |
const height = params[3] | |
const mapContainer = svg.append('g') | |
const projection = d3.geoMercator() | |
// d3's 'fitSize' magically sizes and positions the map for you | |
.fitSize([width, height], data); | |
// this is the function that generates position data from the projection | |
const path = d3.geoPath() | |
.projection(projection); | |
// append country outlines | |
const countries = mapContainer.selectAll('.country') | |
.data(data.features) | |
.enter() | |
.append('path') | |
.attr('class', 'country') | |
.attr('d', path) | |
.on('click', function(d){ | |
const d3this = d3.select(this) | |
if (d3this.classed('active')){ | |
d3.selectAll('.country').classed('active', false); | |
return | |
} | |
d3.selectAll('.country').classed('active', false); | |
d3.select(this).classed('active', true); | |
}); | |
// append labels | |
mapContainer | |
.selectAll('.label') | |
.data(data.features) | |
.enter() | |
.append('text') | |
.attr('class', 'label') | |
.text((d)=> d.properties.admin) | |
.attr('transform', (d)=> { | |
const centroid = path.centroid(d) | |
return `translate(${centroid[0]}, ${centroid[1]})` | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment