A fork of Mike Bostock's Geographic Projection Example. Uses the path.area method of d3.geo.path() to compute the projected area (in pixels) of each country.
These projections are available in the geo.projection plugin.
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
background: #fcfcfa;
height: 500px;
position: relative;
width: 960px;
}
#projection-menu {
position: absolute;
right: 10px;
top: 10px;
}
.stroke {
fill: none;
stroke: #000;
stroke-width: 3px;
}
.fill {
fill: #fff;
}
.graticule {
fill: none;
stroke: #777;
stroke-width: .5px;
stroke-opacity: .5;
}
.land {
fill: #222;
}
.boundary {
fill: none;
stroke: #fff;
stroke-width: .5px;
}
.details {
text-align: center;
max-height: 250px;
overflow: auto;
}
.details span {
display: inline-block;
margin: 0px 5px;
text-align: right;
}
.details .rank {
width: 40px;
}
.details .country {
text-align: left;
width: 300px;
}
.details .size {
width: 60px;
}
.details .pct {
width: 80px;
}
</style>
<select id="projection-menu"></select>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/queue.v1.min.js"></script>
<script src="https://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 500;
var options = [
{name: "Aitoff", projection: d3.geo.aitoff()},
{name: "Albers", projection: d3.geo.albers().scale(145).parallels([20, 50])},
{name: "August", projection: d3.geo.august().scale(60)},
{name: "Baker", projection: d3.geo.baker().scale(100)},
{name: "Boggs", projection: d3.geo.boggs()},
{name: "Bonne", projection: d3.geo.bonne().scale(120)},
{name: "Bromley", projection: d3.geo.bromley()},
{name: "Collignon", projection: d3.geo.collignon().scale(93)},
{name: "Craster Parabolic", projection: d3.geo.craster()},
{name: "Eckert I", projection: d3.geo.eckert1().scale(165)},
{name: "Eckert II", projection: d3.geo.eckert2().scale(165)},
{name: "Eckert III", projection: d3.geo.eckert3().scale(180)},
{name: "Eckert IV", projection: d3.geo.eckert4().scale(180)},
{name: "Eckert V", projection: d3.geo.eckert5().scale(170)},
{name: "Eckert VI", projection: d3.geo.eckert6().scale(170)},
{name: "Eisenlohr", projection: d3.geo.eisenlohr().scale(60)},
{name: "Equirectangular (Plate Carrée)", projection: d3.geo.equirectangular()},
{name: "Hammer", projection: d3.geo.hammer().scale(165)},
{name: "Hill", projection: d3.geo.hill()},
{name: "Goode Homolosine", projection: d3.geo.homolosine()},
{name: "Kavrayskiy VII", projection: d3.geo.kavrayskiy7()},
{name: "Lambert cylindrical equal-area", projection: d3.geo.cylindricalEqualArea()},
{name: "Lagrange", projection: d3.geo.lagrange().scale(120)},
{name: "Larrivée", projection: d3.geo.larrivee().scale(95)},
{name: "Laskowski", projection: d3.geo.laskowski().scale(120)},
{name: "Loximuthal", projection: d3.geo.loximuthal()},
{name: "Mercator", projection: d3.geo.mercator().scale(490 / 2 / Math.PI)},
{name: "Miller", projection: d3.geo.miller().scale(100)},
{name: "McBryde–Thomas Flat-Polar Parabolic", projection: d3.geo.mtFlatPolarParabolic()},
{name: "McBryde–Thomas Flat-Polar Quartic", projection: d3.geo.mtFlatPolarQuartic()},
{name: "McBryde–Thomas Flat-Polar Sinusoidal", projection: d3.geo.mtFlatPolarSinusoidal()},
{name: "Mollweide", projection: d3.geo.mollweide().scale(165)},
{name: "Natural Earth", projection: d3.geo.naturalEarth()},
{name: "Nell–Hammer", projection: d3.geo.nellHammer()},
{name: "Polyconic", projection: d3.geo.polyconic().scale(100)},
{name: "Robinson", projection: d3.geo.robinson()},
{name: "Sinusoidal", projection: d3.geo.sinusoidal()},
{name: "Sinu-Mollweide", projection: d3.geo.sinuMollweide()},
{name: "van der Grinten", projection: d3.geo.vanDerGrinten().scale(75)},
{name: "van der Grinten IV", projection: d3.geo.vanDerGrinten4().scale(120)},
{name: "Wagner IV", projection: d3.geo.wagner4()},
{name: "Wagner VI", projection: d3.geo.wagner6()},
{name: "Wagner VII", projection: d3.geo.wagner7()},
{name: "Winkel Tripel", projection: d3.geo.winkel3()}
];
options.forEach(function(o) {
if (o.name !== 'Mercator') {
o.projection.rotate([0, 0]).center([0, 0]);
}
});
var interval = setInterval(loop, 2000),
i = 0,
n = options.length - 1;
var projection = options[i].projection;
var path = d3.geo.path()
.projection(projection);
var graticule = d3.geo.graticule();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("defs").append("path")
.datum({type: "Sphere"})
.attr("id", "sphere")
.attr("d", path);
svg.append("use")
.attr("class", "stroke")
.attr("xlink:href", "#sphere");
svg.append("use")
.attr("class", "fill")
.attr("xlink:href", "#sphere");
svg.append("path")
.datum(graticule)
.attr("class", "graticule")
.attr("d", path);
var details = d3.select("body").append("div")
.attr("class", "details");
var header = details.append('div').attr('class', 'header');
header.append('span')
.attr('class', 'rank')
.text('');
header.append('span')
.attr('class', 'country')
.text('country');
header.append('span')
.attr('class', 'size')
.text('pixels');
header.append('span')
.attr('class', 'pct')
.text('percent');
queue()
.defer(d3.json, "/d/4090846/world-110m.json")
.defer(d3.tsv, "/d/4090846/world-country-names.tsv")
.await(ready);
function ready (error, world, names) {
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);
names.forEach(function(n) {
n.geom = world.objects.countries.geometries.filter(function(g) {
return +g.id == +n.id;
})[0];
n.area = 0;
});
names = names.filter(function(n) {
return n.geom;
});
var areas = details.selectAll('div.area')
.data(names);
var new_areas = areas.enter()
.append('div')
.attr('class', 'area');
new_areas.append('span')
.attr('class', 'rank')
.text(function(d, i) {return i+1;});
new_areas.append('span')
.attr('class', 'country')
.text(function(d) {return d.name;});
new_areas.append('span')
.attr('class', 'size')
.text("0");
new_areas.append('span')
.attr('class', 'pct')
.text("0.0");
window.world = world;
window.names = names;
update(options[i]);
}
var menu = d3.select("#projection-menu")
.on("change", change);
menu.selectAll("option")
.data(options)
.enter().append("option")
.text(function(d) { return d.name; });
function loop() {
var j = Math.floor(Math.random() * n);
menu.property("selectedIndex", i = j + (j >= i));
update(options[i]);
}
function change() {
clearInterval(interval);
update(options[this.selectedIndex]);
}
function update(option) {
svg.selectAll("path").transition()
.duration(750)
.attrTween("d", projectionTween(projection, projection = option.projection));
var total_area = 0;
names.forEach(function(n) {
total_area += (n.area = computeArea(n.geom, projection));
});
details.selectAll('.area .size')
.transition()
.tween('text', function(d) {
var i = d3.interpolate(this.textContent, d.area);
return function(t) {this.textContent = i(t).toFixed(0);}
});
details.selectAll('.area .pct')
.transition()
.tween('text', function(d) {
var i = d3.interpolate(this.textContent, 100*d.area/total_area);
return function(t) {this.textContent = i(t).toFixed(3);}
});
}
function projectionTween(projection0, projection1) {
return function(d) {
var t = 0;
var projection = d3.geo.projection(project)
.scale(1)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
function project(λ, φ) {
λ *= 180 / Math.PI, φ *= 180 / Math.PI;
var p0 = projection0([λ, φ]), p1 = projection1([λ, φ]);
if (t == 0) {return [p0[0], -p0[1]];}
if (t == 1) {return [p1[0], -p1[1]];}
return [(1 - t) * p0[0] + t * p1[0], (1 - t) * -p0[1] + t * -p1[1]];
}
return function(_) {
t = _;
return path(d);
};
};
}
function computeArea(geometry, projection) {
if (!geometry) {return 0;}
var path = d3.geo.path()
.projection(projection);
return path.area(topojson.feature(world, geometry));
}
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/queue.v1.min.js to a secure url
Modified http://d3js.org/d3.geo.projection.v0.min.js to a secure url
Modified http://d3js.org/topojson.v1.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/queue.v1.min.js
https://d3js.org/d3.geo.projection.v0.min.js
https://d3js.org/topojson.v1.min.js