Skip to content

Instantly share code, notes, and snippets.

@jasondavies
Forked from jasondavies/README.md
Created September 27, 2012 22:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasondavies/3796882 to your computer and use it in GitHub Desktop.
Save jasondavies/3796882 to your computer and use it in GitHub Desktop.
Gringorten Equal-Area Projection
<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment