Climatologist Irving I. Gringorten published this little-known equal-area projection in 1972.
It is available as d3.geo.gringorten in the geo.projection D3 plugin.
Climatologist Irving I. Gringorten published this little-known equal-area projection in 1972.
It is available as d3.geo.gringorten in the geo.projection D3 plugin.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| body { | |
| font-family: sans-serif; | |
| } | |
| .background { | |
| fill: #fff; | |
| } | |
| .foreground { | |
| fill: none; | |
| stroke: #333; | |
| stroke-width: 1.5px; | |
| } | |
| .graticule { | |
| fill: none; | |
| stroke: #000; | |
| stroke-width: .5px; | |
| } | |
| .graticule:nth-child(2n) { | |
| stroke-dasharray: 2,2; | |
| } | |
| .land { | |
| fill: #eee; | |
| stroke: #000; | |
| stroke-width: .5px; | |
| } | |
| .boundary { | |
| fill: none; | |
| stroke: #999; | |
| stroke-width: .5px; | |
| } | |
| </style> | |
| <label for="quincuncial"><input type="checkbox" id="quincuncial" checked> Quincuncial</label> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script src="http://d3js.org/d3.geo.projection.v0.min.js"></script> | |
| <script> | |
| var width = 960, | |
| height = 500, | |
| initial = [0, 0, 0], | |
| velocity = [.005, 0], | |
| rotate = initial.slice(), | |
| t0 = Date.now(), | |
| transitioning = false; | |
| var projection = d3.geo.gringorten().translate([width / 2 - .5, height / 2 - .5]).scale(150), | |
| path = d3.geo.path().projection(projection); | |
| var graticule = d3.geo.graticule().extent([[-180, -80], [180, 80]]), | |
| graticuleS = d3.geo.graticule().extent([[-180, -90 + 1e-6], [180, -80 + 1e-6]]).step([90, 10]), // TODO allow negative step size? e.g. -90 to -80, step -10. | |
| graticuleN = d3.geo.graticule().extent([[-180, 80], [180, 90]]).step([90, 10]); | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width) | |
| .attr("height", height) | |
| .call(d3.behavior.drag() | |
| .origin(function() { return {x: rotate[0], y: -rotate[1]}; }) | |
| .on("dragstart", function() { transitioning = true; }) | |
| .on("drag", function(d) { | |
| rotate[0] = d3.event.x; | |
| rotate[1] = -d3.event.y; | |
| projection.rotate(rotate); | |
| svg.selectAll("path").attr("d", path); | |
| }) | |
| .on("dragend", function() { | |
| transitioning = false; | |
| t0 = Date.now(); | |
| initial = rotate.slice(); | |
| })); | |
| d3.select("#quincuncial").on("change", change); | |
| projection.rotate(initial); | |
| svg.append("rect").attr("class", "background"); | |
| svg.selectAll(".graticule") | |
| .data(graticule.lines().concat(graticuleS.lines()).concat(graticuleN.lines())) | |
| .enter().append("path") | |
| .attr("class", "graticule"); | |
| svg.append("rect").attr("class", "foreground"); | |
| change(); | |
| function change() { | |
| projection.quincuncial(this.checked).rotate([0, 0, 0]); | |
| svg.selectAll("path").attr("d", path); | |
| var dx = projection([180, 0])[0] - projection([-180, 0])[0], | |
| dy = Math.abs(projection([0, -90])[1] - projection([0, 90])[1]); | |
| svg.selectAll("rect") | |
| .attr("transform", "translate(" + projection([0, 0]) + ")") | |
| .attr("x", -dx / 2) | |
| .attr("y", -dy / 2) | |
| .attr("width", dx) | |
| .attr("height", dy); | |
| projection.rotate(rotate); | |
| } | |
| d3.json("/d/3682676/readme-boundaries.json", function(err, collection) { | |
| svg.insert("g", ".graticule") | |
| .attr("class", "boundary") | |
| .selectAll("path") | |
| .data(collection.geometries) | |
| .enter().append("path") | |
| .attr("d", path); | |
| }); | |
| d3.json("/d/3682676/readme-land.json", function(err, collection) { | |
| svg.insert("g", ".graticule,.boundary") | |
| .attr("class", "land") | |
| .selectAll("path") | |
| .data(collection.geometries) | |
| .enter().append("path") | |
| .attr("d", path); | |
| }); | |
| d3.timer(function() { | |
| if (transitioning) return; | |
| var t = Date.now() - t0; | |
| rotate[0] = initial[0] + velocity[0] * t; | |
| rotate[1] = initial[1] + velocity[1] * t; | |
| projection.rotate(rotate); | |
| svg.selectAll("path").attr("d", path); | |
| }); | |
| </script> |