block by emeeks 757e699fed2658bcb42b

City Nature Neighborhoods

Full Screen

Loading and styling data from the Stanford Digital Repository in d3.carto.map.

This example uses neighborhood data from the City Nature Project.

You can see the data here.

index.html

<html xmlns="//www.w3.org/1999/xhtml">
<head>
  <title>d3.carto - City Nature SDR Data</title>
  <meta charset="utf-8" />
    <link type="text/css" rel="stylesheet" href="d3map.css" />
</head>
<style>
  #d3MapLayerBox {
    display: none;
  }
  #legend {
    position: absolute;
    bottom: 20px;
    left: 20px;
    background: rgba(35,31,32,.85);
    width: 330px;
    height: 100px;
  }
  #map {
    width: 100%;
    height: 100%;
  }
  
  text {
    fill: white;
  }
  
  line {
    stroke: white;
  }
</style>
<script>
      function makeSomeMaps() {
        
    var colorScale = d3.scale.quantize().domain([0,.5]).range(colorbrewer.Greens[5])
    
    legend = d3.svg.legend().unitLabel("")
    .formatter(d3.format("%"))
    .title("Percent park")
    .scale(colorScale)

  d3.select("#legend").append("svg").style("width", "100%").style("height", "100%").append("g").attr("transform", "translate(20,35)").attr("class", "legend").call(legend);

    map = d3.carto.map();

    d3.select("#map").call(map);
    
    map.zoom().scale(119404).translate([39679, 12151])

    tileLayer = d3.carto.layer();
    tileLayer
    .type("tile")
    .path("elijahmeeks.map-azn21pbi")
    .label("Terrain")

    csvLayer = d3.carto.layer.csv();
    csvLayer
    .path("https://sul-stacks.stanford.edu/file/druid:qq826dq9111/neighborhood-stats_2661_20130512.csv")
    .label("Neighborhoods")
    .cssClass("point")
    .renderMode("canvas")
    .markerColor(function(d){return colorScale(d.pct_park)})
    .markerSize(3)
    .strokeColor("black")
    .x("lng")
    .y("lat");

    map.addCartoLayer(tileLayer).addCartoLayer(csvLayer);

    
  }
  
</script>
<body onload="makeSomeMaps()">
<div id="buttons"></div>
<div id="map"></div>
<div id="legend"></div>
<footer>
<script src="//d3js.org/colorbrewer.v1.min.js" charset="utf-8" type="text/javascript"></script>
<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="legend.js" type="text/javascript">
</script>
<script src="//bl.ocks.org/emeeks/raw/f3105fda25ff785dc5ed/tile.js" type="text/javascript">
</script>
<script src="https://rawgit.com/emeeks/d3-carto-map/master/d3.carto.map.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>
</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;
}

legend.js

d3.svg.legend = function() {
      var data = [];
      var size = [300,20];
      var xScale = d3.scale.linear();
      var scale;
      var title = "Legend";
      var numberFormat = d3.format(".4n");
      var units = "Units";

    function legend(gSelection) {
      
      createLegendData(scale);
      
      var xMin = d3.min(data, function(d) {return d.domain[0]});
      var xMax = d3.max(data, function(d) {return d.domain[1]});
      xScale.domain([xMin,xMax]).range([0,size[0]])

      gSelection.selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      .attr("height", size[1])
      .attr("width", function (d) {return xScale(d.domain[1]) -  xScale(d.domain[0])})
      .attr("x", function (d) {return xScale(d.domain[0])})
      .style("fill", function(d) {return d.color})

      gSelection.selectAll("line")
      .data(data)
      .enter()
      .append("line")
      .attr("x1", function (d) {return xScale(d.domain[0])})
      .attr("x2", function (d) {return xScale(d.domain[0])})
      .attr("y1", 0)
      .attr("y2", size[1] + 5)
      .style("stroke", "black")
      .style("stroke-width", "2px")

      gSelection.selectAll("text")
      .data(data)
      .enter()
      .append("g")
      .attr("transform", function (d) {return "translate(" + (xScale(d.domain[0])) +"," + (size[1] + 20) + ")"})
      .style("text-anchor", "middle")
      .append("text")
      .text(function(d) {return numberFormat(d.domain[0])})

      gSelection.append("text")
      .attr("transform", function (d) {return "translate(" + (xScale(xMin)) +"," + (size[1] - 30) + ")"})
      .text(title)

      gSelection.append("text")
      .attr("transform", function (d) {return "translate(" + (xScale(xMax)) +"," + (size[1] + 20) + ")"})
      .text(units)

      return legend;
    }
    
    function createLegendData(incScale) {
      var rangeArray = incScale.range();
      data = [];
      
      for (x in rangeArray) {
        var colorValue = rangeArray[x];
        var domainValues = incScale.invertExtent(colorValue);
        data.push({color: colorValue, domain: domainValues})
      }
    }

    
    legend.scale = function(newScale) {
      if (!arguments.length) return scale;
      scale = newScale;
      return this;
    }

    legend.title = function(newTitle) {
      if (!arguments.length) return title;
      title = newTitle;
      return this;
    }

    legend.unitLabel = function(newUnits) {
      if (!arguments.length) return units;
      units = newUnits;
      return this;
    }

    legend.formatter = function(newFormatter) {
      if (!arguments.length) return numberFormat;
      numberFormat = newFormatter;
      return this;
    }

    return legend;
  }