Jody from Tap Twice Tea's destinations on his current trip across Asia. Map made with d3. Thanks Mike Bostock for the great Let's Make a Map tutorial.
Last active
August 29, 2015 14:16
-
-
Save dhoboy/e4adef805c96307f5867 to your computer and use it in GitHub Desktop.
Jody's Journey: destinations
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> | |
<meta charset="utf-8"> | |
<style> | |
.country { | |
fill: #B8B8B8; | |
} | |
.interior-boundary { | |
fill: none; | |
stroke: #FFFFFF; | |
stroke-dasharray: 2,2; | |
stroke-linejoin: round; | |
} | |
.place, | |
.place-label { | |
fill: #444; | |
} | |
text { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
font-size: 10px; | |
pointer-events: none; | |
} | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.js"></script> | |
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script> | |
<script src="http://d3js.org/topojson.v1.js"></script> | |
<script> | |
var width = 1000, | |
height = 590; | |
// draw svg | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
// map projection | |
var projection = d3.geo.patterson() | |
.center([58,54]) | |
.scale(520) | |
.translate([0,0]) | |
.precision(.1); | |
// path generator | |
var path = d3.geo.path() | |
.projection(projection) | |
.pointRadius(1.5); | |
// coordinates are added when constructRoute is called | |
var journey = [ | |
{name:"Kolkata", dates:"Feb. 17 - 22"}, | |
{name:"Darjeeling", dates:"Feb. 23 - 28"}, | |
{name:"Nepal", dates:"March 1 - 6"}, | |
{name:"Myanmar", dates:"March 7 - 10"}, | |
{name:"Cambodia", dates:"March 11 - 13"}, | |
{name:"Laos", dates:"March 14 - 18"}, | |
{name:"Xishuangbanna", dates:"March 18 - 21"}, | |
{name:"Anhui", dates:"March 22 - 28"}, | |
{name:"Fujian", dates:"March 29 - 31"}, | |
{name:"Wuyi", dates:"April 1 - 6"}, | |
{name:"Qingdao", dates:"April 6 - 10"}, | |
{name:"Lishan", dates:"April 11 - 14"}, | |
{name:"Nantou", dates:"April 15 - 18"}, | |
{name:"Alishan", dates:"April 18 - 20"}, | |
{name:"Taiwan", dates:"April 21 - 26"}, | |
{name:"Shizuoka", dates:"April 27 - May 1"}, | |
{name:"Uji", dates:"May 2 - 4"}, | |
{name:"Kyoto", dates:"May 4 - 8"} | |
]; | |
d3.json("asia.json", function(error, asia) { | |
var subunits = topojson.feature(asia, asia.objects.subunits), | |
places = topojson.feature(asia, asia.objects.places), | |
route = constructRoute(journey, places.features); | |
// draw the map | |
svg.selectAll(".subunit") | |
.data(subunits.features) | |
.enter() | |
.append("path") | |
.attr("class", function(d) { return "country"; }) | |
.attr("d", path); | |
// draw interior boundaries between countries | |
svg.append("path") | |
.datum(topojson.mesh(asia, asia.objects.subunits, function(a, b) { | |
return a !== b; | |
})) | |
.attr("d", path) | |
.attr("class", "interior-boundary"); | |
// draw places on map | |
svg.append("path") | |
.datum(places) | |
.attr("d", path) | |
.attr("class", "place"); | |
// set all place labels | |
svg.selectAll(".place-label") | |
.data(places.features) | |
.enter() | |
.append("text") | |
.attr("class", function(d) { return "place-label " + d.properties.name; }) | |
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; }) | |
.attr("x", function(d) { return d.geometry.coordinates[0] > -1 ? 6 : -6; }) | |
.attr("dy", ".35em") | |
.style("text-anchor", function(d) { return d.geometry.coordinates[0] > -1 ? "start" : "end"; }) | |
.text(function(d) { return d.properties.name; }); | |
// adjust Kyoto and Nantou labels | |
svg.select(".place-label.Kyoto") | |
.attr("x", -30) | |
.attr("dy", ".15em"); | |
// probably a better way than these magic numbers... | |
svg.select(".place-label.Nantou") | |
.attr("x", -38) | |
.attr("dy", ".15em"); | |
}); | |
function constructRoute(journey, places) { | |
// forming route for the path generator | |
var route = { | |
type: "LineString", | |
coordinates: [] | |
}; | |
// add coords to journey and route | |
journey.forEach(function(d) { | |
places.forEach(function(p) { | |
if (d.name == p.properties.name) { | |
d.coords = p.geometry.coordinates; | |
} | |
}) | |
route.coordinates.push(d.coords); | |
}); | |
return route; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment