Home > Back-end >  Unable to change the information by changing the buffer size
Unable to change the information by changing the buffer size

Time:10-23

I m trying to make Client-side feature queries which are useful in situations where the application should deliver immediate results in response to user input. With queries on the LayerView there is no round-trip to the server. In this code, users can draw a polygon, polyline or point geometry which is then used as the spatial geometry parameter in the query.

But when I execute the code, all code is working fine, but when I change the buffer size, from lets suppose 30 to 50 meters the graph values don’t change.

Any suggestions?

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>
      SceneLayerView - query statistics by geometry | Sample | ArcGIS API for
      JavaScript 4.21
    </title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      .esri-ui-top-right {
        max-height: 100%;
      }

      #queryDiv,
      #resultDiv {
        min-width: 250px;
        font-size: 14px;
        padding: 10px;
        display: none;
        overflow-y: auto;
        overflow-x: hidden;
      }

      .geometry-options {
        display: flex;
        flex-direction: row;
      }
      .geometry-button {
        flex: 1;
        border-style: solid;
        border-width: 1px;
        border-image: none;
      }
      .geometry-button-selected {
        background: #4c4c4c;
        color: #fff;
      }

      #bufferNum {
        width: 90%;
        margin: 2.5em auto 0;
      }

      .count {
        white-space: nowrap;
        font-size: 14px;
        font-weight: bold;
        display: inline-block;
      }
    </style>
    <!-- Load the Chart.js library -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21/"></script>

    <script>
      require([
        "esri/WebScene",
        "esri/views/SceneView",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Sketch/SketchViewModel",
        "esri/widgets/Slider",
        "esri/geometry/geometryEngine",
        "esri/Graphic",
        "esri/core/promiseUtils"
      ], (
        WebScene,
        SceneView,
        GraphicsLayer,
        SketchViewModel,
        Slider,
        geometryEngine,
        Graphic,
        promiseUtils
      ) => {
        // Load webscene and display it in a SceneView
        const webscene = new WebScene({
          portalItem: {
            id: "fb5948b2bb76439792786000b942e5b7"
          }
        });
        // create the SceneView
        const view = new SceneView({
          container: "viewDiv",
          map: webscene
        });
        window.view = view;
        // add a GraphicsLayer for the sketches and the buffer
        const sketchLayer = new GraphicsLayer();
        const bufferLayer = new GraphicsLayer();
        view.map.addMany([bufferLayer, sketchLayer]);

        let sceneLayer = null;
        let sceneLayerView = null;
        let bufferSize = 0;

        // Assign scene layer once webscene is loaded and initialize UI
        webscene.load().then(() => {
          sceneLayer = webscene.layers.find((layer) => {
            return layer.title === "Helsinki textured buildings";
          });
          sceneLayer.outFields = ["buildingMaterial", "yearCompleted"];

          view.whenLayerView(sceneLayer).then((layerView) => {
            sceneLayerView = layerView;
            queryDiv.style.display = "block";
          });
        });

        view.ui.add([queryDiv], "bottom-left");
        view.ui.add([resultDiv], "top-right");

        // use SketchViewModel to draw polygons that are used as a query
        let sketchGeometry = null;
        const sketchViewModel = new SketchViewModel({
          layer: sketchLayer,
          defaultUpdateOptions: {
            tool: "reshape",
            toggleToolOnClick: false
          },
          view: view,
          defaultCreateOptions: { hasZ: false }
        });

        sketchViewModel.on("create", (event) => {
          if (event.state === "complete") {
            sketchGeometry = event.graphic.geometry;
            runQuery();
          }
        });

        sketchViewModel.on("update", (event) => {
          if (event.state === "complete") {
            sketchGeometry = event.graphics[0].geometry;
            runQuery();
          }
        });
        // draw geometry buttons - use the selected geometry to sktech
        const pointBtn = document.getElementById("point-geometry-button");
        const lineBtn = document.getElementById("line-geometry-button");
        const polygonBtn = document.getElementById("polygon-geometry-button");
        pointBtn.addEventListener("click", geometryButtonsClickHandler);
        lineBtn.addEventListener("click", geometryButtonsClickHandler);
        polygonBtn.addEventListener("click", geometryButtonsClickHandler);
        function geometryButtonsClickHandler(event) {
          const geometryType = event.target.value;
          clearGeometry();
          sketchViewModel.create(geometryType);
        }

        const bufferNumSlider = new Slider({
          container: "bufferNum",
          min: 0,
          max: 500,
          steps: 1,
          visibleElements: {
            labels: true
          },
          precision: 0,
          labelFormatFunction: (value, type) => {
            return `${value.toString()}m`;
          },
          values: [0]
        });
        
        function bufferVariablesChanged(event) {
          bufferSize = event.value;
          runQuery();
        }
        // Clear the geometry and set the default renderer
        const clearGeometryBtn = document.getElementById("clearGeometry");
        clearGeometryBtn.addEventListener("click", clearGeometry);

        // Clear the geometry and set the default renderer
        function clearGeometry() {
          sketchGeometry = null;
          sketchViewModel.cancel();
          sketchLayer.removeAll();
          bufferLayer.removeAll();
          clearHighlighting();
          clearCharts();
          resultDiv.style.display = "none";
        }

        // set the geometry query on the visible SceneLayerView
        const debouncedRunQuery = promiseUtils.debounce(() => {
          if (!sketchGeometry) {
            return;
          }

          resultDiv.style.display = "block";
          updateBufferGraphic(bufferSize);
          return promiseUtils.eachAlways([
            queryStatistics(),
            updateSceneLayer()
          ]);
        });

        function runQuery() {
          debouncedRunQuery().catch((error) => {
            if (error.name === "AbortError") {
              return;
            }

            console.error(error);
          });
        }

        // Set the renderer with objectIds
        let highlightHandle = null;
        function clearHighlighting() {
          if (highlightHandle) {
            highlightHandle.remove();
            highlightHandle = null;
          }
        }

        function highlightBuildings(objectIds) {
          // Remove any previous highlighting
          clearHighlighting();
          const objectIdField = sceneLayer.objectIdField;
          document.getElementById("count").innerHTML = objectIds.length;

          highlightHandle = sceneLayerView.highlight(objectIds);
        }

        // update the graphic with buffer
        function updateBufferGraphic(buffer) {
          // add a polygon graphic for the buffer
          if (buffer > 0) {
            const bufferGeometry = geometryEngine.geodesicBuffer(
              sketchGeometry,
              buffer,
              "meters"
            );
            if (bufferLayer.graphics.length === 0) {
              bufferLayer.add(
                new Graphic({
                  geometry: bufferGeometry,
                  symbol: sketchViewModel.polygonSymbol
                })
              );
            } else {
              bufferLayer.graphics.getItemAt(0).geometry = bufferGeometry;
            }
          } else {
            bufferLayer.removeAll();
          }
        }

        function updateSceneLayer() {
          const query = sceneLayerView.createQuery();
          query.geometry = sketchGeometry;
          query.distance = bufferSize;
          return sceneLayerView.queryObjectIds(query).then(highlightBuildings);
        }

        let yearChart = null;
        let materialChart = null;

        function queryStatistics() {
          const statDefinitions = [
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'concrete or lightweight concrete' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_concrete",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'brick' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_brick",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'wood' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_wood",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'steel' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_steel",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial IN ('concrete or lightweight concrete', 'brick', 'wood', 'steel') THEN 0 ELSE 1 END",
              outStatisticFieldName: "material_other",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1850' AND yearCompleted <= '1899') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1850",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1900' AND yearCompleted <= '1924') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1900",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1925' AND yearCompleted <= '1949') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1925",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1950' AND yearCompleted <= '1974') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1950",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1975' AND yearCompleted <= '1999') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1975",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '2000' AND yearCompleted <= '2015') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_2000",
              statisticType: "sum"
            }
          ];
          const query = sceneLayerView.createQuery();
          query.geometry = sketchGeometry;
          query.distance = bufferSize;
          query.outStatistics = statDefinitions;

          return sceneLayerView.queryFeatures(query).then((result) => {
            const allStats = result.features[0].attributes;
            updateChart(materialChart, [
              allStats.material_concrete,
              allStats.material_brick,
              allStats.material_wood,
              allStats.material_steel,
              allStats.material_other
            ]);
            updateChart(yearChart, [
              allStats.year_1850,
              allStats.year_1900,
              allStats.year_1925,
              allStats.year_1950,
              allStats.year_1975,
              allStats.year_2000
            ]);
          }, console.error);
        }

        // Updates the given chart with new data
        function updateChart(chart, dataValues) {
          chart.data.datasets[0].data = dataValues;
          chart.update();
        }

        function createYearChart() {
          const yearCanvas = document.getElementById("year-chart");
          yearChart = new Chart(yearCanvas.getContext("2d"), {
            type: "horizontalBar",
            data: {
              labels: [
                "1850-1899",
                "1900-1924",
                "1925-1949",
                "1950-1974",
                "1975-1999",
                "2000-2015"
              ],
              datasets: [
                {
                  label: "Build year",
                  backgroundColor: "#149dcf",
                  stack: "Stack 0",
                  data: [0, 0, 0, 0, 0, 0]
                }
              ]
            },
            options: {
              responsive: false,
              legend: {
                display: false
              },
              title: {
                display: true,
                text: "Build year"
              },
              scales: {
                xAxes: [
                  {
                    stacked: true,
                    ticks: {
                      beginAtZero: true,
                      precision: 0
                    }
                  }
                ],
                yAxes: [
                  {
                    stacked: true
                  }
                ]
              }
            }
          });
        }
        function createMaterialChart() {
          const materialCanvas = document.getElementById("material-chart");
          materialChart = new Chart(materialCanvas.getContext("2d"), {
            type: "doughnut",
            data: {
              labels: ["Concrete", "Brick", "Wood", "Steel", "Other"],
              datasets: [
                {
                  backgroundColor: [
                    "#FD7F6F",
                    "#7EB0D5",
                    "#B2E061",
                    "#BD7EBE",
                    "#FFB55A"
                  ],
                  borderWidth: 0,
                  data: [0, 0, 0, 0, 0]
                }
              ]
            },
            options: {
              responsive: false,
              cutoutPercentage: 35,
              legend: {
                position: "bottom"
              },
              title: {
                display: true,
                text: "Building Material"
              }
            }
          });
        }

        function clearCharts() {
          updateChart(materialChart, [0, 0, 0, 0, 0]);
          updateChart(yearChart, [0, 0, 0, 0, 0, 0]);
          document.getElementById("count").innerHTML = 0;
        }

        createYearChart();
        createMaterialChart();
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="queryDiv" class="esri-widget">
      <b>Query by geometry</b><br />
      <br />Draw a geometry to query by:
      <div class="geometry-options">
        <button
          class="esri-widget--button esri-icon-map-pin geometry-button"
          id="point-geometry-button"
          value="point"
          title="Query by point"
        ></button>
        <button
          class="esri-widget--button esri-icon-polyline geometry-button"
          id="line-geometry-button"
          value="polyline"
          title="Query by line"
        ></button>
        <button
          class="esri-widget--button esri-icon-polygon geometry-button"
          id="polygon-geometry-button"
          value="polygon"
          title="Query by polygon"
        ></button>
      </div>
      <br />
      <div class="tooltip">
        <label for="bufferNum">Set a geometry buffer size:</label>
        <div id="bufferNum"></div>
      </div>
      <br />
      <button class="esri-button" id="clearGeometry" type="button">
        Clear
      </button>
    </div>

    <div id="resultDiv" class="esri-widget">
      <div class="count">
        Selected Buildings:
        <div class="count" id="count">0</div>
      </div>
      <div class="charts">
        <div>
          <canvas id="year-chart" height="250" width="260" />
        </div>
        <div>
          <canvas id="material-chart" width="250" height="300" />
        </div>
      </div>
    </div>
  </body>
