block by emeeks fe52c25d4bb0b5ac4baa

Zoom to Bounding Box - d3.carto.map

Full Screen

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.

index.html

<html xmlns="//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("//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="//d3js.org/d3.v3.min.js" charset="utf-8" type="text/javascript"></script>
<script src="//d3js.org/topojson.v1.min.js" type="text/javascript">
</script>
<script src="//d3js.org/d3.geo.projection.v0.min.js" type="text/javascript">
</script>
<script src="//d3js.org/colorbrewer.v1.min.js"></script>
<script src="//bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/tile.js" type="text/javascript">
</script>
<script src="//bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/d3.quadtiles.js" type="text/javascript">
</script>
<script src="//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>

d3map.css

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;
}

example.css

.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;
  }