block by renecnielsen 87e6126d58f86d216a3b

Small Maptiples - d3.carto

Full Screen

hello world

forked from emeeks‘s block: Small Maptiples - d3.carto

index.html

<html xmlns="//www.w3.org/1999/xhtml">
<head>
  <title>d3.carto - Small Multiples with Maps</title>
  <meta charset="utf-8" />
    <link type="text/css" rel="stylesheet" href="d3map.css" />
</head>
<style>
  html,body {
    height: 100%;
    width: 100%;
    margin: 0;
  }

  #map {
    height: 100%;
    width: 100%;
    position: absolute;
  }
  
  .country {
    fill: none;
    stroke: lightgray;
    stroke-width: 1px;
  }
  
  .smallmap {
    width: 33%;
    float: left;
    border: 1px lightgray solid;
  }

</style>
<script>
    function makeSomeMaps() {

    mapImageArray = [];
    map = d3.carto.map();
    d3.select("#map").call(map);

    map.setScale(1)

    countryLayer = d3.carto.layer.topojson();
    
    countryLayer.path("world.topojson")
    .label("Countries")
    .renderMode("canvas")
    .cssClass("country");

    csvLayer = d3.carto.layer.csv();
    csvLayer
    .path("all_sites.csv")
    .label("CSV Points")
    .cssClass("point")
    .renderMode("canvas")
    .markerSize(1)
    .x("xcoord")
    .y("ycoord")
    .on("load", smallMaptiples)

    map.addCartoLayer(countryLayer).addCartoLayer(csvLayer);
    
    function smallMaptiples() {
    var cityAtts = ["aq", "ar", "arid", "capacity", "de", "delivery", "pop", "qu","region"];
    var cityData = csvLayer.features()

    for (var att in cityAtts) {
      
    var attExtent = d3.extent(cityData, function(d) {return parseFloat(d[cityAtts[att]])});
    var colorScale = d3.scale.linear().domain([attExtent[0],(attExtent[0] + attExtent[1])/2,attExtent[1]]).range(["green","yellow","red"])

    csvLayer
    .markerColor(function(d) {return colorScale(d[cityAtts[att]])})
    .strokeColor(function(d) {return colorScale(d[cityAtts[att]])})

    map.refresh();
    mapImageArray.push(d3.select("canvas").node().toDataURL());

    }
    
    window.onresize(null);
    d3.select("#map").remove();
    d3.select("body").append("div").selectAll("img").data(mapImageArray).enter().append("img").attr("class", "smallmap").attr("src", function(d) {return d})
    }
  }
</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="https://rawgit.com/emeeks/d3-carto-map/master/d3.carto.map.js" type="text/javascript">
</script>
<script src="//d3js.org/topojson.v1.min.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;
}

readme.md

Using **[d3.carto.map](https://github.com/emeeks/d3-carto-map)**'s built-in canvas rendering and HTML5 canvas's built-in toDataUrl() function to create small multiples of the same map.

This example cycles through the various numeric attributes of the point dataset and restyles the map by changing layer.markerColor and layer.strokeColor. You have to call map.refresh() to update the display and then select the canvas element associated with the map to get access to the image data as a data URL, which you can pass to img elements.

This method of accessing toDataUrl only works with layers drawn using canvas.