Skip to content

This sample demonstrates how use an Arcade expression in a PopupTemplate to summarize points from one layer that intersect a polygon in a different layer.

The map in this sample contains two layers: a polygon layer representing block groups and a point layer representing the locations of crimes. Each crime has a desc_ field describing the type of crime committed. It also has a is_night field containing either a 1 (crime committed at night) or a 0 (crime committed during the day). This app uses a single Arcade expression to do the following each time the user clicks a feature and opens the popup:

  1. Query the crimes that intersect a selected polygon.
  2. Group those intersecting points by crime type and return the total count and average is_night value within each category.
  3. Sort the groups in descending order by count.

These three steps are reflected in the expression below.

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    <script type="text/arcgis-arcade" id="crimes-arcade">
        // Query the number of crimes that intersect a selected polygon
      var crimes = Intersects(
        $feature,
        FeatureSetByName($map,"San Diego crimes", ["desc_", "is_night"])
      );

      // Queries the count of crimes grouped by the "desc_" field
      var stats = GroupBy(crimes, ["desc_"],
        [ { name: "total", expression: "1", statistic: "count" },
          { name: "night_avg", expression: "is_night", statistic: "avg" }
        ]
      );

      // Orders the results in descending order by the total count
      // excludes crimes that don't have a classification
      var topCrimes = Top(OrderBy(Filter(stats, "desc_ <> ''"), "total desc"), 3);

      var output = "";
      if(Count(topCrimes) == 0){
        return "No crimes committed in this area";
      }
      var num = 0;
      // Format the results for display
      for(var item in topCrimes){
        num++;
        var num_crimes = item.total;
        var crimeType = item["desc_"];

        // The isNight field has values of either 1 or 0.
        // If the average value is high, then most crimes
        // occurred at night. If the average is low, then
        // the crimes typically occurred during daytime hours.
        var timeOfDay = When(
          item.night_avg >= 0.6, "at night",
          item.night_avg <= 0.4, " during the daytime hours",
        " at both night and day");

        // Display crime type with count using template literals
        output += `${num}. ${crimeType}
          -- Total offenses: ${Text(num_crimes, "#,###")}
          -- Most crimes were reported ${timeOfDay}

          `;
      }
      return output;
    </script>

The Arcade documentation for GroupBy() contains additional information for how to query multiple statistics (e.g. sum, min, max, average, standard deviation, variance) in Arcade with a single function call.

After authoring the Arcade expression, you can reference it in JavaScript as a string value and set it to the expression property of the expressionInfos in the layer's popupTemplate.

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
      const arcadeScript = document.getElementById("crimes-arcade").text;
      const blockGroups = new FeatureLayer({
        title: "U.S. Census Block Groups",
        portalItem: {
          id: "181b322639d44fcba6e37d8b82910daf",
        },
        popupTemplate: {
          title: "Tract: {Tract}, Block Group: {BLKGRP}",
          content: "Top 3 crimes: <br\><br\>" + "{expression/top-crimes}",
          expressionInfos: [
            {
              // the name is used to reference the expression value in the template
              name: "top-crimes",
              title: "Top crimes",
              // the Arcade expression stored as text
              expression: arcadeScript,
            },
          ],
        },
      });

See the Popup profile of the Arcade expressions guide and the Reference Arcade expressions in PopupTemplate sample for more information about writing Arcade expressions for popups.

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