Select to view content in your preferred language

How to build an aggregate field on field value group counts?

307
3
Jump to solution
11-21-2024 06:32 AM
ChristopheDiPrima
Emerging Contributor

I am building a map representing activities of some users and I would like to be able to clusterise on the number of different users being active on a spécific cluster. My activity features look like this:

 

 

 

const features = [
 {user_id: "A", activity_id: 1},
 {user_id: "A", activity_id: 2},
 {user_id: "B", activity_id: 3},
 {user_id: "C", activity_id: 4},
 {user_id: "A", activity_id: 5},
]

 

 

 

I am using a ClassBreaksRenderer and I would like the color of the cluster to represent the number of unic 'user_id' for the cluster. The cluster count representing all the features above would be 3 (A + B + C).

AggregateFields with staticType 'count' doesn't allow to pass a groupBy field

0 Kudos
1 Solution

Accepted Solutions
AnneFitz
Esri Regular Contributor

Yes, this is possible, it just requires a bit of Arcade. The first step is creating an AggregateField for each user ID, using an Arcade expression to return 1 if the feature matches the given user type, and 0 if not (this is essentially just going to count the number of users with a given user_id in each cluster):

new AggregateField({
  name: "SUM_USER_A",
  onStatisticExpression: new ExpressionInfo({
     title: "User A",
     returnType: "number",
     expression: "Number($feature.user_id == 'A')"
  }),
  statisticType: "sum"
})

Do this for each user type so that you have a SUM_USER_A, SUM_USER_B, SUM_USER_C, and so on... 

Then, set a cluster renderer using another Arcade expression to Count all the aggregate fields that do not equal zero, and voila! You have the # of user types in each cluster.

var fields = [$feature.SUM_USER_A, $feature.SUM_USER_B, $feature.SUM_USER_C];

function isNotZero(value){
  return value != 0;
}
Count(Filter(fields, isNotZero))

 

Here's an example where I did something similar with NYC's boroughs, where the clusters are colored based on the number of boroughs represented by each cluster: https://codepen.io/annefitz/pen/dPbZVpP?editors=1000

View solution in original post

3 Replies
ChristopheDiPrima
Emerging Contributor

Actulally I would like the number and the size of the cluster to be 5 (5 activities) and the color of the cluster to be defined by some stops following the number of different "user_id"s (A + B + C = 3). Is this possible?

0 Kudos
AnneFitz
Esri Regular Contributor

Yes, this is possible, it just requires a bit of Arcade. The first step is creating an AggregateField for each user ID, using an Arcade expression to return 1 if the feature matches the given user type, and 0 if not (this is essentially just going to count the number of users with a given user_id in each cluster):

new AggregateField({
  name: "SUM_USER_A",
  onStatisticExpression: new ExpressionInfo({
     title: "User A",
     returnType: "number",
     expression: "Number($feature.user_id == 'A')"
  }),
  statisticType: "sum"
})

Do this for each user type so that you have a SUM_USER_A, SUM_USER_B, SUM_USER_C, and so on... 

Then, set a cluster renderer using another Arcade expression to Count all the aggregate fields that do not equal zero, and voila! You have the # of user types in each cluster.

var fields = [$feature.SUM_USER_A, $feature.SUM_USER_B, $feature.SUM_USER_C];

function isNotZero(value){
  return value != 0;
}
Count(Filter(fields, isNotZero))

 

Here's an example where I did something similar with NYC's boroughs, where the clusters are colored based on the number of boroughs represented by each cluster: https://codepen.io/annefitz/pen/dPbZVpP?editors=1000

ChristopheDiPrima
Emerging Contributor

Works like a charm! Thank you so much! 😀

0 Kudos