1

I'm using the Javascript example below from the Developers ArcGIS site (4.11), to feed in my own data.

I've trimmed down the code to only populate the the titleContent (0), getting rid of all the charts. This works fine. However, when I point it to my own webmap and try and populate using my layer data it gives me a 0 as output, where I would be expecting a float value.

Is there anything I should be aware of when using this example from ArcGIS Developers?

Query statistics client-side by distance

The statistics definition that I amend is shown below:

const statDefinitions = [
  {
  onStatisticField: "1",
  outStatisticFieldName: "total",
  statisticType: "count"
  }
];

I add my own field to onStatisticField and enter max as the staticType but it only returns a 0 as my allStats.total.

My full amended code below:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1, maximum-scale=1,user-scalable=no"
    />

    <title>Query statistics client-side by distance - 4.11</title>

    <!-- Load the Chart.js library -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>

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

    <style>
      html,
      body {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
        overflow: hidden;
      }

      #viewDiv {
        position: absolute;
        left: 0;
        right: 40%;
        top: 0;
        bottom: 0;
        height: 100%;
      }

      #panel {
        position: absolute;
        right: 0;
        height: 100%;
        width: 40%;
        overflow: scroll;
      }

      #num-homicides {
        color: #ed5050;
        font-size: 36pt;
        font-weight: bolder;
        line-height: 0.8;
      }

    </style>

    <script src="https://js.arcgis.com/4.11/"></script>

    <script>
      require([
        "esri/views/MapView",
        "esri/WebMap",
        "esri/widgets/Legend",
        "esri/widgets/Expand",
        "esri/widgets/Bookmarks",
        "esri/core/lang",
        "esri/core/promiseUtils",
        "esri/core/watchUtils"
      ], function(
        MapView,
        WebMap,
        Legend,
        Expand,
        Bookmarks,
        lang,
        promiseUtils,
        watchUtils
      ) {
        // declare chart variables to update as the under interacts with the sample

        let 
          totalNumber

        // load a web map containing homicide statistics
        // from a portal item

        const webmap = new WebMap({
          portalItem: {
            id: "f75e88c4e6f64a4xxx4d2cf0acbaf0d7"
          }
        });

        const view = new MapView({
          map: webmap,
          container: "viewDiv",
          constraints: {
            minScale: 300000
          },
          highlightOptions: {
            color: "black",
            haloOpacity: 0.65,
            fillOpacity: 0.45
          }
        });

        // Add UI elements to the view

        // Displays instructions to the user for understanding the sample
        // And places them in an Expand widget instance

        const titleContent = document.createElement("div");
        titleContent.style.padding = "15px";
        titleContent.style.backgroundColor = "white";
        titleContent.style.width = "500px";
        titleContent.innerHTML = [
          "<div id='title' class='esri-widget'>",
          "<span id='num-homicides'>0</span> homicides occurred within one mile of the pointer location over the last 10 years.",
          "</div>"
        ].join(" ");

        const titleExpand = new Expand({
          expandIconClass: "esri-icon-dashboard",
          expandTooltip: "Summary stats",
          view: view,
          content: titleContent,
          expanded: view.widthBreakpoint !== "xsmall"
        });
        view.ui.add(titleExpand, "top-right");

        // Displays instructions to the user for understanding the sample
        // And places them in an Expand widget instance

        const sampleInstructions = document.createElement("div");
        sampleInstructions.style.padding = "10px";
        sampleInstructions.style.backgroundColor = "white";
        sampleInstructions.style.width = "300px";
        sampleInstructions.innerHTML = [
          "<b>Drag</b> the pointer over the data to view stats",
          "within one mile of the pointer location."
        ].join(" ");

        const instructionsExpand = new Expand({
          expandIconClass: "esri-icon-question",
          expandTooltip: "How to use this sample",
          view: view,
          content: sampleInstructions
        });
        view.ui.add(instructionsExpand, "top-left");

        let highlightHandle = null;

        /**
         * Create charts and start querying the layer view when
         * the view is ready and data begins to draw in the view
         */
        view.when().then(function() {

          const layer = webmap.layers.getItemAt(0);

          view.whenLayerView(layer).then(function(layerView) {
            watchUtils.whenFalseOnce(layerView, "updating", function(val) {
              // Query layer view statistics as the user clicks
              // or drags the pointer across the view.
              view.on(["click", "drag"], function(event) {
                // disables navigation by pointer drag
                event.stopPropagation();
                queryStatsOnDrag(layerView, event).then(updateCharts);
              });
            });
          });
        });

        /**
         * Queries statistics against the layer view at the given screen location
         */
        function queryStatsOnDrag(layerView, event) {
          // create a query object for the highlight and the statistics query

          const query = layerView.layer.createQuery();
          query.geometry = view.toMap(event); // converts the screen point to a map point
          query.distance = 1; // queries all features within 1 mile of the point
          query.units = "miles";

          const statsQuery = query.clone();

          // date used to calculate the average time a case has been opened

          // Create the statistic definitions for querying stats from the layer view
          // the `onStatisticField` property can reference a field name or a SQL expression
          // `outStatisticFieldName` is the name of the statistic you will reference in the result
          // `statisticType` can be sum, avg, min, max, count, stddev

          const statDefinitions = [

            {
              onStatisticField: "Exposure",
              outStatisticFieldName: "Exposure",
              statisticType: "sum"
            }

           ];

          // add the stat definitions to the the statistics query object cloned earlier
          statsQuery.outStatistics = statDefinitions;

          // execute the query for all features in the layer view
          const allStatsResponse = layerView.queryFeatures(statsQuery).then(
            function(response) {
              const stats = response.features[0].attributes;
              return stats;
            },
            function(e) {
              console.error(e);
            }
          );

          // highlight all features within the query distance
          layerView.queryObjectIds(query).then(function(ids) {
            if (highlightHandle) {
              highlightHandle.remove();
              highlightHandle = null;
            }
            highlightHandle = layerView.highlight(ids);
          });

          // Return the promises that will resolve to each set of statistics
          return promiseUtils.eachAlways([
            allStatsResponse
          ]);
        }

        /**
         * Updates the charts with the data returned from the statistic queries.
         */
        function updateCharts(responses) {
          totalNumber = document.getElementById("num-homicides");
          const allStats = responses[0].value;
          totalNumber.innerHTML = allStats.Exposure;
          console.log(allStats.exposureVal)
        }

      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="panel">
      <div style="padding: 15px;">
      </div>
    </div>
  </body>
</html>
1

I'm not able to access your webmap item, maybe it's on your own portal?

But a couple of things to try. You are checking statistics on the Exposure field, so try adding it in the outFields to the layer from the webmap.

const webmap = new WebMap({
  portalItem: {
    id: "f75e88c4e6f64a4xxx4d2cf0acbaf0d7"
  }
});

webmap.load().then(function() {
  const layer = web.findLayerById('needLayerId');
  layer.outFields = layer.outFields || [];
  layer.outFields.push('Exposure'); // might not be included by the map
  // continue rest of your application from here
})

Because the statistics are being run on the data in the client, you may not have the Exposure field available, so your statistics don't return a result.

With FeatureLayers only fields required visualizing data is requested. Popup fields are requested as needed.

The other is in how you define your statistics. You have the statistic field and out field named the same. I don't know if this could break something or throw error, but it might.

Try like this.

      const statDefinitions = [

        {
          onStatisticField: "Exposure",
          outStatisticFieldName: "ExposureSum", // try this
          statisticType: "sum"
        }
      ]
  • Thank you for the above. The suggested code didn't seem to change anything. I also changed the on and out statistic field names. However, it did point me in the right direction. I have amended the labels feature in the UI to show the Exposure column and this field is now pulling through and being calculated. Can you think of why the push layer method didn't work in your code example above. – CGarden May 17 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.