block by HarryStevens e605a99d49878fac2e2117256608a3a4

Swiftmap Bubbles, Layers & Tiles

Full Screen

Swiftmap makes it easy to add raster tiles to the background of a map.

This demo is based on the map in “On Delhi’s outskirts, schools urgently need teachers”, published on 7 August, 2017 in the Hindustan Times. Map tiles by Carto.

See also:

index.html

<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        margin: 0;
        font-family: "Helvetica Neue", sans-serif;
      }
      #legend {
        position: absolute;
        background: rgba(255, 255, 255, .8);
        padding: 10px;
      }
      #map {
        width: 100%;
        height: 100vh;
      }
    </style>
  </head>
  <body>
    <div id="legend">
      <b>Select</b><br />
      <input type="radio" name="property" value="students" checked /> Total students<br />
      <input type="radio" name="property" value="student_teacher_ratio" /> Students per teacher
    </div>
    <div id="map"></div>
    
    <!-- To load data, we use modules for d3-request & d3-queue -->
    <script src="https://d3js.org/d3-collection.v1.min.js"></script>
    <script src="https://d3js.org/d3-dispatch.v1.min.js"></script>
    <script src="https://d3js.org/d3-dsv.v1.min.js"></script>
    <script src="https://d3js.org/d3-request.v1.min.js"></script>
    <script src="https://d3js.org/d3-queue.v3.min.js"></script>

    <script src="https://unpkg.com/swiftmap@0.2.4/dist/swiftmap.min.js"></script>

    <script>
      // Create the map.
      var map = swiftmap.map("#map");

      // Set up a scheme for each visual property.
      var schemeRadius = swiftmap.schemeContinuous()
        .from(d => +d.students)
        .to([1, 20]);

      var schemeFill = swiftmap.schemeCategorical()
        .from(d => d.most_urgent)
        .to({
          "TRUE": "#e74c3c",
          "FALSE": "rgb(119, 119, 119)"          
        });

      var schemeStroke = swiftmap.schemeCategorical()
        .from(d => d.most_urgent)
        .to({
          "TRUE": "rgb(191, 39, 24)",
          "FALSE": "rgb(51, 51, 51)"        
        });

      var schemeOpacity = swiftmap.schemeCategorical()
        .from(d => d.most_urgent)
        .to({
          "TRUE": .9,
          "FALSE": .4
        });

      d3.queue()
        .defer(d3.json, "delhi_1997-2012_district.json") // polygons data
        .defer(d3.json, "new_schools.json") // points data
        .defer(d3.csv, "schools.csv") // tabular data
        .await(ready);

      function ready(error, districts, schools, data){
        // Add data to each scheme.
        schemeRadius.data(data, d => +d.edudel_code);
        schemeFill.data(data, d => +d.edudel_code);
        schemeStroke.data(data, d => +d.edudel_code);
        schemeOpacity.data(data, d => +d.edudel_code);

        // Add tiles and geospatial data to your map.
        // Then draw the polygons and bubbles.
        map
          .tiles("cartoLight")
          .layerPolygons(districts)
            .fit()
            .drawBoundary()
          .layerPoints(schools, d => +d.properties.edudel_code)
            .drawPoints();

        // Add the schemes to the bubbles for styling.
        map.layers[1].points
            .attr("r", schemeRadius)
            .style("fill", schemeFill)
            .style("stroke", schemeStroke)
            .style("opacity", schemeOpacity);

        // Update the points' radii when the radio input changes.
        var inputs = document.getElementsByName("property");
        for (var i = 0, l = inputs.length; i < l; i++) {
          inputs[i].onchange = function() {
            schemeRadius.from(d => +d[this.value]);
            map.layers[1].points.transition().duration(1500).attr("r", schemeRadius);
          }
        }

        // It's easy to resize a Swiftmap.
        window.onresize = () => map.resize();
      }
    </script>
  </body>
</html>

delhi_1997-2012_district.json