block by hugolpz e803a946b571a79e1b05

From pixelized to curvy lines

Full Screen

Fork of E. Meeks’ work. An example of how to project coordinates of geodata features and then use those for d3.svg.line to take advantage of built-in line interpolators.

Improvements: minors, for code readability, dataviz display.

See also :

index.html

<html xmlns="//www.w3.org/1999/xhtml">
<head>
  <title>Interpolating Geodata</title>
  <meta charset="utf-8" />
</head>
<style>
  html,body {
    height: 100%;
    width: 100%;
    margin: 0;
  }

  #map {
    height: 100%;
    width: 100%;
    position: absolute;
  }
  svg {
    height: 100%;
    width: 100%;
    position: absolute;
  }  

</style>
<script src="//code.jquery.com/jquery-2.0.2.min.js"></script>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script src="//d3js.org/d3.geo.projection.v0.min.js" type="text/javascript"></script>

<script src="../js/jquery-2.0.1.min.js"></script>
<script src="../js/d3.v3.min.js"></script>
<script src="../js/d3.geo.projection.v0.min.js"></script>

<script src="../js/topojson.v1.min.js"></script>


<script>


function inter() {
  d3.json("./world.geojson", 
		  function(data) { createMap(data) }
		 );
  
  function createMap(countries) {
	// Settings
    width = 800;
    height = 500;
    projection = d3.geo.mercator()
    	.scale(200)
    	.translate([width / 2, height / 2])

    geoPath = d3.geo.path().projection(projection);
 
	// Rounding ?
    roundedCountries = [];  
    for (x in countries.features) {
      for (y in countries.features[x].geometry.coordinates) {
        if (countries.features[x].geometry.coordinates[y].length > 1) {
          roundedCountries.push(
			  	countries.features[x]
				.geometry.coordinates[y]
				.map(function(d) {return projection(d)} )
				)
        }
        else {
          roundedCountries.push(
			  countries.features[x]
			  .geometry.coordinates[y][0]
			  .map(function(d) {return projection(d)})
		  )
        }
      }
    }
// Curving type:
    interpolateMethods = ["linear", "cardinal", "basis", "monotone", "step-before"]
    var n = 1;
	  
// Legend:
	  d3.select("svg")
	  	.append("text")
	  		.attr("id", "inter")
			.attr("x", 40)
			.attr("y", 40)
	  		.style("font-size", "1.8em")
			.text(interpolateMethods[n])

// Map drawing
    d3.select("svg").selectAll("path")
		.data(roundedCountries)
		.enter()
		.append("path")
		.style("stroke-width", 1)
		.style("stroke", "black")
		.style("fill-opacity", .5)


    reinterpolate();
    
    function reinterpolate() {
		colorScale = ["#7fc97f","#beaed4","#fdc086","#ffff99","#386cb0"];
		  if (n == 5) {
			n = 0;
		  }
// Legend update
		d3.select("#inter")
			.text(interpolateMethods[n])
// map update
		d3.select("svg").selectAll("path")
			.style("fill", colorScale[n])
    	.attr("d", d3.svg.line()
			.x(function(d){ return d[0]})
			.y(function(d){ return d[1]})
			.interpolate(interpolateMethods[n]) );

		setTimeout(reinterpolate,2000);
		n++;
    }
    
    
  }
  
}
</script>
<body onload="inter()">
<div id="map"><svg></svg></div>
<footer>
</footer>
</body>
</html>