See discussion on Hacker News. Built with D3 and TopoJSON.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| h1 { | |
| position: absolute; | |
| top: 500px; | |
| font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
| font-size: 18px; | |
| text-align: center; | |
| width: 960px; | |
| } | |
| </style> | |
| <h1></h1> | |
| <script src="//d3js.org/d3.v3.min.js"></script> | |
| <script src="//d3js.org/queue.v1.min.js"></script> | |
| <script src="//d3js.org/topojson.v1.min.js"></script> | |
| <script> | |
| var width = 960, | |
| height = 960; | |
| var projection = d3.geo.orthographic() | |
| .translate([width / 2, height / 2]) | |
| .scale(width / 2 - 20) | |
| .clipAngle(90) | |
| .precision(0.6); | |
| var canvas = d3.select("body").append("canvas") | |
| .attr("width", width) | |
| .attr("height", height); | |
| var c = canvas.node().getContext("2d"); | |
| var path = d3.geo.path() | |
| .projection(projection) | |
| .context(c); | |
| var title = d3.select("h1"); | |
| queue() | |
| .defer(d3.json, "/mbostock/raw/4090846/world-110m.json") | |
| .defer(d3.tsv, "/mbostock/raw/4090846/world-country-names.tsv") | |
| .await(ready); | |
| function ready(error, world, names) { | |
| if (error) throw error; | |
| var globe = {type: "Sphere"}, | |
| land = topojson.feature(world, world.objects.land), | |
| countries = topojson.feature(world, world.objects.countries).features, | |
| borders = topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }), | |
| i = -1, | |
| n = countries.length; | |
| countries = countries.filter(function(d) { | |
| return names.some(function(n) { | |
| if (d.id == n.id) return d.name = n.name; | |
| }); | |
| }).sort(function(a, b) { | |
| return a.name.localeCompare(b.name); | |
| }); | |
| (function transition() { | |
| d3.transition() | |
| .duration(1250) | |
| .each("start", function() { | |
| title.text(countries[i = (i + 1) % n].name); | |
| }) | |
| .tween("rotate", function() { | |
| var p = d3.geo.centroid(countries[i]), | |
| r = d3.interpolate(projection.rotate(), [-p[0], -p[1]]); | |
| return function(t) { | |
| projection.rotate(r(t)); | |
| c.clearRect(0, 0, width, height); | |
| c.fillStyle = "#ccc", c.beginPath(), path(land), c.fill(); | |
| c.fillStyle = "#f00", c.beginPath(), path(countries[i]), c.fill(); | |
| c.strokeStyle = "#fff", c.lineWidth = .5, c.beginPath(), path(borders), c.stroke(); | |
| c.strokeStyle = "#000", c.lineWidth = 2, c.beginPath(), path(globe), c.stroke(); | |
| }; | |
| }) | |
| .transition() | |
| .each("end", transition); | |
| })(); | |
| } | |
| d3.select(self.frameElement).style("height", height + "px"); | |
| </script> |
espinielli
commented
Mar 11, 2013
sherryyur
commented
Aug 26, 2013
Map doesn't load in IE9/10 .
SCRIPT438: Object doesn't support property or method 'transition'
d3.v3.min.js, line 4 character 29727
awc-fueled
commented
Jan 9, 2014
Where can I find the tsv and json files?
martinbarnard
commented
Mar 20, 2014
Go poking in https://gist.github.com/mbostock/4090846 and you'll find the data :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think there is a bug. to see it you let the animation run long enough and get over all the first 174 countries.
So after Zimbawe you get
In fact, this is due to the fact that =n=, the number of countries to iterate through is initialized before the array is filtered. =n= should be set after the filter like:
In my own fork I made the tour random as well:
HTH