|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="UFT-8"> |
|
<title>World visualization</title> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script src="http://d3js.org/topojson.v0.min.js"></script> |
|
<style type="text/css"> |
|
path { |
|
stroke: white; |
|
stroke-width: 0.3; |
|
fill: grey; |
|
} |
|
circle { |
|
fill: red; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<svg></svg> |
|
<script type="text/javascript"> |
|
"use strict"; |
|
|
|
var width = 960, |
|
height = 500; |
|
|
|
var projection = d3.geo.mercator() |
|
.center([0, 5]) // defaults to [0,0] |
|
.scale(200) // defaults to 150 |
|
.rotate([-180, 0]); |
|
|
|
var svg = d3.select("svg") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.append("g"); |
|
|
|
var path = d3.geo.path().projection(projection); |
|
|
|
/* |
|
On drawing maps, first load the GeoJSON because is bigger, then the data- |
|
*/ |
|
d3.json("world-110m2.json", function (error, topo) { |
|
|
|
svg.selectAll("path") |
|
.data(topojson.object(topo, topo.objects.countries).geometries) |
|
.enter() |
|
.append("path") |
|
.attr("d", path); |
|
|
|
d3.csv("cities.csv", function (error, data) { |
|
|
|
svg.selectAll("circle") |
|
.data(data) |
|
.enter() |
|
.append("a") |
|
.attr("xlink:href", function (dp) { |
|
return "https://www.google.com/search?q=" + dp.city; |
|
}).attr("target", "_blank") |
|
.append("circle") |
|
.attr("cx", function (dp) { |
|
return projection([+dp.lon, +dp.lat])[0]; |
|
}).attr("cy", function (dp) { |
|
return projection([+dp.lon, +dp.lat])[1]; |
|
}).attr("r", 5); |
|
}); |
|
}); |
|
|
|
// zoom + pan behavior |
|
var zoom = d3.behavior.zoom() |
|
.on("zoom", function () { |
|
svg.attr("transform", "translate( " + d3.event.translate.join(",") + ")scale( " + d3.event.scale + ") "); |
|
svg.selectAll("circle").attr("d", path.projection(projection)); |
|
svg.selectAll("path").attr("d", path.projection(projection)); |
|
}); |
|
|
|
svg.call(zoom); |
|
</script> |
|
</body> |
|
</html> |