Popup charts for point clusters

Explore in the sandboxView live

This sample demonstrates how to summarize clustered features by type using charts in a cluster's popup. The app visualizes power plants as point clusters. Each cluster's popup displays a list of the five most common fuel types used to generate power within the cluster. It also includes two pie charts that summarize the number of power plants by fuel type and the total mW capacity for each fuel type within the cluster.

The list and charts are created using ExpressionContent popup elements, which can be used to conditionally build rich text, charts, or field lists with Arcade expressions. Expressions that return popup elements must return a dictionary representing the web map specification of the desired content element. The following popup elements are supported: TextContent, FieldsContent, and MediaContent.

Create an HTML list with Arcade

To return HTML from an Arcade expression, the HTML must be returned as a TextContent element. Expressions for building a text content element must return a dictionary matching the following specification:

Use dark colors for code blocksCopy
    
1
2
3
4
return {
  type: "text",
  text: "<b>The text to display in the popup</b>"
}

Because TextContent can contain rich text, we can dynamically build HTML elements as a text value within an Arcade expression. Note that you cannot return HTML in Arcade in any other case, such as displaying an expression value from the PopupTemplate.expressionInfos property.

The following expression demonstrates how this works. Read the comments for details.

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
// Inform the popup, which fields the expression expects to use
// to ensure they are downloaded to the client
Expects($aggregatedFeatures, "fuel1", "capacity_mw")

// Get the total number of features in the cluster
// grouped by type and store it in a num_features field
var statsFS = GroupBy($aggregatedFeatures,
  [
    { name: 'Type', expression: 'fuel1'},
  ],
  [
    { name: 'num_features', expression: '1', statistic: 'COUNT' }
  ]
);
// Only return the top 5 results ordered by total features
var ordered = Top(OrderBy(statsFs, 'num_features DESC'), 5);

// create an HTML ordered list as a string
var list = "<ol>";

// Create a new list item for each type in the top 5 'ordered' featureset
for (var group in ordered){
  list += \`<li>\${group.Type} (\${Text(group.num_features, "#,###")})</li>\`
}
list += "</ol>";

// return the list as rich text
return {
  type: "text",
  text: list
}

Create pie charts with Arcade

Expressions for charts must return a dictionary matching the web map specification of a MediaContent element:

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
return {
  type: "media",
  attributes: {
    field1: number,
    field2: number
  },
  title: "Media content title",
  mediaInfos: [
    {
      type: "piechart",  // can also be "columnchart", "linechart", "piechart", "image"
      title: "Chart title",
      value: {
        // the list of attribute values to include in the chart
        fields: [ "field1", "field2" ]
      }
    }
  // you can define more charts here
  ]
}

When implemented in JavaScript, the charts can be defined with a list of field names. However, when dynamically creating charts with Arcade, you must create an attributes dictionary that stores key-value pairs containing the data to use in the chart. The keys are the field names to reference in the fields property of the chart value.

The following expression demonstrates how this works by creating two pie charts. Read the comments for details.

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
// Inform the popup, which fields the expression expects to use
// to ensure they are downloaded to the client
Expects($aggregatedFeatures, "fuel1", "capacity_mw");
// create an object to store attributes
// and arrays used to store field names for each chart
var attributes = {};
var countFieldNames = [];
var capacityFieldNames = [];

// Get the distinct types of fuel within the cluster.
// This can be an array of 1-12 types depending on the cluster.
var types = Distinct($aggregatedFeatures, "fuel1");

// add attributes to the dictionary for each type
// one for the total count, the other for capacity
for(var t in types){
  var type = t.fuel1;
  // contains all the features belonging to the type
  // on this iteration of the loop
  var filtered = Filter($aggregatedFeatures, "fuel1 = @type");

  // Create a field name for the count of the current type
  var countFieldName = type + " count";
  // Store the total number of features in the attribute
  attributes[countFieldName] = Count(filtered);
  // Push the fieldName to the appropriate array
  Push(countFieldNames, countFieldName);

  // Repeat this process for the second chart
  var capacityFieldName = type + " capacity (mW)";
  // Instead of count, get the sum for the capacity and add to attributes
  attributes[capacityFieldName] = DefaultValue(Sum(filtered, "capacity_mw"), 0);
  Push(capacityFieldNames, capacityFieldName);
}

return {
  type: "media",
  // attributes for both charts here
  attributes: attributes,
  title: "Count vs. capacity comparison",
  // list keys for attributes for each chart in "value"
  mediaInfos: [{
    type: "piechart",
    title: "Total count",
    value: {
      fields: countFieldNames
    }
  }, {
    type: "piechart",
    title: "Total capacity (mW)",
    value: {
      fields: capacityFieldNames
    }
  }]
}

The expressions are added directly to an ExpressionContent element within the popupTemplate content.

Use dark colors for code blocksCopy
                 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
layer.featureReduction = {
  type: "cluster",
  popupTemplate: {
    title: "Power plant summary",
    content: [{
      type: "expression",
      expressionInfo: "// list expression here",
      title: "List of fuel types"
    }, {
      type: "expression",
      expressionInfo: {
        expression: "// chart expression here"
        title: "Pie charts"
      }
    }]
  }
};
Image preview of related sample Point clustering - basic configuration

Point clustering - basic configuration

Point clustering - basic configuration

Image preview of related sample Point clustering - generate suggested configuration

Point clustering - generate suggested configuration

Point clustering - generate suggested configuration

Image preview of related sample Point clustering - filter popup features

Point clustering - filter popup features

This sample demonstrates how to filter clustered features within a cluster's popup.

Image preview of related sample Point clustering - query clusters

Point clustering - query clusters

Point clustering - query clusters

Image preview of related sample Point clustering - advanced configuration

Point clustering - advanced configuration

Point clustering - advanced configuration

ExpressionContent

Read the API Reference for more information.

FeatureReductionCluster

Read the API Reference for more information.

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