ProGuide Custom Dictionary Style - kataya/arcgis-pro-sdk GitHub Wiki

This guide is a reference for how to make your own custom dictionary style (which will work in both ArcGIS Pro and Runtime).

Language:      C#
Subject:       Framework
Contributor:   ArcGIS Pro SDK Team <[email protected]>
Organization:  Esri, http://www.esri.com
Date:          1/20/2020
ArcGIS Pro:    2.7
Visual Studio: 2017, 2019

In this topic

Overview

We are going to make a custom dictionary style that places three different symbols - a "letter" A, B, and C in one of three different placement positions: Left, Center, Right as shown below.

style_example.png

The style will work off three underlying feature attributes: one for the left letter choice, one for the middle letter choice and one for the right letter choice. Each letter choice must correspond to a distinct symbol in our dictionary style. There will be 9 symbols in our style to satisfy all possible 3x3x3=27 rendering options.

For example, to render a feature with AAA, will require: one A symbol offset to the left, another, distinct, A symbol for the middle, and a third, distinct, A symbol offset to the right and so on for other "letter" combinations.

There are three main sections in this guide:

  1. First, a step-by-step procedure for making a style using symbols offset to the left, right, or no offset (middle) via their built-in Offset X property.
  2. Second, the procedure for making a style that uses primitive overrides to accomplish the same thing.
  3. Third (optional), we add a further override to change the symbol background color (in addition to the offset X).

Completed styles

These are links to the completed styles (for download) that are made in this guide:

Prerequisites

Downloads

  • Download and install the DB Browser for SQLite. This is required.
  • Upgrade ArcGIS Pro to version 2.5 or better (only if you want to use primitive overrides)
  • Download a copy of the Runtime custom dictionary style sample: Restaurants.stylx

Resources

You may find the following resources helpful. Creating a dictionary style utilizes many different components of the ArcGIS Platform:

Data Prep

We need to make a dataset that can use our custom dictionary style. We will modify the same sample dataset that the Runtime custom dictionary style sample used: the Redlands restaurants feature service:

To make a local copy of the data from the Redlands restaurants feature service:

DataFromPath.png

  • Run Geoprocessing Copy Features and copy the features from the feature service to a local file gdb feature class called Redlands_Letters or another name of your choosing.

CopyFeatures.png

We need to modify the schema. Our dictionary style is going to be based on a combination of three numeric attributes: LETTER1, LETTER2, and LETTER3. Each attribute will be defined as data type LONG.

  • Add Redlands_Letters to the current map in Pro (if the GP Copy Features tool did not automatically do this).

  • Click the Data tab (on the Pro ribbon)

  • Click the Fields button

  • Add three fields to the feature class:

    • LETTER1, Long
    • LETTER2, Long
    • LETTER3, Long
  • Save the changes

  • Go back to the Map.

  • Open the attribute table for the Redlands_Letters layer.

  • Randomly select different "groups" of the features in Redlands_Letters and calculate the values of LETTER1, LETTER2, and LETTER3 to different combinations of the values 1,2, and 3. The more random, the better. (Use "Calculate Field" on each of the three attributes).

CalcFields.png

Part 1 - Procedure

We will now create our custom style.

Step 1

(In your Windows folder) make a copy of the Restaurants.stylx downloaded from the Runtime sample (see Downloads). Rename the copy Letters_with_offset.stylx.

Step 2

  • Start Pro.
  • Open whichever project contains your Map with the Redlands_Letters dataset (see Data Prep).
  • Add the Letters_with_offset.stylx style file to the Styles folder in Pro.

AddStyle.png

  • Right click on Letters_with_offset
  • Select "Manage". The Catalog pane will open. The Letters_with_offset style will be loaded showing all of its existing symbols (which are part of the original Runtime Restaurants style)

Manage.png

  • Select all of the symbols except the very last symbol (which is actually a label) called "Name label".
  • Delete all of the selected symbols (there is a "Delete" button on the Catalog tab or on the context menu).

Your style will now be empty except for the Name label label symbol

Step 3

We need to add in our new symbols. This will require use of the Pro symbol editor. We will be adding 9 symbols: 3 A's, 3 B's, and 3 C's. It is important to get the names and the keys of the symbols correct.

  • Add a new point symbol to the style (New->Point Symbol)

NewSymbol.png

Next, we will edit its properties (the symbol Details Pane must be visible. If the Details pane is not then open it via the "Show Details Pane" button).

ShowDetails.png

Step 4

  • For Description, set the following metadata properties:
 Name: A1
 Category: LetterSymbol
 Tags: rgb;black;A;letter
 Key: A1

Description.png

  • Apply the changes.

Step 5

Switch to Properties. We will be designing our point symbol.

  • Click "Layers" ("Layers icon" on the top of the symbol properties tab).
  • Change the size to 14pt.
  • Click "Structure" (the "wrench icon" next to "Layers").
  • We are going to make a 2 layer symbol per letter. Add an additional marker layer (the symbol will now have two layers).

MarkerLayer.png

TwoLayers.png

  • Switch back to symbol "Layers". Also notice that we (now) have two symbol layers.

TwoSymbolLayers.png

  • Select the "top" layer. This will become our letter.
  • Click "Font...". Choose "Bookman Old Style" on the popup. Choose the letter "A". Click OK.

ChooseALetter.png

  • Change the Point size to 14pt.
  • Click Apply (on the bottom of the Properties tab).
  • Select the second (ie "bottom" layer). Click "Style...". From the Popup, choose "Circle 3". Click OK.

ChooseAShape2.png

  • Change the Point size to 18pt.
  • Change the Color (on the dropdown) to (Arctic) White. Click Apply.

ChangeColor.png

Your current symbol should now look like this:

PreviewA.png

Click "Apply".

Step 6.

Recall we need a total of 9 symbols. An A, B, and C for each of the three positions: Offset left, middle, and offset right. The simplest way to make the other 8 symbols is to copy the "A" we just made 8 times.

  • Right-click on the symbol, select "Copy". Click off the symbol (so it is not selected), right-click, select "Paste".

CopySymbol.png

  • On paste, you will get the following warning message. Ignore it and click OK.

StyleItemKey.png

  • You will get a "Symbol Downgrade" message. Ignore it and click OK.

SymbolDowngrade.png

  • Repeat "Paste" until you have a total of 9 "A" symbols.

Step 7.

We need to fix the metadata Descriptions of each of the 8 copies we made of our A symbol. The first three "letters" in the style will be the A's. The middle three "letters" will be the B's and the bottom three letters will be changed to C's. Use the following table to set the metadata correctly:

Descriptions

Name<\th> Category Tags Key
A1 LetterSymbol rgb;black;A;letter A1
A2 LetterSymbol rgb;black;A;letter A2
A3 LetterSymbol rgb;black;A;letter A3
B1 LetterSymbol rgb;black;B;letter B1
B2 LetterSymbol rgb;black;B;letter B2
B3 LetterSymbol rgb;black;B;letter B3
C1 LetterSymbol rgb;black;C;letter C1
C2 LetterSymbol rgb;black;C;letter C2
C3 LetterSymbol rgb;black;C;letter C3

When you have changed the symbol description metadata, the style should look like this:

ChangedDescriptions.png

All the symbols are still "A"s but now their Name label should correctly reflect the letter they will be representing.

Step 8

The three symbols designated as "B's" must now be changed to use the character "B" and likewise for the "C's".

  • Select each symbol in turn and return to the "Properties" tab. Select the top layer (which uses the font). Change the font character to "B" or "C" respectively. "Apply" the changes.

ChangeToB.png

The completed style should now look like this:

ChangedSymbols.png

Step 9

We have two different techniques available to us for implementing the offsets (recall, our completed renderer will depict features using a combination of 3 letter symbols). We can:

  • Build the offset X directly into each symbol.
  • Leave the offsets all at 0 in the symbol, and instead, use a primitive override.

In the first part of this Guide we are setting the offsets explicitly on each symbol. In the next section (Primitive Overrides) we will be using overrides. If you do intend to experiment with overrides, it is best to make a copy of your letter symbol style now - before we add in the explicit x offset values (because we want "0" offsets for the style symbols when we use overrides).

Therefore, if you do want to make a copy of your ".stylx" to use later on with the overrides:

  • Exit Pro. Save changes if prompted to do so.
  • Make a copy of the "Letters_with_offset.stylx" file and rename it "Letters_with_po.stylx" then go back to Pro.

Step 10

We are now going to add "Offset X" values to the symbols.

  • Select "A1". Go to properties.
  • Select "Layers".
  • Select each symbol layer in turn (there are two).
  • Expand "Offset Distance". Set the Offset X to -14pt (i.e. negative or "-" 14pt) (remember to repeat this for the other layer)
  • Click Apply.

ChangeOffsetX.png

  • Select the "A3" symbol
  • Set the Offset X to 14pt for both layers (i.e. positive or "+" 14pt).
  • Click Apply.

Repeat this procedure for the B1 and B3, and C1 and C3 symbols respectively. Use the following table as a guide for the relevant Offsets:

Symbol Name<\th> OffsetX
A1 -14pt
A2 0
A3 14pt
B1 -14pt
B2 0
B3 14pt
C1 -14pt
C2 0
C3 14pt

The remainder of our edits will now be done directly in SQLite. Exit Pro. Save any changes if prompted to do so.

Step 11

Run DB Browser (if you have not downloaded and installed the DB Browser for SQLite please do so now).

Open the Letters_with_offset.stylx style file. Use the "Open Database" button on the browser. Be sure to change the file filter to All Files (*). (The default filter is SQLite database files which will not show the .stylx files.)

  • Select the "meta" table

select_meta.png

Refer to the dictionary tool kit, Understanding the dictionary topic for a detailed description of the meta table fields we will be editing.

Step 12

  • Select the dictionary_name field value.
  • Change the value from RESTAURANT-INFO (or whatever it is) to "LETTERS-OFFSET".
  • Click "Apply".

Note: the "Write Changes" button will enable on the Browser toolbar. Click "Write Changes" to save the changes back out to disk in the .stylx file.

Step 13

  • Select the dictionary_configuration value.

We will be changing the json. In the json, the "symbol": field value defines the individual fields that will be used in the dictionary. These fields are mapped to corresponding attributes in the feature layer (by the renderer).

  • Change the "symbol": field json to: "symbol": ["letter1", "letter2", "letter3"], (the trailing comma is not a typo).

The complete dictionary_configuration json value looks as follows:

{
  "configuration": [{
      "name": "text",
      "value": "ON",
      "domain": ["ON", "OFF"],
      "info": "indicates if the text is rendered"
    }
  ],
  "symbol": ["letter1", "letter2", "letter3"],
  "text": ["name"]
}
  • Click "Apply"

Step 14

  • Select the dictionary_script value.

The dictionary_script field contains the Arcade script the renderer executes to identify the symbols from the style that will be used to render each feature. The dictionary renderer passes in to the script the corresponding feature values (that are mapped to each of the "symbol": fields by the renderer). In our case, there are three attributes per feature: a "letter1","letter2", and "letter3" value.

The field values from the feature can be accessed in our script by prefixing the symbol field names with a "$" (dollar sign). Based on the values in the fields, the Arcade script constructs a "key" string that references each symbol to be used for the given feature. Each symbol key must be separated with a semi-colon ";". Our left symbol will be one of A1, B1, or C1. The middle symbol will be one of A2, B2, or C2, and the right will be either A3, B3, or C3. Notice that these key values correspond to the key values stored in our style to identify each symbol.

In this snippet, the Arcade script is looking at the feature's $letter2 value to determine which symbol to use for the "middle" position. decode and isempty are standard Arcade functions. Consult the Arcade Function Reference.

var keys = '';
var key1 = '';
var key2 = '';
var key3 = '';

...

//select the symbol for the middle letter
if (!isempty($letter2)) {
    key2 = decode($letter2, '1','A2','2','B2','3','C2','');
    if (!isempty(keys)) {
         keys = keys + ";" + key2;
    }
    else {
         keys = key2;
    }
}

