A digital version of the world map above our kitchen table.
Install dev dependencies:
npm install
Reproduce the map:
npm run map
height: 500 | |
license: MIT |
node_modules | |
npm-debug.log |
code | |
AUS | |
AUT | |
BEL | |
BHR | |
BRA | |
BFA | |
KHM | |
CHN | |
HKG | |
CZE | |
DNK | |
EGY | |
EST | |
FRA | |
DEU | |
GHA | |
GIB | |
GUY | |
HUN | |
VAT | |
IDN | |
ITA | |
LUX | |
MYS | |
MCO | |
MAR | |
MMR | |
MYS | |
NPL | |
NLD | |
NOR | |
NZL | |
OMN | |
POL | |
PRT | |
ROU | |
SGP | |
SVK | |
ESP | |
SUR | |
SWE | |
CHE | |
THA | |
TUR | |
ARE | |
GBR | |
USA | |
VNM | |
GRC |
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
font-size: 10px; | |
font-family: sans-serif; | |
font-weight: bold; | |
text-anchor: left; | |
} | |
text { | |
fill: #999; | |
} | |
.mesh { | |
fill: none; | |
stroke: #999; | |
stroke-linejoin: round; | |
} | |
.country { | |
fill: none; | |
} | |
.visited { | |
fill: #8c96c6; | |
opacity: 0.5; | |
} | |
.country-NLD { | |
fill: #fe9929; | |
opacity: 1; | |
} | |
</style> | |
<body></body> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src='https://d3js.org/d3-queue.v2.min.js'></script> | |
<script src="https://d3js.org/topojson.v1.min.js"></script> | |
<script> | |
var margin = {top: 10, right: 10, bottom: 10, left: 10}, | |
width = 900 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var projection = d3.geoMercator() | |
.translate([width / 2, height / 2]) | |
.center([0, 25]) | |
.scale(140); | |
var path = d3.geoPath() | |
.projection(projection); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("class", "g-map") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
d3.queue() | |
.defer(d3.json, "world-50m.json") | |
.defer(d3.csv, "countries.csv") | |
.await(ready); | |
function ready(error, geo, countries) { | |
if (error) return console.error(error); | |
var visited = d3.entries(countries).map(function(d){ return d.value.code; }).slice(0, -1); | |
svg.selectAll(".area") | |
.data(topojson.feature(geo, geo.objects.ne_50m_admin_0_countries).features).enter() | |
.append("path") | |
.attr("class", function(d) { return "country country-" + d.id; }) | |
.attr("d", path) | |
.classed("visited", function(d) { return visited.indexOf(d.id) >= 0; }); | |
svg.append("path") | |
.datum(topojson.mesh(geo)) | |
.attr("class", "mesh") | |
.attr("d", path); | |
svg.append("g").append("text") | |
// .attr("dx", 0) | |
.text(function() { return "Visited " + visited.length + " / " + geo.objects.ne_50m_admin_0_countries.geometries.length + " (" + | |
d3.format(".0%")(visited.length / geo.objects.ne_50m_admin_0_countries.geometries.length, 2) + ")"; }); | |
} | |
</script> |
{ | |
"name": "scratch-the-world", | |
"version": "0.0.1", | |
"description": "Mapping of visited countries", | |
"keywords": [ | |
"Travel", | |
"Visualization", | |
"D3.js", | |
"World map" | |
], | |
"author": "Hugo Janssen <nl-hugo@hugojanssen.nl>", | |
"private": true, | |
"license": "MIT", | |
"devDependencies": { | |
"download-cli": "~1.0", | |
"topojson": "~1.6", | |
"rimraf": "latest", | |
"ogr2ogr": "~0.5" | |
}, | |
"scripts": { | |
"clean": "rm -rf ne_50m_admin_0_countries.*", | |
"download": "download --extract http://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_0_countries.zip", | |
"geojson": "ogr2ogr -f GeoJSON ne_50m_admin_0_countries.json ne_50m_admin_0_countries.shp", | |
"topojson": "topojson -o world-50m.json --id-property adm0_a3 --properties name=admin -- ne_50m_admin_0_countries.json", | |
"map": "npm run download && npm run geojson && npm run topojson && npm run clean" | |
} | |
} |