|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<title>A family of equal-area projections</title> |
|
<script charset="utf-8" src="http://d3js.org/d3.v3.min.js"></script> |
|
<script charset="utf-8" src="http://d3js.org/topojson.v1.min.js"></script> |
|
<script charset="utf-8" src="integrate.js"></script> |
|
<style> |
|
.graticule { fill: none; stroke: #777; stroke-width: .5px; stroke-opacity: .5; } |
|
.outline { fill: none; stroke: #777; stroke-width: 2px; stroke-opacity: 1; } |
|
.land { fill: #222; } |
|
.boundary { fill: none; stroke: #fff; stroke-width: .5px; } |
|
#controls { width: 100%; position: relative; height: 48px; } |
|
#slider { position: absolute; left: 80px; width: 800px; } |
|
</style> |
|
|
|
<div id="map"></div> |
|
<div id="controls"> |
|
<input id="slider" type="range" min="0" max="1" step="0.01" value="0.5"> |
|
</div> |
|
|
|
<script> |
|
var width = 960, |
|
height = 500; |
|
|
|
var t, scale; |
|
|
|
function set_t(new_t) { |
|
t = new_t; |
|
|
|
// Set the scale so the map has 2-to-1 proportions |
|
var max_y = integrate(dy, 0, Math.PI/2, [t]); |
|
scale = Math.sqrt(2*max_y/Math.PI); |
|
} |
|
|
|
function dy(φ, args) { |
|
var t = args[0]; |
|
return Math.pow(Math.cos(φ), 1-t); |
|
} |
|
|
|
set_t(0.5); |
|
var projection = d3.geo.projection(function(λ, φ) { |
|
return [ |
|
λ * Math.pow(Math.cos(φ), t) * scale, |
|
integrate(dy, 0, Math.abs(φ), [t]) * (φ < 0 ? -1 : 1) / scale |
|
]; |
|
}); |
|
|
|
var path = d3.geo.path() |
|
.projection(projection); |
|
|
|
var graticule = d3.geo.graticule(); |
|
|
|
var svg = d3.select("#map").append("svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
svg.append("path") |
|
.datum(graticule) |
|
.attr("class", "graticule") |
|
.attr("d", path); |
|
svg.append("path") |
|
.datum(graticule.outline()) |
|
.attr("class", "outline") |
|
.attr("d", path); |
|
|
|
d3.json("/mbostock/raw/4090846/world-50m.json", function(error, world) { |
|
svg.insert("path", ".graticule") |
|
.datum(topojson.feature(world, world.objects.land)) |
|
.attr("class", "land") |
|
.attr("d", path); |
|
|
|
svg.insert("path", ".graticule") |
|
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; })) |
|
.attr("class", "boundary") |
|
.attr("d", path); |
|
}); |
|
|
|
d3.select(self.frameElement).style("height", (height + 48) + "px"); |
|
d3.select("#slider").on("change", function() { |
|
set_t(parseFloat(this.value)); |
|
svg.selectAll("path").transition().attr("d", path); |
|
}); |
|
|
|
</script> |