Performing Calculations in Arcade
Overview:
You will learn how to perform calculations in Arcade, handle text, comments, various coding style options, and use variables.
This article assumes you are familiar with creating Arcade popups. If you are not, complete the article linked in Setup.
Setup:
This is an extension to the article Creating Popups using Arcade. If you saved your map from that article, use it here. If not, then:
- Open a web browser and go to https://www.arcgis.com/
- If prompted to do so, Sign In
- Select Layers
- Click the dropdown on the Add layers button and choose Add Layer from URL, and paste in this URL: 2020 US Census Race and Ethnicity
- Expand the 2020 Census Layer
- Select Block Group from the 2020 census Layer
- Click Pop-ups
- Click Attribute expressions
- Click + Add expression - for more detailed instructions, see the prior article linked in Setup (above)
- Name the expression: Calc Validation.
Now we will create an expression to better grasp the census data and check it's validity, paste in the following code:
// You can comment your code by using double slashes var output = "" // Creating variables details: https://developers.arcgis.com/arcade/guide/variables/ /* * You can also use multiline comments * more details here: https://developers.arcgis.com/arcade/guide/comments/ * The field names aren't very descriptive, the lookup for them with their descriptive alias is here: * https://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/USA_Census_2020_DHC_Race_and_Ethnicity/FeatureServer/4 */ var naAll = $feature.P009_calc_numAIANac // += means append or add to, to show numbers as text you must wrap them with Text() output += "American Indian and Alaska Native alone or in combination with other races and ethnicities: " + Text(naAll) + "\n" //\n is a carriage return var naAloneHispanicLatino = $feature.P0050013 output += "American Indian and Alaska Native alone, Hispanic or Latino: " + Text(naAloneHispanicLatino) + "\n" var naAloneNotHispanic = $feature.P0090007 output += "American Indian and Alaska Native alone, not Hispanic or Latino: " + Text(naAloneNotHispanic) + "\n" var pop2WhiteAIAN = $feature.P0090014 output += "White, American Indian and Alaska Native: " + Text(pop2WhiteAIAN) + "\n" var pop2BlackAIAN = $feature.P0090018 output += "Black or African American, American Indian and Alaska Native: " + Text(pop2BlackAIAN) + "\n" var pop2AIANAsian = $feature.P0090022 output += "American Indian and Alaska Native, Asian: " + Text(pop2AIANAsian) + "\n" var pop2AIANNHPI = $feature.P0090023 output += "American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander: " + Text(pop2AIANNHPI) + "\n" var pop2AIANOther = $feature.P0090024 output += "American Indian and Alaska Native, Some Other Race: " + Text(pop2AIANOther) + "\n" var pop3WhiteBlackAIAN = $feature.P0090029 output += "White, Black or African American, American Indian and Alaska Native: " + Text(pop3WhiteBlackAIAN) + "\n" var pop3WhiteAIANAsian = $feature.P0090033 output += "White, American Indian and Alaska Native, Asian: " + Text(pop3WhiteAIANAsian) + "\n" var pop3WhiteAIANNHPI = $feature.P0090034 output += "White, American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander: " + Text(pop3WhiteAIANNHPI) + "\n" var pop3WhiteAIANOther = $feature.P0090035 output += "White, American Indian and Alaska Native, Some Other Race: " + Text(pop3WhiteAIANOther) + "\n" var pop3BlackAIANAsian = $feature.P0090039 output += "Black or African American, American Indian and Alaska Native, Asian: " + Text(pop3BlackAIANAsian) + "\n" var pop3BlackAIANNHPI = $feature.P0090040 output += "Black or African American, American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander: " + Text(pop3BlackAIANNHPI) + "\n" var pop3BlackAIANOther = $feature.P0090041 output += "Black or African American, American Indian and Alaska Native, Some Other Race: " + Text(pop3BlackAIANOther) + "\n" var pop3AIANAsianNHPI = $feature.P0090045 output += "American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander: " + Text(pop3AIANAsianNHPI) + "\n" var pop3AIANAsianOther = $feature.P0090046 output += "American Indian and Alaska Native, Asian, Some Other Race: " + Text(pop3AIANAsianOther) + "\n" var pop3AIANNHPIOther = $feature.P0090047 output += "American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop3AIANNHPIOther) + "\n" var pop4WhiteBlackAIANAsian = $feature.P0090050 output += "White, Black or African American, American Indian and Alaska Native, Asian: " + Text(pop4WhiteBlackAIANAsian) + "\n" var pop4WhiteBlackAIANNHPI = $feature.P0090051 output += "White, Black or African American, American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander: " + Text(pop4WhiteBlackAIANNHPI) + "\n" var pop4WhiteBlackAIANOther = $feature.P0090052 output += "White, Black or African American, American Indian and Alaska Native, Some Other Race: " + Text(pop4WhiteBlackAIANOther) + "\n" var pop4WhiteAIANAsianNHPI = $feature.P0090056 output += "White, American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander: " + Text(pop4WhiteAIANAsianNHPI) + "\n" var pop4WhiteAIANAsianOther = $feature.P0090057 output += "White, American Indian and Alaska Native, Asian, Some Other Race: " + Text(pop4WhiteAIANAsianOther) + "\n" var pop4WhiteAIANNHPIOther = $feature.P0090058 output += "White, American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop4WhiteAIANNHPIOther) + "\n" var pop4BlackAIANAsianNHPI = $feature.P0090060 output += "Black or African American, American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander: " + Text(pop4BlackAIANAsianNHPI) + "\n" var pop4BlackAIANAsianOther = $feature.P0090061 output += "Black or African American, American Indian and Alaska Native, Asian, Some Other Race: " + Text(pop4BlackAIANAsianOther) + "\n" var pop4BlackAIANNHPIOther = $feature.P0090062 output += "Black or African American, American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop4BlackAIANNHPIOther) + "\n" var pop4BlackAsianNHPIOther = $feature.P0090063 output += "Black or African American, Asian, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop4BlackAsianNHPIOther) + "\n" var pop4AIANAsianNHPIOther = $feature.P0090064 output += "American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop4AIANAsianNHPIOther) + "\n" var pop5WhiteBlackAIANAsianNHPI = $feature.P0090066 output += "White, Black or African American, American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander: " + Text(pop5WhiteBlackAIANAsianNHPI) + "\n" var pop5WhiteBlackAIANAsianOther = $feature.P0090067 output += "White, Black or African American, American Indian and Alaska Native, Asian, Some Other Race: " + Text(pop5WhiteBlackAIANAsianOther) + "\n" var pop5WhiteBlackAIANNHPIOther = $feature.P0090068 output += "White, Black or African American, American Indian and Alaska Native, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop5WhiteBlackAIANNHPIOther) + "\n" var pop5WhiteAIANAsianNHPIOther = $feature.P0090070 output += "White, American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop5WhiteAIANAsianNHPIOther) + "\n" var pop5BlackAIANAsianNHPIOther = $feature.P0090071 output += "Black or African American, American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop5BlackAIANAsianNHPIOther) + "\n" var pop6WhiteBlackAIANAsianNHPIOther = $feature.P0090072 output += "White, Black or African American, American Indian and Alaska Native, Asian, Native Hawaiian and Other Pacific Islander, Some Other Race: " + Text(pop6WhiteBlackAIANAsianNHPIOther) + "\n\n" var pctAIANAloneNotHispanic = $feature.P009_calc_pctAIANa output += "Percent American Indian and Alaska Native alone, not Hispanic: " + Text(pctAIANAloneNotHispanic) + "\n" var pctAIANAloneOrCombo = $feature.P009_calc_pctAIANac output += "Percent American Indian and Alaska Native alone or in combination with other races and ethnicities: " + Text(pctAIANAloneOrCombo) + "\n\n" // naTotal = sum of all variables except naAll, pctAIANAloneNotHispanic, pctAIANAloneOrCombo var naTotal = DefaultValue(naAloneHispanicLatino, 0) + DefaultValue(naAloneNotHispanic, 0) + DefaultValue(pop2WhiteAIAN, 0) + DefaultValue(pop2BlackAIAN, 0) + DefaultValue(pop2AIANAsian, 0) + DefaultValue(pop2AIANNHPI, 0) + DefaultValue(pop2AIANOther, 0) + DefaultValue(pop3WhiteBlackAIAN, 0) + DefaultValue(pop3WhiteAIANAsian, 0) + DefaultValue(pop3WhiteAIANNHPI, 0) + DefaultValue(pop3WhiteAIANOther, 0) + DefaultValue(pop3BlackAIANAsian, 0) + DefaultValue(pop3BlackAIANNHPI, 0) + DefaultValue(pop3BlackAIANOther, 0) + DefaultValue(pop3AIANAsianNHPI, 0) + DefaultValue(pop3AIANAsianOther, 0) + DefaultValue(pop3AIANNHPIOther, 0) + DefaultValue(pop4WhiteBlackAIANAsian, 0) + DefaultValue(pop4WhiteBlackAIANNHPI, 0) + DefaultValue(pop4WhiteBlackAIANOther, 0) + DefaultValue(pop4WhiteAIANAsianNHPI, 0) + DefaultValue(pop4WhiteAIANAsianOther, 0) + DefaultValue(pop4WhiteAIANNHPIOther, 0) + DefaultValue(pop4BlackAIANAsianNHPI, 0) + DefaultValue(pop4BlackAIANAsianOther, 0) + DefaultValue(pop4BlackAIANNHPIOther, 0) + DefaultValue(pop4BlackAsianNHPIOther, 0) + DefaultValue(pop4AIANAsianNHPIOther, 0) + DefaultValue(pop5WhiteBlackAIANAsianNHPI, 0) + DefaultValue(pop5WhiteBlackAIANAsianOther, 0) + DefaultValue(pop5WhiteBlackAIANNHPIOther, 0) + DefaultValue(pop5WhiteAIANAsianNHPIOther, 0) + DefaultValue(pop5BlackAIANAsianNHPIOther, 0) + DefaultValue(pop6WhiteBlackAIANAsianNHPIOther, 0); // Check if naAll equals naTotal, and show the math if not, more info: https://developers.arcgis.com/arcade/guide/operators/ if (naAll == naTotal) { output += "Validation Check: naAll (" + Text(naAll) + ") DOES equal naTotal\n" } else { output += "Validation Check: naAll does NOT equal naTotal: " + Text(naAll) + " != " + Text(naTotal) + "\n" output += "Math: " + Text(naAll) + " != " var mathParts = [ "naAloneHispanicLatino(" + Text(naAloneHispanicLatino) + ")", "naAloneNotHispanic(" + Text(naAloneNotHispanic) + ")", "pop2WhiteAIAN(" + Text(pop2WhiteAIAN) + ")", "pop2BlackAIAN(" + Text(pop2BlackAIAN) + ")", "pop2AIANAsian(" + Text(pop2AIANAsian) + ")", "pop2AIANNHPI(" + Text(pop2AIANNHPI) + ")", "pop2AIANOther(" + Text(pop2AIANOther) + ")", "pop3WhiteBlackAIAN(" + Text(pop3WhiteBlackAIAN) + ")", "pop3WhiteAIANAsian(" + Text(pop3WhiteAIANAsian) + ")", "pop3WhiteAIANNHPI(" + Text(pop3WhiteAIANNHPI) + ")", "pop3WhiteAIANOther(" + Text(pop3WhiteAIANOther) + ")", "pop3BlackAIANAsian(" + Text(pop3BlackAIANAsian) + ")", "pop3BlackAIANNHPI(" + Text(pop3BlackAIANNHPI) + ")", "pop3BlackAIANOther(" + Text(pop3BlackAIANOther) + ")", "pop3AIANAsianNHPI(" + Text(pop3AIANAsianNHPI) + ")", "pop3AIANAsianOther(" + Text(pop3AIANAsianOther) + ")", "pop3AIANNHPIOther(" + Text(pop3AIANNHPIOther) + ")", "pop4WhiteBlackAIANAsian(" + Text(pop4WhiteBlackAIANAsian) + ")", "pop4WhiteBlackAIANNHPI(" + Text(pop4WhiteBlackAIANNHPI) + ")", "pop4WhiteBlackAIANOther(" + Text(pop4WhiteBlackAIANOther) + ")", "pop4WhiteAIANAsianNHPI(" + Text(pop4WhiteAIANAsianNHPI) + ")", "pop4WhiteAIANAsianOther(" + Text(pop4WhiteAIANAsianOther) + ")", "pop4WhiteAIANNHPIOther(" + Text(pop4WhiteAIANNHPIOther) + ")", "pop4BlackAIANAsianNHPI(" + Text(pop4BlackAIANAsianNHPI) + ")", "pop4BlackAIANAsianOther(" + Text(pop4BlackAIANAsianOther) + ")", "pop4BlackAIANNHPIOther(" + Text(pop4BlackAIANNHPIOther) + ")", "pop4BlackAsianNHPIOther(" + Text(pop4BlackAsianNHPIOther) + ")", "pop4AIANAsianNHPIOther(" + Text(pop4AIANAsianNHPIOther) + ")", "pop5WhiteBlackAIANAsianNHPI(" + Text(pop5WhiteBlackAIANAsianNHPI) + ")", "pop5WhiteBlackAIANAsianOther(" + Text(pop5WhiteBlackAIANAsianOther) + ")", "pop5WhiteBlackAIANNHPIOther(" + Text(pop5WhiteBlackAIANNHPIOther) + ")", "pop5WhiteAIANAsianNHPIOther(" + Text(pop5WhiteAIANAsianNHPIOther) + ")", "pop5BlackAIANAsianNHPIOther(" + Text(pop5BlackAIANAsianNHPIOther) + ")", "pop6WhiteBlackAIANAsianNHPIOther(" + Text(pop6WhiteBlackAIANAsianNHPIOther) + ")" ] output += Concatenate(mathParts, " + ") + "\n" } return output // You can test/view your output by clicking the Run button, above line 1 // When everything looks good, click Done button at the bottom right of the form to save.
Be sure to click the Done button to save your expression. You can then click on the expression to view/edit it further.
If you don't know how to make your expression show in the popup as an attribute, review the previous article, linked above in Setup.
A cleaner way to show this expression is to show it as text/html versus an attribute. To do this you will want to start by deleting the field list, click the ... and choose Delete:
To make things easier, start by copying the code from the earlier added expression. Then click + Add content and select Arcade:
Paste in the code from your earlier added expression. Unfortunately, it seems currently, you will need to make some edits to the pasted code. Start by selecting/highlighting \n, with that selected press Ctrl+h to brings up the replace dialog in the replace textbox enter: <br>
Then click the replace all button as shown in above image. Another handy shortcut is Ctrl+f which brings up the find dialog auto populating the find box with selected text. To close the Replace or Find dialog box you can put the cursor in a textbox and press the ESC key.
Next we will need to replace the return line, delete the text:
return output // You can test/view your output by clicking the Run button, above line 1
in it's place put this code:
return { type : 'text', text : output }
You can click the Run button to verify the code is working, then click Done to save it.
Now you can test your new Arcade Popup it should show when you click on a feature versus the Field List from earlier (and the previous article).
Additional Notes (pun intended):
You can use ++ to increment a number variable and — to decrement it:
var x = 0; ++x // x is now 1 and the value 1 is returned var x = 0; x++ // x is now 1 but the value of 0 is returned, until the next line then 1 is returned
Arithmetic Operators Precedence:
When you write an expression with different operators (+
, -
, *
, /
), some operators are handled before others because they have higher "precedence." Operators with higher precedence are calculated first. If two operators have the same precedence, they are done in the order they appear, from left to right. You can use parentheses ()
to change this order—anything inside parentheses is calculated first, you can nest parentheses in which case the innermost is done first.
ESRI Arcade Operator Precedence:
- Multiplication/division (
*
,/
,%
) happen before addition/subtraction (+
,-
). - Parentheses
()
take the highest precedence and are evaluated first. - If two operators have the same precedence, Arcade evaluates them left to right.
Feel free to verify with the following code blocks, to test/run them in ESRI Arcade Editor be sure at the bottom to add the line:
return result
You can test your Arcade code here: https://developers.arcgis.com/arcade/playground/
var result = 2 + 3 * 4 // Multiplication happens first: 3 * 4 = 12 // Then addition: 2 + 12 = 14 // result = 14
var result = (2 + 3) * 4 // Parentheses first: 2 + 3 = 5 // Then multiplication: 5 * 4 = 20 // result = 20
var result = 10 - 4 + 2 // Both - and + have the same precedence, so evaluate left to right: // 10 - 4 = 6 // 6 + 2 = 8 // result = 8
var result = 2 * (3 + (4 - 1)) // Innermost parentheses: 4 - 1 = 3 // Next: 3 + 3 = 6 // Then: 2 * 6 = 12 // result = 12
Similar to increment/decrement operators there are Assignment operators:
Operator | Name | Description |
---|---|---|
+= | Add assign | Adds a number to the value of a number variable and assigns the result to the variable. |
-= | Minus assign | Subtracts a number from a value of a number variable and assigns the result to the variable. |
*= | Multiply assign | Multiplies a number by the value of a number variable and assigns the result to the variable. |
/= | Divide assign | Divides the value of a number variable by another number and assigns the result to the variable. |
// Add assign var result = 1; // optionally in Arcade you may mark the end of a line with ; result+=2; // result = 3
Number Comparisons:
Operator | Name | Description |
---|---|---|
x==y | Equal to | Evaluates to true if the x-value is equal to the y-value. |
!= | Not equal to | Evaluates to true if the x-value is not equal to the y-value. |
> | Greater than | Evaluates to true if the x-value is greater than the y-value. |
>= | Greater than or equal | Evaluates to true if the x-value is greater than or equal to the y-value. |
< | Less than | Evaluates to true if the x-value is less than the y-value. |
<= | Less than equal to | Evaluates to true if the x-value is less than or equal to the y-value. |
Logical operators:
||
returnstrue
if either side is true.&&
returnstrue
only if both sides are true.!
inverts a boolean value.
// Example 1: Logical OR (||) var a = 5 var b = 10 var result_or = (a > 3) || (b < 5) // true || false = true // Example 2: Logical AND (&&) var c = 7 var d = 8 var result_and = (c > 6) && (d == 8) // true && true = true // Example 3: Logical NOT (!) var e = 12 var result_not = !(e < 10) // !(false) = true return "result_or = " + Text(result_or) + "\n" + "result_and = " + Text(result_and) + "\n" + "result_not = " + Text(result_not)
Arcade continues to improve, since release 1.11 you can now use Template literals, which makes dealing with variables in text much easier, take the return line in the code above, you can replace it with this:
return `result_or = ${result_or}\nresult_and = ${result_and}\nresult_not = ${result_not}`
That tick ` is not ', the tick you want to use for Template literals is at the top left of most keyboards with the tilde key.
Math Functions:
There are too many functions like Abs, Min, and Round to go over in this article, you can peruse this list for reference: https://developers.arcgis.com/arcade/function-reference/math_functions/