</html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Your code is correct, you just missed to bound bufferVariablesChanged to a event from the buffer slider. That is why it never changes, bufferSize is always 0.

Something like this will give values,

function bufferVariablesChanged(event) {
    if (
        event.type === "thumb-change"
        || (event.type === "thumb-drag" && event.state === "stop")
    ) {
        bufferSize = event.value;
        runQuery();
    }
}
bufferNumSlider.on("thumb-change", bufferVariablesChanged);
bufferNumSlider.on("thumb-drag", bufferVariablesChanged);

I made some small change to bufferVariablesChanged function in order to use it also for the drag event.

CodePudding user response:

You are not allowing user values to take impact, add in your code this small code, and your code will start taking buffer values on the fly.

    bufferNumSlider.on(
      ["thumb-change", "thumb-drag"],
      bufferVariablesChanged

So your final code will take this shape:

<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>
      SceneLayerView - query statistics by geometry | Sample | ArcGIS API for
      JavaScript 4.21
    </title>
    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      .esri-ui-top-right {
        max-height: 100%;
      }

      #queryDiv,
      #resultDiv {
        min-width: 250px;
        font-size: 14px;
        padding: 10px;
        display: none;
        overflow-y: auto;
        overflow-x: hidden;
      }

      .geometry-options {
        display: flex;
        flex-direction: row;
      }
      .geometry-button {
        flex: 1;
        border-style: solid;
        border-width: 1px;
        border-image: none;
      }
      .geometry-button-selected {
        background: #4c4c4c;
        color: #fff;
      }

      #bufferNum {
        width: 90%;
        margin: 2.5em auto 0;
      }

      .count {
        white-space: nowrap;
        font-size: 14px;
        font-weight: bold;
        display: inline-block;
      }
    </style>
    <!-- Load the Chart.js library -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.21/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.21/"></script>

    <script>
      require([
        "esri/WebScene",
        "esri/views/SceneView",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Sketch/SketchViewModel",
        "esri/widgets/Slider",
        "esri/geometry/geometryEngine",
        "esri/Graphic",
        "esri/core/promiseUtils"
      ], (
        WebScene,
        SceneView,
        GraphicsLayer,
        SketchViewModel,
        Slider,
        geometryEngine,
        Graphic,
        promiseUtils
      ) => {
        // Load webscene and display it in a SceneView
        const webscene = new WebScene({
          portalItem: {
            id: "fb5948b2bb76439792786000b942e5b7"
          }
        });
        // create the SceneView
        const view = new SceneView({
          container: "viewDiv",
          map: webscene
        });
        window.view = view;
        // add a GraphicsLayer for the sketches and the buffer
        const sketchLayer = new GraphicsLayer();
        const bufferLayer = new GraphicsLayer();
        view.map.addMany([bufferLayer, sketchLayer]);

        let sceneLayer = null;
        let sceneLayerView = null;
        let bufferSize = 0;

        // Assign scene layer once webscene is loaded and initialize UI
        webscene.load().then(() => {
          sceneLayer = webscene.layers.find((layer) => {
            return layer.title === "Helsinki textured buildings";
          });
          sceneLayer.outFields = ["buildingMaterial", "yearCompleted"];

          view.whenLayerView(sceneLayer).then((layerView) => {
            sceneLayerView = layerView;
            queryDiv.style.display = "block";
          });
        });

        view.ui.add([queryDiv], "bottom-left");
        view.ui.add([resultDiv], "top-right");

        // use SketchViewModel to draw polygons that are used as a query
        let sketchGeometry = null;
        const sketchViewModel = new SketchViewModel({
          layer: sketchLayer,
          defaultUpdateOptions: {
            tool: "reshape",
            toggleToolOnClick: false
          },
          view: view,
          defaultCreateOptions: { hasZ: false }
        });

        sketchViewModel.on("create", (event) => {
          if (event.state === "complete") {
            sketchGeometry = event.graphic.geometry;
            runQuery();
          }
        });

        sketchViewModel.on("update", (event) => {
          if (event.state === "complete") {
            sketchGeometry = event.graphics[0].geometry;
            runQuery();
          }
        });
        // draw geometry buttons - use the selected geometry to sktech
        const pointBtn = document.getElementById("point-geometry-button");
        const lineBtn = document.getElementById("line-geometry-button");
        const polygonBtn = document.getElementById("polygon-geometry-button");
        pointBtn.addEventListener("click", geometryButtonsClickHandler);
        lineBtn.addEventListener("click", geometryButtonsClickHandler);
        polygonBtn.addEventListener("click", geometryButtonsClickHandler);
        function geometryButtonsClickHandler(event) {
          const geometryType = event.target.value;
          clearGeometry();
          sketchViewModel.create(geometryType);
        }

        const bufferNumSlider = new Slider({
          container: "bufferNum",
          min: 0,
          max: 500,
          steps: 1,
          visibleElements: {
            labels: true
          },
          precision: 0,
          labelFormatFunction: (value, type) => {
            return `${value.toString()}m`;
          },
          values: [0]
        });
        // get user entered values for buffer
        bufferNumSlider.on(
          ["thumb-change", "thumb-drag"],
          bufferVariablesChanged
        );
        function bufferVariablesChanged(event) {
          bufferSize = event.value;
          runQuery();
        }
        // Clear the geometry and set the default renderer
        const clearGeometryBtn = document.getElementById("clearGeometry");
        clearGeometryBtn.addEventListener("click", clearGeometry);

        // Clear the geometry and set the default renderer
        function clearGeometry() {
          sketchGeometry = null;
          sketchViewModel.cancel();
          sketchLayer.removeAll();
          bufferLayer.removeAll();
          clearHighlighting();
          clearCharts();
          resultDiv.style.display = "none";
        }

        // set the geometry query on the visible SceneLayerView
        const debouncedRunQuery = promiseUtils.debounce(() => {
          if (!sketchGeometry) {
            return;
          }

          resultDiv.style.display = "block";
          updateBufferGraphic(bufferSize);
          return promiseUtils.eachAlways([
            queryStatistics(),
            updateSceneLayer()
          ]);
        });

        function runQuery() {
          debouncedRunQuery().catch((error) => {
            if (error.name === "AbortError") {
              return;
            }

            console.error(error);
          });
        }

        // Set the renderer with objectIds
        let highlightHandle = null;
        function clearHighlighting() {
          if (highlightHandle) {
            highlightHandle.remove();
            highlightHandle = null;
          }
        }

        function highlightBuildings(objectIds) {
          // Remove any previous highlighting
          clearHighlighting();
          const objectIdField = sceneLayer.objectIdField;
          document.getElementById("count").innerHTML = objectIds.length;

          highlightHandle = sceneLayerView.highlight(objectIds);
        }

        // update the graphic with buffer
        function updateBufferGraphic(buffer) {
          // add a polygon graphic for the buffer
          if (buffer > 0) {
            const bufferGeometry = geometryEngine.geodesicBuffer(
              sketchGeometry,
              buffer,
              "meters"
            );
            if (bufferLayer.graphics.length === 0) {
              bufferLayer.add(
                new Graphic({
                  geometry: bufferGeometry,
                  symbol: sketchViewModel.polygonSymbol
                })
              );
            } else {
              bufferLayer.graphics.getItemAt(0).geometry = bufferGeometry;
            }
          } else {
            bufferLayer.removeAll();
          }
        }

        function updateSceneLayer() {
          const query = sceneLayerView.createQuery();
          query.geometry = sketchGeometry;
          query.distance = bufferSize;
          return sceneLayerView.queryObjectIds(query).then(highlightBuildings);
        }

        let yearChart = null;
        let materialChart = null;

        function queryStatistics() {
          const statDefinitions = [
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'concrete or lightweight concrete' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_concrete",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'brick' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_brick",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'wood' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_wood",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial = 'steel' THEN 1 ELSE 0 END",
              outStatisticFieldName: "material_steel",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN buildingMaterial IN ('concrete or lightweight concrete', 'brick', 'wood', 'steel') THEN 0 ELSE 1 END",
              outStatisticFieldName: "material_other",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1850' AND yearCompleted <= '1899') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1850",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1900' AND yearCompleted <= '1924') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1900",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1925' AND yearCompleted <= '1949') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1925",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1950' AND yearCompleted <= '1974') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1950",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '1975' AND yearCompleted <= '1999') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_1975",
              statisticType: "sum"
            },
            {
              onStatisticField:
                "CASE WHEN (yearCompleted >= '2000' AND yearCompleted <= '2015') THEN 1 ELSE 0 END",
              outStatisticFieldName: "year_2000",
              statisticType: "sum"
            }
          ];
          const query = sceneLayerView.createQuery();
          query.geometry = sketchGeometry;
          query.distance = bufferSize;
          query.outStatistics = statDefinitions;

          return sceneLayerView.queryFeatures(query).then((result) => {
            const allStats = result.features[0].attributes;
            updateChart(materialChart, [
              allStats.material_concrete,
              allStats.material_brick,
              allStats.material_wood,
              allStats.material_steel,
              allStats.material_other
            ]);
            updateChart(yearChart, [
              allStats.year_1850,
              allStats.year_1900,
              allStats.year_1925,
              allStats.year_1950,
              allStats.year_1975,
              allStats.year_2000
            ]);
          }, console.error);
        }

        // Updates the given chart with new data
        function updateChart(chart, dataValues) {
          chart.data.datasets[0].data = dataValues;
          chart.update();
        }

        function createYearChart() {
          const yearCanvas = document.getElementById("year-chart");
          yearChart = new Chart(yearCanvas.getContext("2d"), {
            type: "horizontalBar",
            data: {
              labels: [
                "1850-1899",
                "1900-1924",
                "1925-1949",
                "1950-1974",
                "1975-1999",
                "2000-2015"
              ],
              datasets: [
                {
                  label: "Build year",
                  backgroundColor: "#149dcf",
                  stack: "Stack 0",
                  data: [0, 0, 0, 0, 0, 0]
                }
              ]
            },
            options: {
              responsive: false,
              legend: {
                display: false
              },
              title: {
                display: true,
                text: "Build year"
              },
              scales: {
                xAxes: [
                  {
                    stacked: true,
                    ticks: {
                      beginAtZero: true,
                      precision: 0
                    }
                  }
                ],
                yAxes: [
                  {
                    stacked: true
                  }
                ]
              }
            }
          });
        }
        function createMaterialChart() {
          const materialCanvas = document.getElementById("material-chart");
          materialChart = new Chart(materialCanvas.getContext("2d"), {
            type: "doughnut",
            data: {
              labels: ["Concrete", "Brick", "Wood", "Steel", "Other"],
              datasets: [
                {
                  backgroundColor: [
                    "#FD7F6F",
                    "#7EB0D5",
                    "#B2E061",
                    "#BD7EBE",
                    "#FFB55A"
                  ],
                  borderWidth: 0,
                  data: [0, 0, 0, 0, 0]
                }
              ]
            },
            options: {
              responsive: false,
              cutoutPercentage: 35,
              legend: {
                position: "bottom"
              },
              title: {
                display: true,
                text: "Building Material"
              }
            }
          });
        }

        function clearCharts() {
          updateChart(materialChart, [0, 0, 0, 0, 0]);
          updateChart(yearChart, [0, 0, 0, 0, 0, 0]);
          document.getElementById("count").innerHTML = 0;
        }

        createYearChart();
        createMaterialChart();
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="queryDiv" class="esri-widget">
      <b>Query by geometry</b><br />
      <br />Draw a geometry to query by:
      <div class="geometry-options">
        <button
          class="esri-widget--button esri-icon-map-pin geometry-button"
          id="point-geometry-button"
          value="point"
          title="Query by point"
        ></button>
        <button
          class="esri-widget--button esri-icon-polyline geometry-button"
          id="line-geometry-button"
          value="polyline"
          title="Query by line"
        ></button>
        <button
          class="esri-widget--button esri-icon-polygon geometry-button"
          id="polygon-geometry-button"
          value="polygon"
          title="Query by polygon"
        ></button>
      </div>
      <br />
      <div class="tooltip">
        <label for="bufferNum">Set a geometry buffer size:</label>
        <div id="bufferNum"></div>
      </div>
      <br />
      <button class="esri-button" id="clearGeometry" type="button">
        Clear
      </button>
    </div>

    <div id="resultDiv" class="esri-widget">
      <div class="count">
        Selected Buildings:
        <div class="count" id="count">0</div>
      </div>
      <div class="charts">
        <div>
          <canvas id="year-chart" height="250" width="260" />
        </div>
        <div>
          <canvas id="material-chart" width="250" height="300" />
        </div>
      </div>
    </div>
  </body>
</html>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related