Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>My answer is close to Jan van der Laan’s, but you can simplify things slightly because you don’t need to compute the geographic centroid; you only need the bounding box. And, by using an unscaled, untranslated unit projection, you can simplify the math.</p> <p>The important part of the code is this:</p> <pre><code>// Create a unit projection. var projection = d3.geo.albers() .scale(1) .translate([0, 0]); // Create a path generator. var path = d3.geo.path() .projection(projection); // Compute the bounds of a feature of interest, then derive scale &amp; translate. var b = path.bounds(state), s = .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height), t = [(width - s * (b[1][0] + b[0][0])) / 2, (height - s * (b[1][1] + b[0][1])) / 2]; // Update the projection to use computed scale &amp; translate. projection .scale(s) .translate(t); </code></pre> <p>After comping the feature’s <a href="https://github.com/mbostock/d3/wiki/Geo-Paths#wiki-path_bounds" rel="noreferrer">bounding box</a> in the unit projection, you can compute the appropriate <strong>scale</strong> by comparing the aspect ratio of the bounding box (<code>b[1][0] - b[0][0]</code> and <code>b[1][1] - b[0][1]</code>) to the aspect ratio of the canvas (<code>width</code> and <code>height</code>). In this case, I’ve also scaled the bounding box to 95% of the canvas, rather than 100%, so there’s a little extra room on the edges for strokes and surrounding features or padding.</p> <p>Then you can compute the <strong>translate</strong> using the center of the bounding box (<code>(b[1][0] + b[0][0]) / 2</code> and <code>(b[1][1] + b[0][1]) / 2</code>) and the center of the canvas (<code>width / 2</code> and <code>height / 2</code>). Note that since the bounding box is in the unit projection’s coordinates, it must be multiplied by the scale (<code>s</code>).</p> <p>For example, <a href="http://bl.ocks.org/mbostock/4707858" rel="noreferrer">bl.ocks.org/4707858</a>:</p> <p><a href="http://bl.ocks.org/mbostock/4707858" rel="noreferrer"><img src="https://i.stack.imgur.com/AJYDL.png" alt="project to bounding box"></a></p> <p>There’s a related question where which is how to zoom to a specific feature in a collection without adjusting the projection, <em>i.e.</em>, combining the projection with a geometric transform to zoom in and out. That uses the same principles as above, but the math is slightly different because the geometric transform (the SVG "transform" attribute) is combined with the geographic projection.</p> <p>For example, <a href="http://bl.ocks.org/mbostock/4699541" rel="noreferrer">bl.ocks.org/4699541</a>:</p> <p><a href="http://bl.ocks.org/mbostock/4699541" rel="noreferrer"><img src="https://i.stack.imgur.com/kQAYa.png" alt="zoom to bounding box"></a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload