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:
- Query the crimes that intersect a selected polygon.
- Group those intersecting points by crime type and return the total count and average
is_nightvalue within each category. - Sort the groups in descending order by count.
These three steps are reflected in the expression below.
<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.
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.