The basic idea is to get the bounding box of the country that has been selected
and set the parameters of the projection (zoom level and center) accordingly.
HTH,
Lars
The relevant lines are below, in the function updateMap(). The argument to that
function is a geojson fragment that can be either the entire map (which it is in
the beginning) or the fragment for a specific country (this way the
centering/zooming works).
proj.scale(Math.min(wscale*5, pscale));
tproj.scale(Math.min(wscale*5, pscale));
var off = tproj([-bounds0[0][0], -bounds0[1][1]]),
other = tproj([-bounds0[1][0], -bounds0[0][1]]),
len = [off[0] - other[0], off[1] - other[1]],
dx = off[0] + (width - clistw - 2*margin)/2 - len[0]/2,
dy = off[1] + (height - 7.5*margin)/2 - len[1]/2;
proj.translate([dx, dy]);
map.selectAll("path")
.transition().duration(1000)
.attr("d", path);
Figuring out the offsets between different projections is a bit hairy, but
relatively straightforward. You might want to check out this pull request
(https://github.com/mbostock/d3/pull/330) that adds a geotranslate method to the
projections that allows you to input user coordinates instead of projected
coordinates.
You might be able to get away with simply copying the updateMap() function and
adjusting/removing some of the variables in there (width, margin etc). You might
be able to use it directly from the code that generates your list of countries
if you're using .data() and the argument you're giving it is the actual json,
e.g.
.on("click", function(d) { updateMap(d); });
Lars
menu.selectAll("option")
.data(collection.features)
.enter().append("option")
.text(function(d) { return d.name; })
.on("click", function(d) { updateMap(d); });
Lars