A mashup of Map Projection Distortions and examples using the d3 projections plugin
A comparison of map projections by four different types of distortion. Lower is better. Data transcribed from the Natural Earth Projection by @mbostock
Read more about map projections on Wikipedia
xxxxxxxxxx
<meta charset="utf-8">
<title>Map Projections</title>
<style>
body {
margin-top:30px;
margin-left: 20px;
}
svg {
font: 10px sans-serif;
}
.background path {
fill: none;
stroke: none;
stroke-width: 24px;
pointer-events: stroke;
}
.foreground path {
fill: none;
stroke: steelblue;
stroke-width: 1px;
}
.axis .title {
font-size: 11px;
font-weight: bold;
text-transform: uppercase;
}
.axis line,
.axis path {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.label {
-webkit-transition: fill 125ms linear;
}
.active .label:not(.inactive) {
font-weight: bold;
}
.label.inactive {
fill: #888;
}
.foreground path.inactive {
stroke: #888;
stroke-opacity: .3;
stroke-width: 1px;
}
path.background {
fill: #A5BFDD;
}
path.foreground {
fill: none;
stroke: #333;
stroke-width: 0.51px;
}
path.graticule {
fill: none;
stroke: #fff;
stroke-width: .5px;
}
.line:nth-child(2n) {
stroke-dasharray: 2,2;
}
.land {
fill: #fff;
stroke: #766951;
}
.boundary {
fill: none;
stroke: #a5967e;
}
#projections { margin: 20px 20px 0;}
a { font-family: Helvetica; display: inline-block; margin: 5px; font-size: 15px; color: #88b;}
</style>
<body>
<script src="d3.v2.min.js"></script>
<script src="jquery.min.js"></script>
<div id="projections"></div>
<script src="projection.js"></script>
<script>
/* Projections */
var projections = {
"Aitoff": d3.geo.aitoff().scale(135),
"Bonne": d3.geo.bonne().scale(135),
"Eckert I": d3.geo.eckert1().scale(140),
"Eckert II": d3.geo.eckert2().scale(140),
"Eckert III": d3.geo.eckert3().scale(144),
"Eckert IV": d3.geo.eckert4().scale(144),
"Eckert V": d3.geo.eckert5().scale(140),
"Eckert VI": d3.geo.eckert6().scale(140),
"Equidistant Cylindrical (Plate Carrée)": d3.geo.equirectangular().scale(660),
"Hammer": d3.geo.hammer().scale(140),
"Kavraisky VII": d3.geo.kavrayskiy7().scale(135),
"Mercator": d3.geo.mercator().scale(380),
"Mollweide": d3.geo.mollweide().scale(100),
"Nell–Hammer": d3.geo.nellHammer().scale(124),
"Robinson": d3.geo.robinson().scale(135),
"Sinusoidal": d3.geo.sinusoidal().scale(130),
"van der Grinten (I)": d3.geo.vanDerGrinten().scale(84),
"Wagner VI": d3.geo.wagner6().scale(135),
"Winkel Tripel": d3.geo.winkel3().scale(135)
};
$.each(projections, function(name) {
var a = $('<a href="#">'+name+'</a>');
a.click(function(e) {
e.preventDefault();
changeproj($(e.target).html());
});
$('#projections').append(a);
})
/* Map */
var map_width = 860,
map_height = 500;
var projection = d3.geo.aitoff()
.translate([map_width / 2 - .5, map_height / 2 - .5]).scale(135);
var path = d3.geo.path()
.projection(projection);
var graticule = d3.geo.graticule();
var map_svg = d3.select("body").append("svg")
.attr("width", map_width)
.attr("height", map_height);
map_svg.append("path")
.datum(graticule.outline)
.attr("class", "background")
.attr("d", path)
map_svg.selectAll(".graticule")
.data(graticule.lines)
.enter().append("path")
.attr("class", "graticule")
.attr("d", path);
map_svg.append("path")
.datum(graticule.outline)
.attr("class", "foreground")
.attr("d", path);
d3.json("readme-boundaries.json", function(collection) {
map_svg.insert("g", ".graticule")
.attr("class", "boundary")
.selectAll("path")
.data(collection.geometries)
.enter().append("path")
.attr("d", path);
});
d3.json("readme-land.json", function(collection) {
map_svg.insert("g", ".graticule,.boundary")
.attr("class", "land")
.selectAll("path")
.data(collection.geometries)
.enter().append("path")
.attr("d", path);
});
/* Parallel Coordinates */
function changeproj(name) {
if (!(name in projections)) return;
// update map
projection = projections[name]
.translate([map_width / 2 - .5, map_height / 2 - .5]);
path = d3.geo.path()
.projection(projection);
map_svg.selectAll("path")
.transition()
.duration(1200)
.attr("d", path);
}
function draw(d) {
return line(dimensions.map(function(dimension) {
return [x(dimension.name), dimension.scale(d[dimension.name])];
}));
}
</script>
</body>
</html>