block by dhoboy e4adef805c96307f5867

Jody's Journey: destinations

Full Screen

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.

index.html

<!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="//d3js.org/d3.v3.js"></script>
<script src="//d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="//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>