How to create a choropleth of the world using d3?

2019-03-13 08:35发布

问题:

This tutorial is a great intro to creating choropleths with d3, but it's data is US-centric. Where do I get the corresponding data for a world map?

I'm sure it's in the docs somewhere, but I can't find it. This is the closest I've found, but the one world map on there specifically says it's not recommended for choropleths. Also,

回答1:

NOTE: This answer was written for version 2 of d3. Version 3 is out now, and it has awesome new features that create better geometry segmentation and solve the fill issue mentioned below. Also, the interface for setting up projections _may_ have changed in V3 (not sure bc I haven't tried).

There is a json file available for the entire world, and you can render it equivalently to the us-states.json coropleth (using an Albers equal area projection) – assuming you understand (and are ok with) the fact that an Albers-projected world map looks like this, which is not quite how most people recognize a world map.

First you need the json data for the entire world, which is the same data used by the world mercator projection example.

Then you need to render the world json data using a customized Albers projection:

<!DOCTYPE html>
<meta charset="utf-8">
<title>Mercator Projection</title>

<style>
  path {
    fill: #ccc;
    stroke: #fff;
  }
</style>

<svg width="960" height="500"></svg>

<script src="http://d3js.org/d3.v2.js?2.9.1"></script>
<script type="text/javascript">
  d3.json("world-countries.json", function(collection) {
    d3.select("svg").selectAll("path")
        .data(collection.features)
      .enter().append("path")
        .attr("d", d3.geo.path().projection(
          d3.geo.albers()
            .parallels([10, 80])
            .origin([0,40])
            .translate([500,250])
            .scale(100)
        ));
  });
</script>

origin(), parallels(), translate(), and scale() values can be tweaked to get different results.

There's a problem with Antartica, which – due to the nature of this projection – gets "flipped" and is not a closed shape, so its fill covers the whole world. You either have to remove it from the json, or don't apply fill to it.

Also for some reason Brazil (and couple of others) didn't get rendered properly when I tried this. Dunno why. You'd have to examine the svg and the data to figure out why.



标签: map d3.js