Create pop-ups in ArcGIS Online with conditional images using Arcade

10-09-2017 07:05 AM

Create pop-ups in ArcGIS Online with conditional images using Arcade


Arcade expressions can be used to define the symbology in a dynamic way for almost a year now. See ArcGIS Arcade | ArcGIS for Developers 

Relatively new is the use of Arcade expression in pop-ups in ArcGIS Online. While exploring the possibilities I obtained the following result:

Based in the percentage of coverage 5 symbols are displayed per service (water, sewer and gas). For each symbol (image) there is an expression that evaluates the coverage and defines which image to use.

Creating the Arcade expressions

For this example, we used a hosted feature service from our Open Data portal at Esri Colombia, with data per municipality:

  • Number of households with electricity
  • Number of households without electricity
  • Number of households connected to natural gas
  • Number of households not connected to natural gas
  • Number of households with aqueduct
  • Number of households without aqueduct
  • Number of households connected to the sewerage
  • Number of households not connected to the sewerage
  • Number of households with telephone
  • Number of households without telephone

To start, you should know the percentage of coverage of a service. This can be derived from the number of household with and without the service. For instance:
Energy coverage = households with electricity / (households with electricity + households without electricity) * 100%.

Since this coverage information is not provided in the data, we can calculate it on the fly using Arcade. This is done in the configuration of the pop-up window. Just use the ADD button to add a new expression:

The Arcade expression configuration Windows allows you to configure your expression and put in all the logic you want based on the attributes of the data. 

Arcade Expression:

