Query statistics client-side

This sample demonstrates how to query for statistics in a FeatureLayerView and display the results of the query in a chart as custom content in a LayerList panel.

This app displays educational attainment data in Mexico. The layer displays the predominant education level achieved among all the residents ages 12 and older in each municipality using an Arcade expression in a UniqueValueRenderer. The total population belonging to each category among all features in the view extent is displayed in a chart in the LayerList panel's content. This chart updates each time the user pans or zooms in/out of the view.

How it works

After the view is ready, create a LayerList instance and add DOM elements as custom content to each list item's panel. You can place anything in these elements. In the case of this sample, we place a pie chart in the predominance layer's list item panel surrounded by text. We also set the container property of the LayerList to a custom DOM element to place it outside of the view's default UI.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
let layerList = new LayerList({
  view: view,
  container: document.createElement("div"),
  listItemCreatedFunction: function(event) {
    const item = event.item;

    // add the pie chart to the Predominance layer list item panel
    if (item.title === predominanceLayer.title) {
      item.panel = {
        content: [
          [
            "<b>Educational attainment</b> refers to the highest level of education that an individual has completed. ",
            "This chart categorizes the population living within the current ",
            "view extent by their educational attainment."
          ].join(""),

          document.createElement("canvas"),

          [
            "Notice that while one attainment level appears to dominate certain regions, it doesn't ",
            "necessarily mean it represents the majority of the population. In fact, as ",
            "you explore most areas, you will find the predominant educational attainment makes up ",
            "just a fraction of the population due to the number of categories considered."
          ].join("")
        ],
        className: "esri-icon-pie-chart",
        open: item.visible
      };
    }
  }
});
layerList.container.style = "height: 100%";
let panelDiv = document.getElementById("panel");
panelDiv.appendChild(layerList.container);

A statistics query on a FeatureLayerView occurs client-side, which provides you with the ability to create highly interactive apps because of fast response times. In this sample, statistics are queried on the layer each time the layer view finishes fetching new features. For example, new features will be fetched when the user pans and zooms in or out of the view in this sample. We handle this by watching for the dataUpdating property of the layer view.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
// Update the pie chart after once the layer view finishes updating its data
view.whenLayerView(predominanceLayer).then((layerView) => {
  reactiveUtils.when(() => !layerView.dataUpdating, () => {
    queryLayerViewStats(layerView).then(function (newData) {
      updateChart(newData);
    });
  });
});

Create an array of StatisticDefinition objects, setting a field name and statistic type for each field for which you wish to query statistics. In this sample, we want to display the total number of people in each educational attainment category. We do this by indicating each field name and setting the sum statistic type. This will sum the values of each field for all features within the view's extent.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
function queryLayerViewStats(layerView) {
  const educationFields = [
    "EDUC01_CY",
    "EDUC02_CY",
    "EDUC03_CY",
    "EDUC04_CY",
    "EDUC05_CY",
    "EDUC06_CY",
    "EDUC07_CY",
    "EDUC08_CY",
    "EDUC09_CY",
    "EDUC10_CY",
    "EDUC11_CY",
    "EDUC12_CY",
    "EDUC13_CY",
    "EDUC14_CY",
    "EDUC15_CY",
    "EDUC16_CY",
    "EDUCA_BASE"
  ];

  // Creates a query object for statistics of each of the fields listed above
  const statDefinitions = educationFields.map(function(fieldName) {
    return {
      onStatisticField: fieldName,
      outStatisticFieldName: fieldName + "_TOTAL",
      statisticType: "sum"
    };
  });

  // query statistics for features only in view extent
  const query = layerView.layer.createQuery();
  query.outStatistics = statDefinitions;
  query.geometry = view.extent;

  // query features within the view's extent on the client
  return layerView.queryFeatures(query).then(function(response) {
    const stats = response[0].attributes;

    const updatedData = [
      stats.EDUC01_CY_TOTAL, // no school
      stats.EDUC02_CY_TOTAL, // preschool
      stats.EDUC03_CY_TOTAL, // some elementary
      stats.EDUC04_CY_TOTAL + stats.EDUC07_CY_TOTAL, // elementary
      stats.EDUC05_CY_TOTAL, // some secondary
      stats.EDUC06_CY_TOTAL + stats.EDUC08_CY_TOTAL, // secondary
      stats.EDUC09_CY_TOTAL + stats.EDUC11_CY_TOTAL, // high school
      stats.EDUC10_CY_TOTAL +
        stats.EDUC12_CY_TOTAL +
        stats.EDUC13_CY_TOTAL +
        stats.EDUC14_CY_TOTAL +
        stats.EDUC15_CY_TOTAL, // college
      stats.EDUC16_CY_TOTAL // not specified
    ];

    // data used to update the pie chart
    return {
      total: stats.EDUCA_BASE_TOTAL,
      values: updatedData
    };
  });
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.