Custom Cluster icon based on condition logic from 3 features properties

468
5
Jump to solution
02-01-2024 04:56 AM
DanielMoga
New Contributor II

 

Hello community!

I'm new to GIS technology and terminology, and I hope I can explain my issue correctly.

I'm working with a FeatureLayer, and for each item in the features, there's a specific logic for its symbol. Now, I need to implement a logic where clusters have different icons based on three feature properties.

For example, consider the following structure:

featureLayer => features: any[] => just for example = [
{ status: 'U', alert: '', priority: 'high' },
{ status: 'C', alert: '1', priority: 'high' },
{ status: 'U', alert: '1', priority: 'low'},
.........................
]
 

During feature reduction, I need the cluster to have a specific symbol if it contains items with status 'U' and no alerts, another symbol if there are items with status 'C', and so on, covering all combinations of statuses, alerts, and priorities.

From what I've observed, the cluster.featureReduction.renderer seems to overwrite the individual renderer.

Is there a way to achieve this functionality?

0 Kudos
1 Solution

Accepted Solutions
KristianEkenes
Esri Regular Contributor

Yes you would need to set layer.featureReduction.renderer. to incorporate the three field values, you can either use a UniqueValueRenderer (if all the values are categorical) OR write an Arcade expression to combine them into a composite score. Something like the example below. Note that since this is a cluster renderer the attributes in $feature come from featureReduction.fields NOT layer.fields. So you'll need to account for that.

const clusterRenderer = new SimpleRenderer({
  symbol: {
    type: "simple-marker",
    size: 8,
    outline: {
      width: 0.5,
      color: "rgba(255,255,255,0.5)"
    }
  },
  visualVariables: [{
    type: "size",
    field: "cluster_count",
    minSize: 12,
    maxSize: 60,
    minDataValue: 1,
    maxDataValue: 1000
  }, {
    type: "color",
    valueExpression: `
      // $feature gives you access to feature attributes.
      var status = Decode($feature.status,
        "U", 10,
        "C", 5,
        0
      );  
      var alert = Number($feature.alert);
      var priority = Decode($feature.priority,
        "High", 10,
        "Medium", 5,
        "Low", 3,
        0
      );

      var score = (status + alert + priority) / 3;
      return score;
    `,
    stops: [
      { value: 0, color: "white" },
      { value: 3, color: "beige" },
      { value: 5, color: "yellow" },
      { value: 7, color: "orange" },
      { value: 10, color: "red" }
    ]
  }]
});

layer.featureReduction.renderer = clusterRenderer;

mposite score or level.

for example...

 

 

View solution in original post

0 Kudos
5 Replies
JeffreyThompson2
MVP Regular Contributor

You can define the featureReduction renderer with visual variables as in this example. 

https://developers.arcgis.com/javascript/latest/sample-code/featurereduction-cluster-visualvariables...

Visual variable can also be used with an UniqueVauleRenderer, so you can make your most important variable change what kind of icon is used and the other variables adjust the color or size.

https://developers.arcgis.com/javascript/latest/api-reference/esri-renderers-UniqueValueRenderer.htm...

GIS Developer
City of Arlington, Texas
0 Kudos
KristianEkenes
Esri Regular Contributor

Yes you would need to set layer.featureReduction.renderer. to incorporate the three field values, you can either use a UniqueValueRenderer (if all the values are categorical) OR write an Arcade expression to combine them into a composite score. Something like the example below. Note that since this is a cluster renderer the attributes in $feature come from featureReduction.fields NOT layer.fields. So you'll need to account for that.

const clusterRenderer = new SimpleRenderer({
  symbol: {
    type: "simple-marker",
    size: 8,
    outline: {
      width: 0.5,
      color: "rgba(255,255,255,0.5)"
    }
  },
  visualVariables: [{
    type: "size",
    field: "cluster_count",
    minSize: 12,
    maxSize: 60,
    minDataValue: 1,
    maxDataValue: 1000
  }, {
    type: "color",
    valueExpression: `
      // $feature gives you access to feature attributes.
      var status = Decode($feature.status,
        "U", 10,
        "C", 5,
        0
      );  
      var alert = Number($feature.alert);
      var priority = Decode($feature.priority,
        "High", 10,
        "Medium", 5,
        "Low", 3,
        0
      );

      var score = (status + alert + priority) / 3;
      return score;
    `,
    stops: [
      { value: 0, color: "white" },
      { value: 3, color: "beige" },
      { value: 5, color: "yellow" },
      { value: 7, color: "orange" },
      { value: 10, color: "red" }
    ]
  }]
});

layer.featureReduction.renderer = clusterRenderer;

mposite score or level.

for example...

 

 

0 Kudos
DanielMoga
New Contributor II

thank you for your responses but I`m facing to a new question: How can I access individual properties? After I Console($feature) I have this: {"attributes":{"cluster_count":6},"geometry":{"x":267,"y":-14}}. What I`m missing in my configs to be able to have those features properties available in $feature context ? 

0 Kudos
KristianEkenes
Esri Regular Contributor

You need to define aggregate fields for them to come through in $feature. That's what I meant by featureReduction.fields. This sample demonstrates how to do that. https://developers.arcgis.com/javascript/latest/sample-code/featurereduction-cluster-aggregate-field... 

 

0 Kudos
DanielMoga
New Contributor II

You are right ! Thank you so much! 

0 Kudos