var total_hh = $feature.P_ENERSI + $feature.P_ENERNO;
var coverage = 0;
if (total_hh > 0) {
    coverage = $feature.P_ENERSI * 100.0 / total_hh;
return coverage;

In the example above, “$feature.P_ENERSI” corresponds to the number of households that have electricity and “$feature.P_ENERNO” to those that don’t. The coverage is initially set to 0 to avoid errors when dividing by zero in case of incomplete data. The name of the virtual field has been called “Energy % Coverage” and will be available to show in the pop-up.

The expressions used for the symbols that indicate the coverage is a little bit more complex. Every symbol represents a chunk of 20% of the total of 100% coverage. Therefore, there are 5 symbols (0-20%, 20-40%, 40-60%, 60-80% and 80-100%). For each range of 20% and every service it is necessary to define which out of three possible symbols should be used.

This logic can be achieved like this:

The function “GetImageOnClass” take two parameters a value (the percentage of coverage 0 – 100) and an image number (1 to 5 corresponding to the range the symbol represents).

There are 3 different symbols stored in the variable “lst”. To complete the URL, there is a variable called “base_url”. The class_from and class_to variables hold the range to be evaluated based on the image number (see lines 4 and 5).

The actual validation starts on line 8:

  • If the percentage of coverage is higher than the upper class limit (minus 5%), than this range is visualized using a green symbol.
  • When the percentage of coverage is lower than the lower class limit (plus 5%), this range is visualized using the red symbol
  • For the rest of the cases the green to red symbol is used.

An example:
A coverage of 24%, will result in a red symbol for the range of 20 – 40%.
A coverage of 30% will use a green to red symbol for the same range and
A coverage of 36% will yield a green symbol for that range of 20 – 40%

0 - 20%20- 40%40 - 60%

Below the “GetImageOnClass” function the logic is implemented to determine the coverage and indicate the image number:

The percentage of coverage is calculated, just like we did in the first Arcade expression, but this time the value is provided to the “GetImageOnClass” function together with the value 1, which indicates the first range (from 0 – 20%). The result is a URL to the correct symbol which we can use in the pop-up.

Since we have 5 different types of services (energy, gas, aqueduct, sewerage and telephone) and 5 symbols per service, we need to create 5 * 5 = 25 Arcade expressions that are very similar. Within the same service energy, the only thing that changes, is the image number on line 29. For the other services, we need to change the attributes read on lines 18 and 19.

Below the Arcade expression:

function GetImageOnClass(value, image_number) {
     var lst = ['persona_verde40.png ', 'persona_verde_a_rojo40.png', 'persona_rojo40.png'];
     var base_url = '';
     var class_from = (image_number - 1) * 20
     var class_to = (image_number) * 20
     var url = '';
     if (value >= class_to - 5) {
          url = base_url + lst[0];
     } else if (value <= class_from + 5) {
          url = base_url + lst[2];
     } else {
          url = base_url + lst[1];
    return url;

var hh_no = $feature.P_ENERNO;
var hh_yes = $feature.P_ENERSI;
var total = hh_no + hh_yes;
var percentage = 0;
if (total > 0) {
    percentage = hh_yes * 100 / total;

Console('total:' + total);
Console('percentage:' + percentage);

return GetImageOnClass(percentage, 1);
Currently, it is not possible to use parameters for the Arcade expression itself. If that were possible the 25 expressions could be reduced to a single expression, that takes the household with and household without the service and the image number as parameter.

Configure the pop-up window

Now that we have the expressions, we can configure the pop-up window. We will use the option “A custom attribute display”.

Select that option and hit the CONFIGURE button. The Custom Attribute Display window will show. In this window we can press the “View HTML Source” button and paste our HTML code:

After pasting the HTML code (find HTML further down) the window will be as follows:

When we switch back the window will show the result of the configuration:

In this case we have the name of the municipality (county) and the department (state) and below that we have the average coverage for all the 5 services and the percentage of missing data.

The symbols with the coverage are implemented like this:

<img alt="" src="{expression/expr1}" />
<img alt="" src="{expression/expr2}" />
<img alt="" src="{expression/expr3}" />
<img alt="" src="{expression/expr4}" />
<img alt="" src="{expression/expr5}" />

Each symbol is image that uses the expression as the source (URL) to the image. For each service we designed some symbols:

The symbols have a size of 64 x 64 pixels, but were to big for the pop-up window (take make it fit on 1 line) and were reduced by specifying the width attribute of the image tag:

<img alt="" src="" width="40" />

Find below the complete HTML used:

<b><font face="Verdana" size="4">{MPIO_CNMBR}</font></b>
<br />
<b><font face="Verdana" size="2">(<i>{DEPTO}</i>)</font></b> 
<br />
<br />Average coverage: <b>{expression/expr6}%</b> 
<br />Without information: <b>{expression/expr31}%</b>
<br />

 <br /> <br /><img alt="" src="" width="40" />
<img alt="" src="{expression/expr1}" />
<img alt="" src="{expression/expr2}" />
<img alt="" src="{expression/expr3}" />
<img alt="" src="{expression/expr4}" />
<img alt="" src="{expression/expr5}" />

 <br /><img alt="" src="" width="40" />
<img alt="" src="{expression/expr8}" />
<img alt="" src="{expression/expr9}" />
<img alt="" src="{expression/expr10}" />
<img alt="" src="{expression/expr11}" />
<img alt="" src="{expression/expr12}" />
 <br /><img alt="" src="" width="40" />
<img alt="" src="{expression/expr14}" />
<img alt="" src="{expression/expr15}" />
<img alt="" src="{expression/expr16}" />
<img alt="" src="{expression/expr17}" />
<img alt="" src="{expression/expr18}" />

 <br /><img alt="" src="" width="40" />
<img alt="" src="{expression/expr20}" />
<img alt="" src="{expression/expr21}" />
<img alt="" src="{expression/expr22}" />
<img alt="" src="{expression/expr23}" />
<img alt="" src="{expression/expr24}" />

 <br /><img alt="" src="" width="40" />
<img alt="" src="{expression/expr26}" />
<img alt="" src="{expression/expr27}" />
<img alt="" src="{expression/expr28}" />
<img alt="" src="{expression/expr29}" />
<img alt="" src="{expression/expr30}" />

Creating a matching symbology using Arcade

To create some matching symbology we can use Arcade to visualize the average coverage for the 5 services. Change the symbology of the layer:

Scroll down the list of attributes until you find the last option “New Expression”:

The Arcade expression window will pop up. Here we can add all the attributes of the 5 services (households with service) and those that don’t receive the service and define the coverage:

Arcade expression:

var ener_yes = $feature.P_ENERSI;
var ener_no = $feature.P_ENERNO;
var gas_yes = $feature.P_GASNSI;
var gas_no = $feature.P_GASNNO;
var acue_yes = $feature.P_ACUESI;
var acue_no = $feature.P_ACUENO;
var alca_yes = $feature.P_ALCANSI;
var alca_no = $feature.P_ALCANNO;
var telco_yes = $feature.P_TELEFSI;
var telco_no = $feature.P_TELEFNO;

var spx_yes = ener_yes + gas_yes + acue_yes + alca_yes + telco_yes;
var spx_no = ener_no + gas_no + acue_no + alca_no + telco_no;
var spx_total = spx_yes + spx_no;

var coverage = 0;
if (spx_total > 0) {
    coverage = (spx_yes * 100.0) / spx_total;
return coverage;

When you hit the OK button, the expression is interpreted and the data will display using the Counts and Amounts (size option). Select the “Counts and Amounts (Color)” option and hit OPTIONS:

Select the “Above and Below” Theme:

Select an appropriate color scheme:

Edit the values:

And this is the result:

The resulting application consuming this web map (Spanish version) can be found here:



I know you put this together awhile back, but it is really helpful and valuable and I think not enough people know about the potential with Arcade expressions. Thanks again for putting this together! Electric and Gas

Version history
Last update:
‎12-12-2021 03:44 AM
Updated by: