block by emeeks af3c0114adfd9ead565e6c0f4a9c494e

d3.geoPath.area recoloring on drag

Full Screen

Drag the globe to rotate it, countries are re-colored based on their graphical area. Sorry, Europe, your countries are too small to see any difference.

index.html

<html>
<head>
   <style>
		path.graticule {
		     fill: none;
		     stroke-width: 1;
		     stroke: #9A8B7A;
		}
		path.graticule.outline {
		     fill: none;
		     stroke: #9A8B7A;
		}
    </style>
</head>
 <script src="https://d3js.org/d3.v4.js" type="text/JavaScript"></script>
<script src="https://d3js.org/d3-geo-projection.v1.min.js"></script>

<body>
   <div id="vizcontainer">
   <svg style="width:500px;height:500px;" />
   </div>
   <script type="text/javascript">

d3.json("world.geojson", createMap)

function createMap(countries) {

var projection = d3.geoOrthographic()
   .scale(200)
   .translate([250,250])
   .center([0,0])
   .rotate([0,0])


var geoPath = d3.geoPath().projection(projection);
var featureSize = d3.extent(countries.features, function(d) { return geoPath.area(d)})
var countryColor = d3.scaleQuantize()
              .domain(featureSize).range(["#cdc597","#a4b77d","#72972f","#36611b","#113719"]);

d3.select("svg").selectAll("path").data(countries.features)
     .enter()
     .append("path")
     .attr("d", geoPath)
     .attr("class", "countries")
     .style("fill", function(d) { return countryColor(geoPath.area(d))})
     .style("stroke", function(d) { return d3.rgb(countryColor(geoPath.area(d))).darker()})

var graticule = d3.geoGraticule();
d3.select("svg").insert("path", "path.countries")
  .datum(graticule)
  .attr("class", "graticule line")
  .attr("d", geoPath)
d3.select("svg").insert("path", "path.countries")
  .datum(graticule.outline)
  .attr("class", "graticule outline")
  .attr("d", geoPath)

var mapZoom = d3.zoom()
   .on("zoom", zoomed)

var zoomSettings = d3.zoomIdentity
    .translate(0, 0)
    .scale(200)

var rotateScale = d3.scaleLinear()
  .domain([-500, 0, 500])
  .range([-180, 0, 180]);

d3.select("svg")
  .call(mapZoom)
  .call(mapZoom.transform, zoomSettings)


function zoomed() {
  var e = d3.event
  var currentRotate = rotateScale(e.transform.x) % 360

  projection
    .rotate([currentRotate, 0])
    .scale(e.transform.k)

  d3.selectAll("path.graticule").attr("d", geoPath);
  d3.selectAll("path.countries").attr("d", geoPath)
     .style("fill", function(d) { return countryColor(geoPath.area(d))})
     .style("stroke", function(d) { return d3.rgb(countryColor(geoPath.area(d))).darker()})

  }
}

   </script>
</body>
<footer>
</html>