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.
For this example, we used a hosted feature service from our Open Data portal at Esri Colombia, with data per municipality:
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:
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% | |
---|---|---|---|
24% | |||
30% | |||
36% |
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 = 'http://geoportal.esri.co/SP/imagenes/sym/';
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.
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="http://geoportal.esri.co/SP/imagenes/sym/electricidad.png" 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="http://geoportal.esri.co/SP/imagenes/sym/electricidad.png" 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}" />
({expression/expr0}%)
<br /><img alt="" src="http://geoportal.esri.co/SP/imagenes/sym/gas.png" 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}" />
({expression/expr7}%)
<br /><img alt="" src="http://geoportal.esri.co/SP/imagenes/sym/acueducto.png" 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}" />
({expression/expr13}%)
<br /><img alt="" src="http://geoportal.esri.co/SP/imagenes/sym/alcantarillado.png" 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}" />
({expression/expr19}%)
<br /><img alt="" src="http://geoportal.esri.co/SP/imagenes/sym/telefono.png" 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}" />
({expression/expr25}%)
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
Hi Brian Baldwin ,
Your welcome, it's been fun working with Arcade. I have published a couple of other documents with Arcade examples, but most of them created in Spanish for our community in GeoNet. Might be interesting to have a look:
If you want to know more about any of those, just let me know.