block by syntagmatic 4653097

Colored Atlantis Projection

Full Screen

A combination of Mike Bostock’s Atlantis projection and Jason Davies’ Automatically Colored World Map

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>
html, body {
  background: #f3f3f3;
}

.country {
  fill: #ccc;
  stroke: #fff;
  stroke-width: .5px;
  stroke-linejoin: round;
}

.graticule {
  fill: none;
  stroke: #000;
  stroke-opacity: .5;
  stroke-width: .5px;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="//d3js.org/topojson.v0.min.js"></script>
<script>

var width = 960,
    height = 880;

var projection = d3.geo.mollweide()
    .rotate([30, -45, 90])
    .scale(150)
    .translate([width * .46, height / 2])
    .precision(.1);

var path = d3.geo.path()
    .projection(projection);

var graticule = d3.geo.graticule()
    .step([10, 10])
    .extent([[-180, -80], [180, 80 + 1e-3]]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "rotate(90 480,480)");

svg.append("g")
    .attr("class", "graticule")
  .selectAll("path")
    .data(graticule.lines)
  .enter().append("path")
    .attr("d", path);

d3.json("readme-world.json", function(error, world) {
  var neighbors = topojson.neighbors(world, world.objects.countries.geometries),
      colors = d3.scale.category10().range().map(function(c) { c = d3.hcl(c); c.c *= .8; c.h = c.h*0.9 + 100; c.l = 60; return c; }),
      nColors = colors.length,
      colorByObject = {};

  world.objects.countries.geometries.forEach(function(o, index) {
    var oNeighbours = neighbors[index] || [],
        m = oNeighbours.length;
    nextColor:
    for (var i = 0; i < nColors; ++i) {
      var color = colors[i];
      for (var j = 0; j < m; ++j) {
        if (colorByObject[oNeighbours[j].id] === color) continue nextColor;
      }
      colorByObject[o.id] = color;
      break;
    }
  });

  svg.selectAll(".country")
      .data(topojson.object(world, world.objects.countries).geometries)
    .enter().insert("path", ".graticule")
      .attr("class", "country")
      .attr("d", path)
      .style("fill", function(d) { return colorByObject[d.id]; });
});

topojson.neighbors = function(topology, objects) {
  var objectsByArc = topology.arcs.map(function() { return []; });

  function line(arcs, index) {
    for (var i = 0, n = arcs.length, arc; i < n; ++i) {
      if ((arc = arcs[i]) < 0) arc = ~arc;
      objectsByArc[arc].push(index);
    }
  }

  function polygon(arcs, i) {
    arcs.forEach(function(arc) { line(arc, i); });
  }

  function geometry(o, i) {
    geometryType[o.type](o.arcs, i);
  }

  var geometryType = {
    LineString: line,
    MultiLineString: polygon,
    Polygon: polygon,
    MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }
  };

  objects.forEach(geometry);

  var neighbors = [];
  objectsByArc.forEach(function(d) {
    if (d.length < 2) return;
    if (!neighbors[d[0]]) neighbors[d[0]] = [];
    if (!neighbors[d[1]]) neighbors[d[1]] = [];
    neighbors[d[0]].push(objects[d[1]]);
    neighbors[d[1]].push(objects[d[0]]);
  });
  return neighbors;
};


d3.select(self.frameElement).style("height", height + "px");

</script>