The 12 core projections.
From D3 in Depth book by Peter Cook.
| license: gpl-3.0 | |
| height: 6350 | |
| border: no |
The 12 core projections.
From D3 in Depth book by Peter Cook.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <head> | |
| <title>Geo (projection distortion)</title> | |
| </head> | |
| <style> | |
| body { | |
| font-family: "Helvetica Neue", Helvetica, sans-serif; | |
| font-size: 14px; | |
| color: #333; | |
| } | |
| canvas { | |
| border: 1px solid #eee; | |
| margin: 5px; | |
| } | |
| .description { | |
| margin: 10px 0; | |
| } | |
| </style> | |
| <body> | |
| <h1>D3 core projections</h1> | |
| <div class="description">Here are the 12 <a href="https://github.com/d3/d3-geo/blob/master/README.md#projections" target="_blank">core geographic projections</a> in <a href="https://d3js.org" target="_blank">D3</a> (version 4.2). Equal radius circles are drawn to highlight area distortion (e.g. see Mercator).</div> | |
| <div class="description">From <a href="http://d3indepth.com">D3 in Depth</a>.</div> | |
| <div id="content"></div> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-geo-projection/2.1.2/d3-geo-projection.min.js"></script> | |
| <script> | |
| var geojson = {}; | |
| var projections = [ | |
| {type: 'AzimuthalEqualArea', scale: 100}, | |
| {type: 'AzimuthalEquidistant', scale: 80}, | |
| {type: 'Gnomonic', scale: 100}, | |
| {type: 'Orthographic', scale: 160}, | |
| {type: 'Stereographic', scale: 100}, | |
| {type: 'Albers', scale: 120}, | |
| {type: 'ConicConformal', scale: 100}, | |
| {type: 'ConicEqualArea', scale: 100}, | |
| {type: 'ConicEquidistant', scale: 100}, | |
| {type: 'Equirectangular', scale: 80}, | |
| {type: 'Mercator', scale: 70}, | |
| {type: 'TransverseMercator', scale: 70}, | |
| ]; | |
| var circles = [[0, 0], [-90, 0], [-45, 0], [45, 0], [90, 0], [0, -70], [0, -35], [0, 35], [0, 70]]; | |
| var geoCircle = d3.geoCircle().radius(10).precision(1); | |
| var geoGraticule = d3.geoGraticule(); | |
| var width = 500, height = 500, globalScale = 1.2, yaw = 1; | |
| var yawScale = d3.scaleLinear().domain([0, width]).range([-180, 180]); | |
| function updateCanvas(d) { | |
| var context = this.getContext('2d'); | |
| var projection = d3['geo' + d.type]() | |
| .scale(globalScale * d.scale) | |
| .center([0, 0]) | |
| .translate([0.5 * width, 0.5 * height]) | |
| .rotate([yaw, 0, 0]) | |
| var geoGenerator = d3.geoPath() | |
| .projection(projection) | |
| .context(context); | |
| context.lineWidth = 0.5; | |
| // Graticule | |
| context.strokeStyle = '#ccc'; | |
| context.fillStyle = 'none'; | |
| context.setLineDash([1,1]); | |
| context.beginPath(); | |
| geoGenerator(geoGraticule()); | |
| context.stroke(); | |
| // World | |
| context.fillStyle = '#eee'; | |
| context.setLineDash([]); | |
| context.beginPath(); | |
| geoGenerator({type: 'FeatureCollection', features: geojson.features}) | |
| context.fill(); | |
| context.stroke(); | |
| // Circles | |
| context.strokeStyle = '#888'; | |
| context.fillStyle = 'none'; | |
| circles.forEach(function(center) { | |
| geoCircle.center(center); | |
| context.beginPath(); | |
| geoGenerator(geoCircle()); | |
| context.stroke(); | |
| }); | |
| // Projection label | |
| context.fillStyle = '#333'; | |
| context.fillText(d.type, 10, 20); | |
| } | |
| function update() { | |
| var u = d3.select('#content') | |
| .selectAll('canvas') | |
| .data(projections); | |
| u.enter() | |
| .append('canvas') | |
| .attr('width', width + 'px') | |
| .attr('height', height + 'px') | |
| .merge(u) | |
| .each(updateCanvas); | |
| u.exit().remove(); | |
| } | |
| // REQUEST DATA | |
| d3.json('ne_110m_land.json', function(err, json) { | |
| geojson = json; | |
| update(); | |
| }) | |
| </script> | |
| </body> | |
| </html> |