Skip to content

Instantly share code, notes, and snippets.

@kedarvaidya
Created December 31, 2013 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kedarvaidya/8195618 to your computer and use it in GitHub Desktop.
Save kedarvaidya/8195618 to your computer and use it in GitHub Desktop.
D3 geo zoom to specific countries.
html, body, table, svg {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
path.country {
fill: none;
stroke: #333;
stroke-width: 1px;
}
path.country.highlight {
fill: red;
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="D3 geo zoom to specific countries" />
<meta charset=utf-8 />
<title>D3 geo zoom to specific countries</title>
</head>
<body>
<table>
<tr height="22px">
<td width="100%">
<input id="selectedCountryNames" type="search" placeholder="Comma seperated list of countries" style="width: 100%"/>
</td>
<td width="57px">
<button id="search">Search</button>
</td>
</tr>
<tr>
<td colspan="2">
<svg id="svg">
</svg>
</td>
</tr>
</table>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.3.11/d3.min.js"></script>
</body>
</html>
$.ajax({
url: "https://api.github.com/repos/johan/world.geo.json/contents/countries.geo.json",
dataType: "json",
accepts: {
json: "application/vnd.github.v3.raw+json"
},
success: function( response ) {
draw(response);
}
});
function boundsToPos(bounds) {
return { left: bounds[0][0], right: bounds[1][0], bottom: bounds[0][1], top: bounds[1][1] };
}
function draw(world) {
var countries = world.features;
console.log('No of countries:', countries.length);
var countriesByName = {};
$.each(countries, function(i, d) {
countriesByName[d.properties.name.toLowerCase()] = d;
});
var svg = d3.select('#svg');
var margin = { top: 20, right: 0, bottom: 20, left: 0 };
var width = parseInt(svg.style('width'), 10) - margin.left - margin.right;
var height = parseInt(svg.style('height'), 10) - margin.top - margin.bottom;
var map = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var projection = d3.geo.equirectangular();
var path = d3.geo.path()
.projection(projection);
projection
.scale(1)
.translate([0, 0]);
$.each(countries, function(i, d) {
d.properties.pos = boundsToPos(path.bounds(d));
});
var p = boundsToPos(path.bounds(world)),
s = 0.95 / Math.max((p.right - p.left) / width, (p.top - p.bottom) / height),
t = [(width - s * (p.right + p.left)) / 2, (height - s * (p.top + p.bottom)) / 2];
projection
.scale(s)
.translate(t);
var countryPaths = map.selectAll('path.country')
.data(countries);
countryPaths.enter()
.append('path')
.classed('country', true)
.attr('data-name', function(d) { return d.properties.name; })
.attr('d', path)
.attr('title', function(d) { return d.properties.name; });
$('#search').click(function() {
var selectedCountryNames = $('#selectedCountryNames').val().toLowerCase().split(/\s*[,]+\s*/);
countryPaths.classed('highlight', function(d) {
return $.inArray(d.properties.name.toLowerCase(), selectedCountryNames) >= 0;
});
var selectedCountries = $.grep(countries, function(d,i) {
return $.inArray(d.properties.name.toLowerCase(), selectedCountryNames) >= 0;
});
if(selectedCountries.length) {
var selectedCountriesColl = { type: "FeatureCollection", features: selectedCountries };
var pos = { left: Infinity, right: -Infinity, top: -Infinity, bottom: Infinity };
$.each(selectedCountries, function(i,d) {
var dp = d.properties.pos;
pos.left = Math.min(pos.left, dp.left);
pos.right = Math.max(pos.right, dp.right);
pos.top = Math.max(pos.top, dp.top);
pos.bottom = Math.min(pos.bottom, dp.bottom);
});
s = 0.95 / Math.max((pos.right - pos.left) / width, (pos.top - pos.bottom) / height);
t = [(width - s * (pos.right + pos.left)) / 2, (height - s * (pos.top + pos.bottom)) / 2];
projection = projection
.scale(s)
.translate(t);
path = path.projection(projection);
countryPaths.
transition()
.duration(1000)
.attr('d', path);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment