block by syntagmatic 3719520

Stereographic to Cylindrical Transitions

Full Screen

The extent of the graticules goes from -179 to 179 to avoid breaking the stereographic projection.

index.html

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  height: 500px;
  position: relative;
  width: 960px;
}

#projection-menu {
  position: absolute;
  right: 10px;
  top: 10px;
}

.background {
  fill: #a4bac7;
}

.foreground {
  fill: none;
  stroke: #333;
  stroke-width: 1.5px;
}

.graticule {
  fill: none;
  stroke: #fff;
  stroke-width: .5px;
}

.graticule:nth-child(2n) {
  stroke-dasharray: 2,2;
}

.land {
  fill: #d7c7ad;
  stroke: #766951;
}

.boundary {
  fill: none;
  stroke: #a5967e;
}

</style>
<select id="projection-menu">
  <option value="aitoff">Aitoff</option>
  <option value="albers">Albers</option>
  <!--<option value="azimuthal">Azimuthal</option>-->
  <option value="bonne">Bonne</option>
  <option value="equirectangular">Plate Carrée</option>
  <option value="kavrayskiy7">Kavrayskiy VII</option>
  <option value="mercator">Mercator</option>
  <option value="robinson">Robinson</option>
  <option selected value="stereographic">Stereographic</option>
  <!--<option value="gnomonic">Gnomonic</option>-->
  <option value="wagner6">Wagner VI</option>
  <option value="winkel3">Winkel Tripel</option>
</select>
<script src="//d3js.org/d3.v2.js"></script>
<script src="https://raw.github.com/d3/d3-plugins/master/geo/projection/projection.js"></script>
<script>

var width = 960,
    height = 500;

var path = d3.geo.path()
    .projection(d3.geo.azimuthal()
      .mode("stereographic")
      .translate([width / 2 - .5, height / 2 - .5]));

var graticule = d3.geo.graticule()
  .extent([[-179,-90],[179,90]]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

svg.append("path")
    .datum(graticule.outline)
    .attr("class", "background")
    .attr("d", path);

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

svg.append("path")
    .datum(graticule.outline)
    .attr("class", "foreground")
    .attr("d", path);

var menu = d3.select("#projection-menu").on("change", change),
    interval = setInterval(loop, 1500),
    i = 0,
    n = menu.selectAll("option")[0].length - 1;

function loop() {
  var j = Math.floor(Math.random() * n);
  update(menu.property("selectedIndex", i = j + (j >= i)).property("value"));
}

function change() {
  clearInterval(interval);
  update(this.value);
}

// hackety hack continued ... 
d3.geo.stereographic = d3.geo.azimuthal;
d3.geo.gnomonic = d3.geo.azimuthal;

function update(value) {
  projection = d3.geo[value]().translate([width / 2 - .5, height / 2 - .5]);
  if (value === "equirectangular") projection.scale(960);
  if (value === "albers") projection.scale(70);
  if (value === "azimuthal") projection.mode("orthographic");
  // ... here
  if (value === "stereographic") projection.mode("stereographic");
  if (value === "gnomonic") projection.mode("gnomonic");
  svg.selectAll("path").transition().duration(750).attr("d", path.projection(projection));
}

</script>