Hide Table of Contents
View Explore Heat Maps sample in sandbox
Explore Heat Maps

Description

The HeatmapRenderer creates a surface using a standard Gaussian blur algorithm used in data visualization for illustrating areas of concentration within datasets. (Added at version 3.11 of the JS API)

Code

<!DOCTYPE html>
<html>
  <head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
  <title>FeatureLayer using Weighted HeatmapRenderer</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.22/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.22/esri/css/esri.css">
  <style>
    html, body, #map {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
    }

    .blurInfo {
      position: absolute;
      top: 10px;
      right: 5px;
      font-size: 1.25em;
      font-family: monospace;
      color: #4C4C4C;
      width: 240px;
      background-color: #FFFFFF;
      padding: 10px;
      border: 2px solid #57585A;
      border-radius: 20px;
    }

    .blurInfo p span {
      background-color: #FFFFFF;
      padding: 0 5px;
      border-radius: 5px;
    }

    .blurInfo input[type=range] {
      width: 100%;
      display: block;
    }
    </style>
    <script src="https://js.arcgis.com/3.22/"></script>

    <script>
      var map;
      require([
        "dojo/number",
        "esri/InfoTemplate",
        "esri/layers/FeatureLayer",
        "esri/map",
        "esri/renderers/HeatmapRenderer",
        "dojo/domReady!"
      ], function (number, InfoTemplate, FeatureLayer, Map, HeatmapRenderer){

        map = new Map("map", {
          basemap: "gray",
          zoom: 3,
          center: [-103, 18],
          minZoom: 3,
          maxZoom: 5
        });
        // --------------------------------------------------------------------
        // Format the magnitude value in the pop up to show one decimal place.
        // Uses the dojo/number module to perform formatting.
        // --------------------------------------------------------------------
        formatMagnitude = function (value, key, data){
          return number.format(value, {places: 1, locale: "en-us"});
        };

        var infoTemplate = new InfoTemplate("Attributes",
          "Name: ${Name}<br>Magnitude: ${Magnitude:formatMagnitude}");

        var serviceURL = "//services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Earthquakes_Since_1970/FeatureServer/0";
        var heatmapFeatureLayerOptions = {
          mode: FeatureLayer.MODE_SNAPSHOT,
          outFields: ["Name", "Magnitude"],
          infoTemplate: infoTemplate
        };
        var heatmapFeatureLayer = new FeatureLayer(serviceURL, heatmapFeatureLayerOptions);

        var blurCtrl = document.getElementById("blurControl");
        var maxCtrl = document.getElementById("maxControl");
        var minCtrl = document.getElementById("minControl");
        var valCtrl = document.getElementById("valueControl");

        var heatmapRenderer = new HeatmapRenderer({
          field: "Magnitude",
          blurRadius: blurCtrl.value,
          maxPixelIntensity: maxCtrl.value,
          minPixelIntensity: minCtrl.value
        });

        heatmapFeatureLayer.setRenderer(heatmapRenderer);
        map.addLayer(heatmapFeatureLayer);

        /** Add event handlers for interactivity **/

        var sliders = document.querySelectorAll(".blurInfo p~input[type=range]");
        var addLiveValue = function (ctrl){
          var val = ctrl.previousElementSibling.querySelector("span");
          ctrl.addEventListener("input", function (evt){
            val.innerHTML = evt.target.value;
          });
        };
        for (var i = 0; i < sliders.length; i++) {
          addLiveValue(sliders.item(i));
        }

        blurCtrl.addEventListener("change", function (evt){
          var r = +evt.target.value;
          if (r !== heatmapRenderer.blurRadius) {
            heatmapRenderer.blurRadius = r;
            heatmapFeatureLayer.redraw();
          }
        });
        maxCtrl.addEventListener("change", function (evt){
          var r = +evt.target.value;
          if (r !== heatmapRenderer.maxPixelIntensity) {
            heatmapRenderer.maxPixelIntensity = r;
            heatmapFeatureLayer.redraw();
          }
        });
        minCtrl.addEventListener("change", function (evt){
          var r = +evt.target.value;
          if (r !== heatmapRenderer.minPixelIntensity) {
            heatmapRenderer.minPixelIntensity = r;
            heatmapFeatureLayer.redraw();
          }
        });
        // --------------------------------------------------------------------
        // When check / uncheck the control for the HeatmapRenderer field,
        // we will leave the blurRadius and the minPixelIntensity values the
        // same. However we will adjust the maxPixelIntensity value so it
        // spreads the colors across the range of magnitude values. For your
        // own dataset, you will need to experiment to find what looks good
        // based upon the level of geography when you display the heatmap
        // and the values in your dataset.
        // --------------------------------------------------------------------
        valCtrl.addEventListener("change", function (evt){
          var chk = evt.target.checked;
          if (!chk) {
            document.getElementById("maxValue").innerHTML = 21;
            maxCtrl.value = 21;
            heatmapRenderer.maxPixelIntensity = 21;
          }
          else {
            document.getElementById("maxValue").innerHTML = 250;
            maxCtrl.value = 250;
            heatmapRenderer.maxPixelIntensity = 250;

          }
          heatmapRenderer.field = (chk) ? "Magnitude" : null;
          heatmapFeatureLayer.redraw();
        });
      });
    </script>
</head>
<body>
  <div id="map"></div>
  <div class="blurInfo">
    <p>
      <label for="valueControl">Weight by magnitude</label>
      <input id="valueControl" type="checkbox" checked>
    </p>
    <p>Blur Radius : <span id="blurValue">10</span></p>
    <input id="blurControl" type="range" max=30 min=0 value=10 step=1/>

    <p>Max Value : <span id="maxValue">100</span></p>
    <input id="maxControl" type="range" max=500 min=0 value=100 step=1/>

    <p>Min Value : <span id="minValue">0</span></p>
    <input id="minControl" type="range" max=500 min=0 value=0 step=1/>
  </div>
</body>
</html>