In practice, while developing your Arcade script, the Arcade Playground will prove very useful for debugging your Arcade code.

Here is the completed Arcade script for the custom style:

// conventions:
// $xyz: attribute (received as string)
// _xyz: local variable

// calculating the semi-colon delimited keys
var keys = '';
var key1 = '';
var key2 = '';
var key3 = '';

//Translate the letter values into a symbol key
if (!isempty($letter1)) {
    key1 = decode($letter1, '1','A1','2','B1','3','C1','');
    keys = key1;
}
if (!isempty($letter2)) {
    key2 = decode($letter2, '1','A2','2','B2','3','C2','');
    if (!isempty(keys)) {
         keys = keys + ";" + key2;
    }
    else {
         keys = key2;
    }
}
if (!isempty($letter3)) {
    key3 = decode($letter3, '1','A3','2','B3','3','C3','');
    if (!isempty(keys)) {
        keys = keys + ";" + key3;
    }
    else {
        keys = key3;
    }
}

// See if text should be displayed.
var showLabels = $text != 'OFF';

// Create the concatenated string of keys (separated with ";"). Add the label key if text is on.
if (showLabels) {
  keys = keys + ";label-name";
}
  
// Return string of keys.
return keys;
  • Copy and paste this entire script into the dictionary_script value.
  • Click Apply.
  • Click "Write Changes" (on the DB Browser toolbar).

Step 15

  • Open ArcGIS Pro.
  • Create or open a project with a 2D map.
  • Add your Redlands_Letters dataset (created in Data Prep) to the TOC.

redlands_letters.png

Step 16

We are going to set the renderer of our layer to use our custom dictionary style.

  • Select the Redlands_Letters layer in the TOC
  • Open the symbology dockpane.
  • Change the Primary Symbology to be "Dictionary".

dictionary.png

By default the MIL-STD-2525D symbol set will probably be selected. We need to change that to our custom style "LETTERS-OFFSET" but first we will have to add our style to the list of styles in the Dictionary combo.

  • Select "More"->"Add custom dictionary..."

add_dictionary.png

  • Browse to the location of the "Letters_with_offset" style.
  • Click OK

The style will be added into the COMBO and should, by default, become selected. Otherwise just select "LETTERS-OFFSET" in the combo.

letters_offset.png

The letter1, letter2, and letter3 attributes in the feature dataset should automatically get mapped to the letter1,2, and 3 attributes defined in the custom style. If not, select them in the layer field combos.

Step 17

The custom style should be rendering now. If symbols are not rendering correctly you will need to debug your style.

The most common issue is code or logic errors in the Arcade script. There can also be "errors" in the key values assigned to each symbol (eg typos). If symbol key values stored in the custom style do not match the key values being returned from the Arcade script then the features will not draw correctly.

Debugging the Arcade script is very much a "trial and error" process. Go back and forth between the Arcade playground, your custom style in the DB Browser (to update the dictionary_script value with changes) and Pro to refresh the display. Pro caches display rendering so if your changes don't show up on the layer you may need to close and re-open Pro.

style_rendered.png

Part 2 - Primitive Overrides

In this part of the guide we will be using something called primitive overrides to set the symbol Offset X values rather than setting them explicitly on the individual symbol layer properties (as we did in the previous steps above) in the style.

Assuming that you have your Letters_with_po.stylx custom style created (see step 1 through step 9 above) we will be using it to make a custom style that uses overrides.

Step 1

Make sure Letters_with_po.stylx is added to Catalog. Open the style using "Manage" (see previous Step 2). We will be adding "primitive names" to each of the symbols. Primitive names are arbitrary strings that are referenced in the Arcade script to "set" primitive overrides (note: you must have ArcGIS Pro 2.5 or better to edit primitive names on a symbol).

We will be adding a primitive_name for the left offset to A1, B1, and C1; a primitive name for the middle offset (for consistency - we don't actually use it) to A2, B2, and C2; and a primitive name for the right offset (to A3, B3, and C3).

  • Select A1.
  • Select the "Properties" view.
  • Switch to the "Structure" tab.
  • Click on the "show primitive name" icon (this is only available in Pro 2.5 or later) for the letter layer.

structure_tab.png

  • Enter "offset_left" in the popup.

primitive_name.png

  • Repeat for the "circle" layer.
  • Click Apply.

Repeat for all other symbols A2-C3. Use the table below to set the correct primitive name per symbol.

Symbol name Primitive name
A1, B1, C1 offset_left
A2, B2, C2 offset_middle
A3, B3, C3 offset_right

Note: If you do have an Offset X set for a given symbol be sure to set it back to 0.

  • Save the project.

Step 2

  • Open the Letters_with_po.stylx in the DB Browser and open the style's meta table.

Make the following changes:

  • Change dictionary_name to "LETTERS-PO".
  • Change the dictionary_configuration value. Change the "symbol": json definition to: "symbol": ["letter1", "letter2", "letter3"], (see step 13)
  • Click Apply.

Step 3

We need to configure our Arcade script to use primitive overrides for the offset x values.

A primitive override is a way to change a symbol property value programmatically using Arcade. Primitive overrides refer to the specific symbol properties to be "overridden" via a primitive name (see step 1 above). The Arcade script adds the override, primitive name, and the property it references, into the key string - all concatenated onto the symbol key of the symbol that is to be changed. The primitive name is always be prefixed with po:.

The exact syntax for referring to a primitive override is po:<primitive_name>|<property_name>|<value> where <property_name>|<value> are the corresponding property and value (in the given symbol) to be overridden. (refer to understanding the dictionary)

Recall, each feature that uses our style, is rendered with three symbols: An offset x left, no offset x middle, and an offset x right. For example:

style_example.png

This corresponds to a key string of A1;B2;C3 in our Letters_with_offset.stylx style (corresponding to feature "letter" attribute values: 1, 2, 3, with symbol offsets of -14pt, 0, 14pt respectively) .

Using primitive overrides, our corresponding key string for the Letters_with_po.stylx style will be:

A1:po:offset_left|OffsetX|-14;B2;C3:po:offset_right|OffsetX|14;

Notice how the key string now contains the offset X value as part of an override. Let's break it down:

  • A1:po:offset_left|OffsetX|-14; use symbol key A1, with an override po: on symbol layers tagged with primitive name offset_left to set the OffsetX property with a value of -14 (pts) (offset to the left).

  • B2; use symbol key B2 as-is with no overrides.

  • C3:po:offset_right|OffsetX|14 use symbol key C3, with an override po: on symbol layers tagged with primitive name offset_right to set the OffsetX property with a value of 14 (pts) (offset to the right).

The below Arcade snippet uses a function offsetoverride to apply an offset to the given symbol key using primitive overrides. It also includes logic to apply an offset Y if you want to experiment with that also.

var _key = "";

// Create a key string for the offset x and offset y (if a y is provided)
function offsetoverride(pn_name, offset_x, offset_y) {
    _key = "";
	
    //Offset markers
    if (offset_x != 0) {
       _key += ';po:' + pn_name + '|OffsetX|';
       _key += offset_x;
    }
	
    if (offset_y != 0) {
       _key += ';po:' + pn_name + '|OffsetY|';
       _key += offset_y;
    }
    return _key;
}

var _letter = "";
//offset left for letter1
if (!isempty($letter1)) {
    _letter = decode($letter1, '1','A1','2','B1','3','C1','');
    key1 = _letter + offsetoverride("offset_left",-14, 0);//14pts to the left
    keys = key1;
}

Notice that the key1 key string includes the symbol key plus its corresponding OffsetX override string (retrieved from the offsetoverride function). The complete Arcade script is below. Copy this into the dictionary_script field value. Apply and Write Changes to save it to the style.

// conventions:
// $xyz: attribute (received as string)
// _xyz: local variable

// calculating the semi-colon delimited keys
var keys = '';
var key1 = '';
var key2 = '';
var key3 = '';

var _key = "";

// Create a key string for the offset x and offset y (if a y is provided)
function offsetoverride(pn_name, offset_x, offset_y) {
    _key = "";
	
    //Offset markers
    if (offset_x != 0) {
       _key += ';po:' + pn_name + '|OffsetX|';
       _key += offset_x;
    }
	
    if (offset_y != 0) {
       _key += ';po:' + pn_name + '|OffsetY|';
       _key += offset_y;
    }
    return _key;
}

//Translate the letter values into a symbol key
var _letter = "";
//offset left for letter1
if (!isempty($letter1)) {
    _letter = decode($letter1, '1','A1','2','B1','3','C1','');
    key1 = _letter + offsetoverride("offset_left",-14, 0);//14pts to the left
    keys = key1;
}

//No offset for the middle letter but we will change the
//background color
if (!isempty($letter2)) {
    _letter = decode($letter2, '1','A2','2','B2','3','C2','');
    key2 = _letter;
    //key2 = _letter + coloroverride("color_middle",'#00FF00');
    if (!isempty(keys)) {
         keys = keys + ";" + key2;
    }
    else {
         keys = key2;
    }
}

//offset right for letter 3
if (!isempty($letter3)) {
    _letter = decode($letter3, '1','A3','2','B3','3','C3','');
    key3 = _letter + offsetoverride("offset_right",14, 0);//14pts to the  right
    if (!isempty(keys)) {
        keys = keys + ";" + key3;
    }
    else {
        keys = key3;
    }
}

// See if text should be displayed.
var showLabels = $text != 'OFF';

// Create the concatenated string of keys (separated with ";"). Add the label key if text is on.
if (showLabels) {
  keys = keys + ";label-name";
}
  
// Return string of keys.
return keys;

Part 3 - Optional - Modify Symbol Color via Primitive Override

Let's look at one final modification. We will use a primitive override to change the "middle" symbols' background color (A2, B2, and C3). We are going to change A2 to be green, B2 to be (baby) blue, and C2 to be yellow.

style_with_colors2.png

For the color primitive override to work we will have to change the structure of our symbols slightly to use a polygon fill (not a point symbol as currently) for the letter background.

We need to change the "Circle" shape maker symbol layer in each of the three "middle" symbols from this:

point_symbol_before.png

To this:

point_symbol_after.png

Note the change from "point symbol" to "fill symbol"

Step 1

  • Open the Catalog view (i.e. "Manage")
  • Select A2.
  • Select "Properties". Select the "Layers" tab.
  • Select the "Circle" shape marker symbol layer.
  • Select the "Circle" shape from the "Form" combo

select_circle_form.png

This will change the layer to use a "Shape fill symbol" which is what we want.

To replicate the look of the original symbol which used a point marker we need to tweak the size and outline.

  • Change the size to 17pt and the Outline width to 0.75pt and Apply the changes.

change_size_and_width.png

Step 2

Next, we need to set the primitive name that we will use in the override (for the color). However, we need to set the primitive name _on the "embedded" polygon symbol_ used for the fill color and not on the "parent" shape marker layer (as we did for the x offsets).

  • Select the "Format polygon symbol..." menu option from within the "Shape fill symbol" combo (on the "Circle" shape marker symbol layer)

format_polygon_symbol.png

This will show the "Layers" for the embedded polygon symbol.

  • Select the "Structure" tab.
  • Add the primitive name "color_fill_middle" to the fill layer (to manipulate the outline, tag the outline with "color_outline_middle" or any name of your choice).

embedded_polygon_symbol.png

  • Click Apply to apply your changes.
  • Repeat for symbols B2 and C2.
  • Save the Project.

Step 3

We need to add code to our Arcade script to override the background color using our "color_fill_middle" primitive name.

We will be using the code shown in the following snippet. The function coloroverride provides the color override key string. The code for the "key2" string picks a background color based on the selected "letter" then calls the coloroverride function to construct the override string:

 // Create a key string to override the background color
 function coloroverride(pn_name, color) {
    _key = "";
    _key += ';po:' + pn_name + '|Color|';
    _key += color;
	
    return _key;
 }

 ...

 //No offset X for the middle letter but we will change the background color
 if (!isempty($letter2)) {
    _letter = decode($letter2, '1','A2','2','B2','3','C2','');

    //pick a fill color for each letter
    //Note - you can specify an "Alpha" if you want to modify the transparency
    //eg 00FF0000 green, full transparent, #00FF0050 green, semi transparent, #00FF0099 green, opaque
    var _fill_color = decode(_letter, 'A2','#00FF00','B2','#73C2FB','C2','#FFFF00','#FFFFFF');

    //outline color change if you want it...
    //var _outline_color = decode(_letter, 'A2','#FF0000','B2','#00FF00','C2','#000080','#000000');

    key2 = _letter + coloroverride("color_fill_middle",_fill_color);
    //key2 += coloroverride("color_outline_middle",_outline_color);
    if (!isempty(keys)) {
         keys = keys + ";" + key2;
    }
    else {
         keys = key2;
    }
 }
 ...

The complete Arcade script to use is below. Copy/paste it into the dictionary_script field value (within the "meta" table using the DB Browser).

// conventions:
// $xyz: attribute (received as string)
// _xyz: local variable

 // calculating the semi-colon delimited keys
 var keys = '';
 var key1 = '';
 var key2 = '';
 var key3 = '';

 var _key = "";

// Create a key string for the offset x and offset y (if a y is provided)
function offsetoverride(pn_name, offset_x, offset_y) {
    _key = "";
	
    //Offset markers
    if (offset_x != 0) {
       _key += ';po:' + pn_name + '|OffsetX|';
       _key += offset_x;
    }
	
    if (offset_y != 0) {
      _key += ';po:' + pn_name + '|OffsetY|';
      _key += offset_y;
    }
    return _key;
}

// Create a key string to override the background color
function coloroverride(pn_name, color) {
    _key = "";
   _key += ';po:' + pn_name + '|Color|';
   _key += color;
	
    return _key;
}

//Translate the letter values into a symbol key
var _letter = "";
//offset left for letter1
if (!isempty($letter1)) {
    _letter = decode($letter1, '1','A1','2','B1','3','C1','');
    key1 = _letter + offsetoverride("offset_left",-14, 0);//14pts to the left
    keys = key1;
}

//No offset X for the middle letter but we will change the background color
if (!isempty($letter2)) {
    _letter = decode($letter2, '1','A2','2','B2','3','C2','');

    //pick a fill color for each letter
    //Note - you can specify an "Alpha" if you want to modify the transparency
    //eg 00FF0000 green, full transparent, #00FF0050 green, semi transparent, #00FF0099 green, opaque
    var _fill_color = decode(_letter, 'A2','#00FF00','B2','#73C2FB','C2','#FFFF00','#FFFFFF');

    //outline color change if you want it...
    //var _outline_color = decode(_letter, 'A2','#FF0000','B2','#00FF00','C2','#000080','#000000');
    
    key2 = _letter + coloroverride("color_fill_middle",_fill_color);
    //key2 += coloroverride("color_outline_middle",_outline_color);
    if (!isempty(keys)) {
         keys = keys + ";" + key2;
    }
    else {
         keys = key2;
    }
}

//offset right for letter 3
if (!isempty($letter3)) {
    _letter = decode($letter3, '1','A3','2','B3','3','C3','');
    key3 = _letter + offsetoverride("offset_right",14, 0);//14pts to the  right
    if (!isempty(keys)) {
        keys = keys + ";" + key3;
    }
    else {
        keys = key3;
    }
}

// See if text should be displayed.
var showLabels = $text != 'OFF';

// Create the concatenated string of keys (separated with ";"). Add the label key if text is on.
if (showLabels) {
  keys = keys + ";label-name";
}
  
// Return string of keys.
return keys;

Click "Apply" and "Write Changes"

Step 4

Open Pro. Your "Redlands_Letters" layer that is using the "LETTERS-PO" dictionary style should now be rendering the middle symbol with its associated background color. Debug your style and Arcade script as needed.

style_with_colors.png

...and with the symbol outline code uncommented:

style_with_colors3.png

⚠️ **GitHub.com Fallback** ⚠️