<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Changing symbology dynamically based on selector filters in ArcGIS Dashboards in ArcGIS Dashboards Questions</title>
    <link>https://community.esri.com/t5/arcgis-dashboards-questions/changing-symbology-dynamically-based-on-selector/m-p/1658095#M11546</link>
    <description>&lt;P&gt;I've done something like this by having the same layer with different symbols applied and having them render only when being selected. For instance i have a set of points that normally just show location and can be selected by an administrative boundary, that same layer can also be selected using two different number selectors&amp;nbsp; based on different metrics of interest. If this could be done against a single layer that would be interesting, but I suspect not possible even using Arcade.&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 15 Oct 2025 16:12:06 GMT</pubDate>
    <dc:creator>clt_cabq</dc:creator>
    <dc:date>2025-10-15T16:12:06Z</dc:date>
    <item>
      <title>Changing symbology dynamically based on selector filters in ArcGIS Dashboards</title>
      <link>https://community.esri.com/t5/arcgis-dashboards-questions/changing-symbology-dynamically-based-on-selector/m-p/1658066#M11543</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;&lt;P&gt;I'm creating a dashboard that shows map data for different indicators and themes.&lt;BR /&gt;This is currently based on one feature layer with a single symbology defined in Map Viewer.&lt;/P&gt;&lt;P&gt;I was wondering if it’s possible to change the symbology dynamically based on the filters applied through the different selectors (Scale, Theme, and Indicator).&lt;BR /&gt;For example, one indicator might have much lower values than another, so the current symbology range doesn’t fit all cases.&lt;/P&gt;&lt;P&gt;Could this be achieved with Arcade or data expressions, or is there another recommended approach?&lt;/P&gt;&lt;P&gt;Kind regards,&lt;/P&gt;&lt;P&gt;Geert Offenberg&lt;/P&gt;</description>
      <pubDate>Wed, 15 Oct 2025 15:25:03 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-dashboards-questions/changing-symbology-dynamically-based-on-selector/m-p/1658066#M11543</guid>
      <dc:creator>GOffenberg</dc:creator>
      <dc:date>2025-10-15T15:25:03Z</dc:date>
    </item>
    <item>
      <title>Re: Changing symbology dynamically based on selector filters in ArcGIS Dashboards</title>
      <link>https://community.esri.com/t5/arcgis-dashboards-questions/changing-symbology-dynamically-based-on-selector/m-p/1658095#M11546</link>
      <description>&lt;P&gt;I've done something like this by having the same layer with different symbols applied and having them render only when being selected. For instance i have a set of points that normally just show location and can be selected by an administrative boundary, that same layer can also be selected using two different number selectors&amp;nbsp; based on different metrics of interest. If this could be done against a single layer that would be interesting, but I suspect not possible even using Arcade.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 15 Oct 2025 16:12:06 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-dashboards-questions/changing-symbology-dynamically-based-on-selector/m-p/1658095#M11546</guid>
      <dc:creator>clt_cabq</dc:creator>
      <dc:date>2025-10-15T16:12:06Z</dc:date>
    </item>
    <item>
      <title>Re: Changing symbology dynamically based on selector filters in ArcGIS Dashboards</title>
      <link>https://community.esri.com/t5/arcgis-dashboards-questions/changing-symbology-dynamically-based-on-selector/m-p/1698815#M11902</link>
      <description>&lt;P&gt;Sorry for the late reply and the wall of text, but if I understand correctly, I believe we have implemented something similar in a dashboard I called 'Dynamic choropleth mapping'.&amp;nbsp; It was quite the task to figure out, so I want to document it here in case it helps someone else in the future.&lt;/P&gt;&lt;P&gt;We have an indicator for "Select Geography" where the user can pick between different sets of polygon features, like Council District, School District, or Zip Code.&amp;nbsp; Once a geography is selected, a dashboard list of the different variables / parameters is populated, like Average Household Size, Population, Median Income, etc.&amp;nbsp; Once we have selected both the geography and the variable, the map updates with color gradient symbology. We use another list to display a custom legend for that map. This was just a proof of concept, but it seemed to work. Note in the screenshots that the geography, symbology layer, and color scale are different, but it is all fed by a single hosted feature layer.&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="BrennanSmith1_0-1777399792006.png" style="width: 400px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/151684i0ED37FB2835036AD/image-size/medium?v=v2&amp;amp;px=400" role="button" title="BrennanSmith1_0-1777399792006.png" alt="BrennanSmith1_0-1777399792006.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="BrennanSmith1_1-1777399816230.png" style="width: 400px;"&gt;&lt;img src="https://community.esri.com/t5/image/serverpage/image-id/151686iC6D57203DD5A82B0/image-size/medium?v=v2&amp;amp;px=400" role="button" title="BrennanSmith1_1-1777399816230.png" alt="BrennanSmith1_1-1777399816230.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;It was a bit tricky to set up.&amp;nbsp; I created a single feature class that contained every combination of geography (i.e. polygon sets) and variable (i.e. whatever census metrics we were interested in). This python script did that first part.&amp;nbsp; You end up with a feature class that has the geography (polygon source), feature_na (unique identifier for each feature within a source, e.g. zip code), metric_name (the variable you want to plot), value (the value of the metric), and filter_list (the concatenated string of geography source and metric name, used in the dashboard).&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
import pandas as pd
import os

# ==========================================
# 0. HELPER FUNCTIONS
# ==========================================

def arc_to_df(in_fc, input_fields=None, query=""):
    """Converts an arcpy table/feature class to a pandas DataFrame."""
    OIDFieldName = arcpy.Describe(in_fc).OIDFieldName
    if input_fields:
        final_fields = [OIDFieldName] + input_fields
    else:
        final_fields = [f.name for f in arcpy.ListFields(in_fc) if f.type not in ['Geometry','Blob']]
    
    data = [row for row in arcpy.da.SearchCursor(in_fc, final_fields, where_clause=query)]
    fc_dataframe = pd.DataFrame(data, columns=final_fields)
    fc_dataframe = fc_dataframe.set_index(OIDFieldName, drop=True)
    return fc_dataframe

# ==========================================
# 1. CONFIGURATION
# ==========================================

#This assumes you have already assembled a master table with every input geography and output metric.
hosted_table = "Demo_Data_Table" 

# Dictionary of { "Geography Type Name" : "Path to Feature Class or name in TOC" }
geo_inputs = {
    "Council District": "CD_Geo",
    "Constituent Services": "CS_Geo",
    "Zipcode": "Zip_Geo_Clip",
    "Elementary Sch. Dist.":"ElemSch_Geo",
    "Middle Sch. Dist.":"MidSch_Geo",
    "High Sch. Dist.":"HighSch_Geo"
}

# Dictionary of { "Input Field Name" : "Output Metric Description" }
metric_dict = {
    "populationtotals_totpop_cy": "Total Population",
    "populationtotals_dpop_cy":"Daytime Population",
    "householdtotals_tothh_cy": "Number of Households",
    "householdtotals_avghhsz_cy": "Average Household Size", 
    "homevalue_medval_cy":"Median Home Value",
    "householdincome_medhinc_cy":"Median Income"
}

# Output setup
workspace = arcpy.env.scratchGDB
out_fc_name = "opz_dashboard_metrics"
out_fc_path = os.path.join(workspace, out_fc_name)

# ==========================================
# 2. PANDAS DATA PREP (The Melt)
# ==========================================
print("Loading data from hosted table via arc_to_df...")

# Build the list of fields to pull from the hosted table (using lowercase)
## In our case, the geography field defines the polygon source (i.e. the keys in the geo_inputs dict)
## and the feature_na field is the unique descriptions for each individual polygon within a source (i.e. the zip codes)
fields_to_pull = ["geography", "feature_na"] + list(metric_dict.keys())

# Create the dataframe using your function
df = arc_to_df(hosted_table, input_fields=fields_to_pull)

# Ensure the merge key is a string to match the GIS data reliably
df['feature_na'] = df['feature_na'].astype(str)

print("Melting dataframe...")

# The magic 'melt' function: wide format to long format
melted_df = df.melt(
    id_vars=["geography", "feature_na"],          
    value_vars=list(metric_dict.keys()),          
    var_name="metric_code",                       
    value_name="value"                            
)

# Map the readable descriptions from your dictionary
melted_df["metric_name"] = melted_df["metric_code"].map(metric_dict)

# Make field that combines geography and metric name for filtering
melted_df['filter_list'] = melted_df['geography'] + " - " + melted_df['metric_name']

# Drop rows where the metric value is null so you don't draw empty polygons
melted_df = melted_df.dropna(subset=["value"])

# ==========================================
# 3. GEOMETRY LOOKUP
# ==========================================
print("Building geometry lookup dictionary from feature layers...")

# We will store geometries here -&amp;gt; {(geography, feature_na): SHAPE@}
geom_dict = {}

for geo_name, fc_path in geo_inputs.items():
    with arcpy.da.SearchCursor(fc_path, ["feature_na", "SHAPE@"]) as s_cursor:
        for row in s_cursor:
            feat_id = str(row[0]) 
            shape = row[1]
            geom_dict[(geo_name, feat_id)] = shape

# ==========================================
# 4. OUTPUT FEATURE CLASS CREATION
# ==========================================
print(f"Setting up output schema in: {workspace}")

first_layer = list(geo_inputs.values())[0]
desc = arcpy.Describe(first_layer)
sr = desc.spatialReference
geom_type = desc.shapeType

arcpy.env.overwriteOutput = True

arcpy.management.CreateFeatureclass(
    out_path=workspace,
    out_name=out_fc_name,
    geometry_type=geom_type,
    spatial_reference=sr
)

# Lowercase field names applied to the schema
arcpy.management.AddField(out_fc_path, "geography", "TEXT", field_length=50)
arcpy.management.AddField(out_fc_path, "feature_na", "TEXT", field_length=100)
arcpy.management.AddField(out_fc_path, "metric_name", "TEXT", field_length=100)
arcpy.management.AddField(out_fc_path, "value", "DOUBLE")
arcpy.management.AddField(out_fc_path, "filter_list", "TEXT", field_length=200)

# ==========================================
# 5. WRITE TO OUTPUT
# ==========================================
print("Writing merged data and geometries to output feature class...")

insert_fields = ["SHAPE@", "geography", "feature_na", "metric_name", "value","filter_list"]
total_inserted = 0
missing_geometries = 0

with arcpy.da.InsertCursor(out_fc_path, insert_fields) as i_cursor:
    # Iterate through the pandas dataframe rows using itertuples
    for row in melted_df.itertuples(index=False):
        # Accessing the properties via lowercase names based on the dataframe columns
        geo_name = row.geography
        feat_id = str(row.feature_na)
        metric_name = row.metric_name
        value = row.value
        f_list = row.filter_list
        
        # Look up the matching geometry based on the composite key
        shape = geom_dict.get((geo_name, feat_id))
        
        if shape:
            i_cursor.insertRow((shape, geo_name, feat_id, metric_name, value,f_list))
            total_inserted += 1
        else:
            missing_geometries += 1

print(f"Done! {total_inserted} records inserted.")
if missing_geometries &amp;gt; 0:
    print(f"Note: {missing_geometries} records from the hosted table had no matching geometry in the feature classes and were skipped.")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We then need to assign a color code to each polygon, based on the unique range of values for that combination of geography and metric. This script assigns a value 1-5 for the symbology_class field, and a color code to the color_hex field. Color schemes were set manually, use your preferred AI bot to save time updating the palettes dictionary. It also sets a unique value symbology for the layer, based on the color_hex field. Attribute mapping could be a cleaner way to achieve this, but doesn't publish online correctly.&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import arcpy
import pandas as pd
import numpy as np

# ==========================================
# 1. CONFIGURATION
# ==========================================
# Path to your master output feature class. And to your working Map and Layer name for the sybology customization
fc_path = r"opz_dashboard_metrics"
layer_name = "opz_dashboard_metrics" 
map_name    = "Map"

# Define your specific palettes for known metrics (Light to Dark)
palettes = {
    # Populations (Purples &amp;amp; Reds)
    "Total Population": {
        1: "#F2F0F7", 2: "#CBC9E2", 3: "#9E9AC8", 4: "#756BB1", 5: "#54278F"
    },
    "Daytime Population": {
        1: "#FEE5D9", 2: "#FCAE91", 3: "#FB6A4A", 4: "#DE2D26", 5: "#A50F15"
    },
    # Households (Greens)
    "Number of Households": {
        1: "#EDF8E9", 2: "#BAE4B3", 3: "#74C476", 4: "#31A354", 5: "#006D2C"
    },
    "Average Household Size": {
        1: "#E5F5E0", 2: "#A1D99B", 3: "#74C476", 4: "#41AB5D", 5: "#005A32" # Slightly different green tint
    },
    # Wealth &amp;amp; Value (Oranges &amp;amp; Golds)
    "Median Home Value": {
        1: "#FEEDDE", 2: "#FDBE85", 3: "#FD8D3C", 4: "#E6550D", 5: "#A63603"
    },
    "Median Income": {
        1: "#FFFFD4", 2: "#FED98E", 3: "#FE9929", 4: "#D95F0E", 5: "#993404"
    }
}

# The fallback palette if a metric isn't found above (Blues)
default_palette = {
    1: "#EFF3FF", 2: "#BDD7E7", 3: "#6BAED6", 4: "#3182BD", 5: "#08519C"
}

# Apply function to read the metric, class, and handle the default fallback
def get_color(row):
    metric = row['metric_name']
    val_class = row['symbology_class']
    
    # Check for No Data / Nulls first
    if val_class == 0 or pd.isna(val_class):
        return "#CCCCCC" # Light Gray
    
    # Check if we have a specific palette mapped for this metric
    if metric in palettes and val_class in palettes[metric]:
        return palettes[metric][val_class]
    
    # If metric is not in palettes, fallback to the default Blues
    if val_class in default_palette:
        return default_palette[val_class]
        
    return "#CCCCCC" # Ultimate failsafe


# ==========================================
# 2. READ DATA AND CALCULATE BINS
# ==========================================
print("Reading feature class to calculate color bins...")

oid_field = arcpy.Describe(fc_path).OIDFieldName
fields = [oid_field, "geography", "metric_name", "value"]

# Pull data into a pandas dataframe
data = [row for row in arcpy.da.SearchCursor(fc_path, fields)]
df = pd.DataFrame(data, columns=fields)

# Function to calculate 1-5 rank within a specific group
def assign_class(group):
    valid_vals = group.dropna()
    if len(valid_vals) == 0:
        return pd.Series(index=group.index, dtype=float)
    
    # Calculate percentile rank, then multiply by 5 and round up to get 1-5 classes
    ranks = valid_vals.rank(pct=True)
    classes = np.ceil(ranks * 5).astype(int)
    return classes.clip(1, 5) # Ensure it stays cleanly within 1-5

print("Grouping and applying classes...")

# Apply the binning function grouped by Geography AND Metric Name
df['symbology_class'] = df.groupby(['geography', 'metric_name'])['value'].transform(assign_class)

# Apply get_color across the dataframe (axis=1 means row-by-row) to turn class into hex
df['color_hex'] = df.apply(get_color, axis=1)

# ==========================================
# 3. WRITE COLORS BACK TO FEATURE CLASS
# ==========================================
print("Writing colors back to feature class...")

# Add fields for the class and the hex code (skipping if they already exist)
existing_fields = [f.name for f in arcpy.ListFields(fc_path)]
if "symbology_class" not in existing_fields:
    arcpy.management.AddField(fc_path, "symbology_class", "SHORT")
if "color_hex" not in existing_fields:
    arcpy.management.AddField(fc_path, "color_hex", "TEXT", field_length=10)

# Convert dataframe to a dictionary for lightning-fast lookup during the Update Cursor
# Format: { OID : {'symbology_class': 3, 'color_hex': '#6BAED6'} }
update_dict = df.set_index(oid_field)[['symbology_class', 'color_hex']].to_dict('index')

updated_count = 0
with arcpy.da.UpdateCursor(fc_path, [oid_field, "symbology_class", "color_hex"]) as u_cursor:
    for row in u_cursor:
        oid = row[0]
        if oid in update_dict:
            row[1] = update_dict[oid]['symbology_class']
            
            # Ensure we don't write NaN to the integer field
            if pd.isna(row[1]):
                row[1] = 0 
                
            row[2] = update_dict[oid]['color_hex']
            u_cursor.updateRow(row)
            updated_count += 1

print(f"Success! Updated colors for {updated_count} features.")



r'''
How to map the Hex Field in ArcGIS Pro
Set to Single Symbol: In the main Symbology pane for your layer, ensure the primary symbology is set to Single Symbol.

Open the Symbol Formatter: Click directly on the colored polygon patch next to "Symbol" to open the Format Polygon Symbol pane.

Go to Symbol Layers: Click the Properties tab, and then click the Layers icon (it looks like three stacked sheets of paper).

Enable Connections: Look near the top right of this panel for a tiny icon that looks like a database with a link or gear on it. Hover over it—it should say Allow symbol property connections. Click it so it turns blue/active.

Connect the Color: Now, look down at your Color dropdown. Because you clicked that button in Step 4, there will be a new, tiny database icon sitting right next to the color picker. Click that little database icon.

Select the Field: A "Set Attribute Mapping" dialog will pop up. In the Field dropdown, select your color_hex field. Click OK.

Apply: Click the Apply button at the bottom right of the pane.

Your map should instantly snap to using the exact hex colors we generated in the script.

'''

### BUMMER!  This approach doesn't publish to portal, too advanced.  Do this instead to hardcode unique values
# ==========================================
# 1. CONFIGURATION
# ==========================================

def hex_to_rgb_dict(hex_string):
    """Converts a hex color string to an ArcPy-friendly RGB dictionary."""
    h = hex_string.lstrip('#')
    # Convert hex to integers and append 100 for full opacity
    return {'RGB': [int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16), 100]}
    
    
# Target the active map and your specific layer
aprx = arcpy.mp.ArcGISProject("CURRENT")
m = aprx.listMaps(map_name)[0] # Change "Map" if your map frame is named differently

# The name of your layer exactly as it appears in the Table of Contents
lyr = m.listLayers(layer_name)[0]

# ==========================================
# 2. APPLY UNIQUE VALUES SYMBOLOGY
# ==========================================
print(f"Updating symbology for '{layer_name}'...")

sym = lyr.symbology

# Change renderer to Unique Values
if hasattr(sym, 'updateRenderer'):
    sym.updateRenderer('UniqueValueRenderer')
    
    # Set the field to our hex codes
    sym.renderer.fields = ["color_hex"]
    
    # Apply it back to the layer so Pro reads the data and generates the classes
    lyr.symbology = sym 
    
    # Re-read the symbology object to access the newly generated classes
    sym = lyr.symbology 
    
    # ==========================================
    # 3. MATCH COLORS TO HEX STRINGS
    # ==========================================
    update_count = 0
    
    # Loop through the unique value groups and items
    for grp in sym.renderer.groups:
        for itm in grp.items:
            hex_string = itm.label # The label is our actual hex code (e.g., "#08519C")
            
            # Skip the "&amp;lt;all other values&amp;gt;" bucket
            if hex_string.startswith("#"):
                try:
                    # Translate the hex to RGB and apply it
                    itm.symbol.color = hex_to_rgb_dict(hex_string)
                    update_count += 1
                except Exception as e:
                    print(f"  Could not set color for {hex_string}: {e}")
    
    # Apply the final color changes back to the layer
    lyr.symbology = sym
    print(f"Success! Matched {update_count} unique symbol patches to their hex codes.")

else:
    print("Error: Layer does not support Unique Values.")&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Once you publish this layer and get a dashboard ready, we build a data expression for both lists [Select Choropleth Layer for Map] and [Legend for Choropleth Layer].&amp;nbsp; &amp;nbsp;This first list needs to Action Filter both the map layer and legend list, using "Render Only When Filtered."&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*

This populates the list of geography - metric

Selections here will propagate forward to filter the map layer and the legend
*/

var fs = FeatureSetByPortalItem(Portal('URL'), 'itemID',0)

// 2. Group the data by the filter_list field to get unique values
var unique_menu = GroupBy(
    fs,
    ['filter_list', 'geography'], 
    [{ name: 'record_count', expression: '1', statistic: 'COUNT' }] 
);

// 3. Sort alphabetically 
return OrderBy(unique_menu, 'filter_list ASC');
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
Legend Data expression

This populates the list of geography - metric

Selections here will propagate forward to filter the map layer and the legend
*/

var fs = FeatureSetByPortalItem(Portal('URL'), 'itemID',0)

// We group by BOTH the filter string and the class so your Dashboard Category Selector still works!
var grouped = GroupBy(
    fs,
    ['filter_list', 'symbology_class'],
    [
        {name: 'min_val', expression: 'value', statistic: 'MIN'},
        {name: 'max_val', expression: 'value', statistic: 'MAX'},
        {name: 'hex_code', expression: 'color_hex', statistic: 'MAX'}
    ]
);

// Sort so Class 5 is always at the top of the legend
return OrderBy(grouped, 'symbology_class DESC');
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We then use Advanced Formatting on the legend list, to make the legend labels and format to 3 sig figs.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="javascript"&gt;/*
ADVANCED FORMATTING FOR LEGEND list

This does rounding to 3 sig figs, and creates the legend labels
*/

// Function to dynamically round to a specific number of significant figures
function formatSigFigs(val, sigFigs) {
    // Handle 0 or nulls so the math doesn't break
    if (IsEmpty(val) || val == 0) { 
        return "0"; 
    }
    
    // Calculate base-10 log by dividing natural Log(val) by natural Log(10)
    var mag = Floor(Log(Abs(val)) / Log(10));
    
    // Create a scale factor based on the requested sig figs
    var scale = Pow(10, (sigFigs - 1) - mag);
    
    // Do the actual mathematical rounding
    var rounded = Round(val * scale) / scale;
    
    // Apply commas for thousands, and allow up to 3 decimal places for small numbers
    return Text(rounded, '#,###.###'); 
}

// Pass our min and max values through the sig fig function (asking for 3 sig figs)
var minVal = formatSigFigs($datapoint["min_val"], 3);
var maxVal = formatSigFigs($datapoint["max_val"], 3);
var hex = $datapoint["hex_code"];

// Create the label text
var legendLabel = minVal + " to " + maxVal;

// Handle the fallback/No Data class
if ($datapoint["symbology_class"] == 0) {
    legendLabel = "No Data";
}

// Return the variables to your HTML
return {
    attributes: {
        labelText: legendLabel,
        hexColor: hex
    }
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And finally, we format the HTML of the legend table to make it look like a legend, with colored squares:&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;&amp;lt;figure class="table" style="width:100%;"&amp;gt;
    &amp;lt;table style="border-collapse:collapse;"&amp;gt;
        &amp;lt;tbody&amp;gt;
            &amp;lt;tr&amp;gt;
                &amp;lt;td style="background-color:{expression/hexColor};border-color:#a6a6a6;border-radius:3px;height:25px;width:35px;"&amp;gt;
                    &amp;amp;nbsp;
                &amp;lt;/td&amp;gt;
                &amp;lt;td style="color:#4c4c4c;font-size:14px;padding-left:15px;"&amp;gt;
                    {expression/labelText}
                &amp;lt;/td&amp;gt;
            &amp;lt;/tr&amp;gt;
        &amp;lt;/tbody&amp;gt;
    &amp;lt;/table&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 28 Apr 2026 18:35:07 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-dashboards-questions/changing-symbology-dynamically-based-on-selector/m-p/1698815#M11902</guid>
      <dc:creator>BrennanSmith1</dc:creator>
      <dc:date>2026-04-28T18:35:07Z</dc:date>
    </item>
  </channel>
</rss>

