Skip to content

Instantly share code, notes, and snippets.

@emeeks
Last active August 29, 2015 14:03
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 emeeks/fe52c25d4bb0b5ac4baa to your computer and use it in GitHub Desktop.
Save emeeks/fe52c25d4bb0b5ac4baa to your computer and use it in GitHub Desktop.
Zoom to Bounding Box - d3.carto.map

Zoom to bounding box example for d3.carto.map.

Click on any country and the map will automatically zoom to the bounding box of that country. This is done by creating an invisible vector layer that's overlaid on the tile layer, with zoomTo being called on click of any of the invisible paths.

path,circle,rect,polygon,ellipse,line {
vector-effect: non-scaling-stroke;
}
svg, canvas {
top: 0;
}
#d3MapZoomBox {
position: absolute;
z-index: 10;
height: 100px;
width: 25px;
top: 10px;
right: 50px;
}
#d3MapZoomBox > button {
height:25px;
width: 25px;
line-height: 25px;
}
.d3MapControlsBox > button {
font-size:22px;
font-weight:900;
border: none;
height:25px;
width:25px;
background: rgba(35,31,32,.85);
color: white;
padding: 0;
cursor: pointer;
}
.d3MapControlsBox > button:hover {
background: black;
}
#d3MapPanBox {
position: absolute;
z-index: 10;
height: 100px;
width: 25px;
top: 60px;
right: 50px;
}
#d3MapPanBox > button {
height:25px;
width: 25px;
line-height: 25px;
}
#d3MapPanBox > button#left {
position: absolute;
left: -25px;
top: 10px;
}
#d3MapPanBox > button#right {
position: absolute;
right: -25px;
top: 10px;
}
#d3MapLayerBox {
position: relative;
z-index: 10;
height: 100px;
width: 120px;
top: 10px;
left: 10px;
overflow: auto;
color: white;
background: rgba(35,31,32,.85);
}
#d3MapLayerBox > div {
margin: 5px;
border: none;
}
#d3MapLayerBox ul {
list-style: none;
padding: 0;
margin: 0;
cursor: pointer;
}
#d3MapLayerBox li {
list-style: none;
padding: 0;
}
#d3MapLayerBox li:hover {
font-weight:700;
}
#d3MapLayerBox li input {
cursor: pointer;
}
div.d3MapModal {
position: absolute;
z-index: 11;
background: rgba(35,31,32,.90);
top: 50px;
left: 50px;
color: white;
max-width: 400px;
}
div.d3MapModalContent {
width:100%;
height: 100%;
overflow: auto;
}
div.d3MapModalContent > p {
padding: 0px 20px;
margin: 5px 0;
}
div.d3MapModalContent > h1 {
padding: 0px 20px;
font-size: 20px;
}
div.d3MapModalArrow {
content: "";
width: 0;
height: 0;
border-left: 20px solid transparent;
border-right: 20px solid transparent;
border-top: 20px solid rgba(35,31,32,.90);
position: absolute;
bottom: -20px;
left: 33px;
}
#d3MapSVG {
}
rect.minimap-extent {
fill: rgba(200,255,255,0.35);
stroke: black;
stroke-width: 2px;
stroke-dasharray: 5 5;
}
circle.newpoints {
fill: black;
stroke: red;
stroke-width: 2px;
}
path.newfeatures {
fill: steelblue;
fill-opacity: .5;
stroke: pink;
stroke-width: 2px;
}
.countrylabel {
font-size: 12px;
color: red;
text-anchor: middle;
pointer-events: none;
font-weight: 900;
}
.wards {
fill: gray;
stroke: gray;
stroke-width: 1px;
}
.countryborders {
fill: rgba(0,0,0,0);
stroke-width: 1px;
stroke: gray;
cursor: pointer;
}
.invisible {
fill: rgba(0,0,0,0);
stroke-width: 0;
stroke: black;
cursor: pointer;
}
.countries {
fill: none;
stroke-width: 1px;
stroke: black;
opacity: 1;
}
.halffilledcountries {
fill: rgba(224,224,209,0.5);
stroke-width: 1px;
stroke: black;
opacity: 1;
}
.filledcountries {
fill: #E0E0D1;
stroke-width: 1px;
stroke: black;
opacity: 1;
}
.francelike {
fill: steelblue;
stroke-width: 2px;
stroke: lightgray;
}
.roads {
stroke: brown;
stroke-width: 1px;
fill: none;
}
.rivers {
stroke: blue;
stroke-width: 2px;
fill: none;
opacity: 1;
}
.thickborders {
stroke: brown;
stroke-width: 2px;
fill: none;
}
circle {
fill: black;
stroke: red;
}
circle.pinkcircle {
fill: pink;
stroke: black;
stroke-width: 1;
opacity: 1
}
circle.greencircle {
fill: green;
stroke: red;
opacity: 1;
stroke-width: 3;
}
#infoBox {
position: fixed;
z-index: 1;
bottom: 150px;
right: 150px;
background: white;
border: 1px gray dashed;
padding:20px;
width: 200px;
}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>d3.carto.map - Zoom to Bounding Box</title>
<meta charset="utf-8" />
<link type="text/css" rel="stylesheet" href="d3map.css" />
<link type="text/css" rel="stylesheet" href="example.css" />
</head>
<style>
html,body {
height: 100%;
width: 100%;
margin: 0;
}
#map {
height: 100%;
width: 100%;
position: absolute;
}
</style>
<script>
function makeSomeMaps() {
zoomMap = d3.carto.map();
d3.select("#map").call(zoomMap);
zoomMap.setScale(2)
tileLayer = d3.carto.layer.tile();
tileLayer
.path("examples.map-zgrqqx0w")
.label("Terrain");
zoomMap.addCartoLayer(tileLayer);
d3.json("http://bl.ocks.org/emeeks/raw/c970c9ee3e242e90004b/world.geojson", function(error,data) {
featureLayer = d3.carto.layer.featureArray();
featureLayer
.features(data.features)
.label("Countries")
.cssClass("invisible")
.renderMode("svg")
.clickableFeatures(true)
.on("load", clickToZoom);
zoomMap.addCartoLayer(featureLayer);
function clickToZoom() {
d3.select("#map").selectAll("path.invisible").on("click", function (d) {
var path = d3.geo.path().projection(zoomMap.projection());
zoomMap.zoomTo(path.bounds(d),"scaled",.95,2000);
})
}
})
}
</script>
<body onload="makeSomeMaps()">
<div id="map"></div>
<footer>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8" type="text/javascript"></script>
<script src="http://d3js.org/topojson.v1.min.js" type="text/javascript">
</script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js" type="text/javascript">
</script>
<script src="http://d3js.org/colorbrewer.v1.min.js"></script>
<script src="http://bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/tile.js" type="text/javascript">
</script>
<script src="http://bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/d3.quadtiles.js" type="text/javascript">
</script>
<script src="http://bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/d3.geo.raster.js" type="text/javascript">
</script>
<script src="https://rawgit.com/emeeks/d3-carto-map/master/d3.carto.map.js" type="text/javascript">
</script>
</footer>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment