Select to view content in your preferred language

Use ArcGIS Arcade to Create Environmental Callout Box and Into Dynamic Results

870
10
Jump to solution
07-16-2024 05:13 PM
Christopher_Spadi
Occasional Contributor

Greetings, 

I am using this source: Use ArcGIS Arcade to Step Out of the Static Environmental Callout Box and Into Dynamic Results - Ind...

Which is great by the way.

1. I wanted to modify it to add a few extra fields for a general label that highlights exceedances based off field with Y and N. 

- I could get the extra fields added but the table background was giving me issues. Would like it to look like this format for the whole table: 

Christopher_Spadi_0-1721174583013.png

 

Currently it looks like this in the label:

Christopher_Spadi_1-1721174613357.png

 

With this code: 

 

// Define fields
var analyte_fields = [$feature.Test1, $feature.Test2, $feature.Test3, $feature.Test4];
var result_fields = [$feature.Test1Result, $feature.Test2Result, $feature.Test3Result, $feature.Test4Result];
var exceed_fields = [$feature.Test1Exceed, $feature.Test2Exceed, $feature.Test3Exceed, $feature.Test4Exceed];
var sampledate_fields = [$feature.SampleDate1, $feature.SampleDate2, $feature.SampleDate3, $feature.SampleDate4];
var shallowdepth_fields = [$feature.ShallowDepth1, $feature.ShallowDepth2, $feature.ShallowDepth3, $feature.ShallowDepth4];
var deepestdepth_fields = [$feature.DeepestDepth1, $feature.DeepestDepth2, $feature.DeepestDepth3, $feature.DeepestDepth4];

// Column widths
var clmwdth_s = 20; // Column width for Sample
var clmwdth_r = 12; // Column width for Result
var clmwdth_d = 20; // Column width for Date
var clmwdth_sd = 16; // Column width for Shallow Depth
var clmwdth_dd = 16; // Column width for Deepest Depth

// Text settings
var textFontName = "Consolas";
var textFontStyle = "Regular";
var textFontSize = 14;

// Helper functions
function ljust(string, width) {
    if (Count(string) > width) {
        string = Left(string, width);
    } else {
        for (var i = Count(string); i < width; i++) {
            string += ' ';
        }
    }
    return string;
}

function FormatFont(label, name, style, size) {
    var tagName = IIF(name == "", "", " NAME='" + name + "'");
    var tagStyle = IIF(style == "", "", " STYLE='" + style + "'");
    var tagSize = IIF(size == 0, "", " SIZE='" + size + "'");
    return "<FNT" + tagName + tagStyle + tagSize + ">" + label + "</FNT>";
}

// Setup table headings
var h1 = FormatFont(ljust(" Sample", clmwdth_s), textFontName, textFontStyle, 0);
var h2 = FormatFont(ljust(" Result", clmwdth_r), textFontName, textFontStyle, 0);
var h4 = FormatFont(ljust(" Sample Date", clmwdth_d), textFontName, textFontStyle, 0);
var h5 = FormatFont(ljust(" Shallow Depth", clmwdth_sd), textFontName, textFontStyle, 0);
var h6 = FormatFont(ljust(" Deepest Depth", clmwdth_dd), textFontName, textFontStyle, 0);

// Create the style for each row
var counter = 0;
var table_result = "";

// Create a combined list of analyte and depth rows
var total_rows = Max(Count(analyte_fields), Count(sampledate_fields));

// Function to format a single row
function formatRow(analyte_idx, date_idx) {
    var row = "";

    // Analyte part
    if (analyte_idx < Count(analyte_fields)) {
        var analyte_val = analyte_fields[analyte_idx];
        var result_val = result_fields[analyte_idx];
        var exceed_val = exceed_fields[analyte_idx];

        if (analyte_val != null && result_val != null && exceed_val != null) {
            row += ljust(" " + analyte_val, clmwdth_s) +
                   ljust(" " + Text(Round(result_val, 4)), clmwdth_r);
        } else {
            row += ljust(" ", clmwdth_s) + ljust(" ", clmwdth_r);
        }
    } else {
        row += ljust(" ", clmwdth_s) + ljust(" ", clmwdth_r);
    }

    // Date and depth part
    if (date_idx < Count(sampledate_fields)) {
        var sampledate_val = sampledate_fields[date_idx];
        var shallowdepth_val = shallowdepth_fields[date_idx];
        var deepestdepth_val = deepestdepth_fields[date_idx];

        if (sampledate_val != null && shallowdepth_val != null && deepestdepth_val != null) {
            row += ljust(" " + Text(sampledate_val), clmwdth_d) +
                   ljust(" " + Text(shallowdepth_val), clmwdth_sd) +
                   ljust(" " + Text(deepestdepth_val), clmwdth_dd) +
                   TextFormatting.Newline;
        } else {
            row += ljust(" ", clmwdth_d) + ljust(" ", clmwdth_sd) + ljust(" ", clmwdth_dd) + TextFormatting.Newline;
        }
    } else {
        row += ljust(" ", clmwdth_d) + ljust(" ", clmwdth_sd) + ljust(" ", clmwdth_dd) + TextFormatting.Newline;
    }

    return row;
}

// Iterate over the combined list
for (var i = 0; i < total_rows; i++) {
    table_result += formatRow(i, i);
}

// Final concatenated string
$feature.SiteName + " - " + $feature.SampleID + "\n" + h1 + h2 + h4 + h5 + h6 + "\n" + table_result;

 

I would greatly appreciate if I could get the script updated to show like the original did using the attached Table_1_Test_Example

2. I was also wanting to get a version of this that used a shallowest and deepest depth field but was thinking the source data table needed to be formatted differently, wide vs long.

My end goal for the label on the 2nd example would be this:

Screenshot 2024-07-16 164136.png

What would the source table need to be formatted to and what would be the arcade expression for that?

 

Thanks in advance.

 

Chris

 

 

 

 

0 Kudos
1 Solution

Accepted Solutions
Christopher_Spadi
Occasional Contributor

Was able to figure out. 

Christopher_Spadi_0-1721430871436.png

 

View solution in original post

0 Kudos
10 Replies
jcarlson
MVP Esteemed Contributor

Take a look at the BGD style tag. That lets you apply a background color, outline, and padding. Everything you need to make it look like a table! Since your cells all have the same outline and padding, you could probably define those globally and just use the parameter to alter the color.

I'm not able to test it in Pro right now, but try adding another parameter to your FormatFont helper function.

 

// up at the top
var bgdGlobals= `width='1' padding='1' outline_black='100' outline_alpha='100' alpha='100'`

// other stuff…

// your function
function FormatFont(label, name, style, size, bgcol) {
    var tagName = IIF(name == "", "", `NAME='${name}'`);
    var tagStyle = IIF(style == "", "", `STYLE='${style}'`);
    var tagSize = IIF(size == 0, "", `SIZE='${size}'`);
    return `<FNT ${tagName} ${tagStyle} ${tagSize}><BGD ${bgdGlobals} ${bgcol}>${label}</BGD></FNT>`;
}

 

 

Then when you build your label, you can do something like this:

 

FormatFont(ljust(" Sample", clmwdth_s), textFontName, textFontStyle, 0, "blue='150'")

 

 

And I think that would do the trick.

Edit to add: to get it conditional to highlight exceeded values, you would probably just need an IIF statement in the final parameter.

FormatFont(
  'This could be highlighted',
  textFontName,
  textFontStyle,
  0,
  Iif(
    $feature['some_value'] > 0.001, // set threshold for highlighting as needed
    "red='200'", // adjust as needed to get your "highlight" color
    "red='255' blue='255' green='255'" // default to white
  )
)
- Josh Carlson
Kendall County GIS
0 Kudos
Christopher_Spadi
Occasional Contributor

Thanks for the response, Josh, wasn't able to get it to work on my end. 

I would still like to get a version of the table label 1 to be formatted like the ESRI example with the additional fields, but when I try there is no expression error, but nothing appears for the label. 

0 Kudos
jcarlson
MVP Esteemed Contributor

https://pro.arcgis.com/en/pro-app/latest/help/mapping/text/text-formatting-tags.htm#ESRI_SECTION1_DD...

I feel like it is possible somehow. Messing around in Pro, I can get some of the background attributes to work, but not all.

jcarlson_0-1721253737603.png

Similar to what you said, when I add things like padding or outline width, the labels disappear entirely. What version of Pro are you on? I'm on 3.2, I wonder if the other formatting tags were added later.

- Josh Carlson
Kendall County GIS
0 Kudos
Christopher_Spadi
Occasional Contributor

Thanks for trying Josh. I am currently on Version 3.1, we are about to go to 3.2 in the next few weeks, is it stable for the most part?

0 Kudos
jcarlson
MVP Esteemed Contributor

3.2 has worked well for our department's needs, and we're sticking here for now, 3.3 had some issues that made our work harder.

- Josh Carlson
Kendall County GIS
0 Kudos
Christopher_Spadi
Occasional Contributor

For the 2nd label type I am going for, I've attached an Excel file of example data.

This is the Arcade so far:

 

 

 

// User can define fields specific to their data here

// Sample ID Fields - this is the field that includes the sample IDs
var sampleid_fields = [$feature.SampleID];

// Set the column width for the tables
// You can define multiple widths or a single width for all
var clmwdth_s = 28; // Column width for Sample ID
var clmwdth_d = 8; // Column width for Depth
var clmwdth_r = 10; // Column width for Result

// Set up for color definitions - these do not need to be changed unless you would like to vary the colors
// Adjust the rgba values for these or add additional colors, the first three are RGB colors and the last number is the transparency
var yellow = [252,202,70,100];
var orange = [254,127,45,100];
var red    = [164,22,26,100];
var blue   = [3,83,164,100];
var ltblue = [95,168,211,100];
var green  = [76,149,108,100];
var ltgreen= [97,155,138,100];
var black  = [0,0,0,100];
var white  = [255,255,255,100];
var none   = [0,0,0,0];

// Set default text for use across all label cells
// Var textFontName  = "Consolas"; is used as it correctly displays monospace fonts - recommend using Consolas font as everything lines up better
var textFontName  = "Consolas";
var textFontStyle = "Regular";
var textFontSize  = "8";

function ljust(string, width) {
    if (count(string) > width ) {
        string = left(string, width)
    } else {
        for (var i = count(string); i < width; i++) {
            string += ' '
        }
    }
    return string
}

// Configure base functions for the font color, style, background and outline - this does not need to be updated unless deliverable requires different formatting
function FormatBO(background, outline, width, padding, txt){
  var attr = ""
  if(background != none && count(background) == 4){
   attr += " red='"   + background[0] + "'"
    attr += " green='" + background[1] + "'"
    attr += " blue='"  + background[2] + "'"
    attr += " alpha='" + background[3] + "'"
  }
  if(outline != none && count(outline) == 4){
    attr += " outline_red='"    + outline[0] + "'"
    attr += " outline_green='"  + outline[1] + "'"
    attr += " outline_blue='"   + outline[2] + "'"
    attr += " outline_alpha='"  + outline[3] + "'"
    attr += " width='" + width + "'"
    attr += " padding='" + padding + "'"
  }
  return "<BGD" + attr + ">" + txt + "</BGD>"
}

function SetTextColor(rgba, txt)
{
  var r = rgba[0]
  var g = rgba[1]
  var b = rgba[2]
  var a = rgba[3]
  return "<CLR red='" + r + "' green='" + g + "' blue='" + b + "' alpha='" + a + "'>" + txt + "</CLR>"; 
}

// This can be used to override the default font setting for a particular cell
function FormatFont(label, name, style, size)
{
  var tagName = iif(name=="", "", " NAME='"+name+"'")
  var tagStyle = iif(style=="", "", " STYLE='"+style+"'")
  var tagSize = iif(size==0, "", " SIZE='"+size+"'")
  return "<FNT" + tagName + tagStyle + tagSize + ">" + label + "</FNT>"
}


// Setup the items for the table heading 
// You can add additonal lines using "\n"
// This is only needed if you would like headers for each of your columns - in this case I used the column headers to give the units for the depths and then the two sampling periods)
var h1 = SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" (ft) bgs ", clmwdth_d), textFontName, textFontStyle, 0)))
var h2 = SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" PCE ", clmwdth_r), textFontName, textFontStyle, 0)))
var h3 = SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" TCE ", clmwdth_r), textFontName, textFontStyle, 0)))
var h4 = SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" VC ", clmwdth_r), textFontName, textFontStyle, 0)))
var h5 = SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" Benzene ", clmwdth_r), textFontName, textFontStyle, 0)))

// Create the style for each row
// Repeat for each set of columns you have to create the text for each row

// This section creates the first row of data, it refers to the D1 and D1 result fields
var counter = 0;
var table_result1 = ""

for (var sampleid in sampleid_fields){

table_result1 += 
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.D1, clmwdth_d), textFontName, textFontStyle, 0))) + 
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test1Result_D1, clmwdth_r), textFontName, textFontStyle, 0))) +
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test2Result_D1, clmwdth_r), textFontName, textFontStyle, 0))) +
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test3Result_D1, clmwdth_r), textFontName, textFontStyle, 0))) +
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test4Result_D1, clmwdth_r), textFontName, textFontStyle, 0)))

counter+=1
}

// This section creates the second row of data, it refers to the D2 and D2 result fields
var counter = 0;
var table_result2 = ""

for (var sampleid in sampleid_fields){

table_result2 += 
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.D2, clmwdth_d), textFontName, textFontStyle, 0))) + 
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test1Result_D2, clmwdth_r), textFontName, textFontStyle, 0))) +
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test2Result_D2, clmwdth_r), textFontName, textFontStyle, 0))) +
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test3Result_D2, clmwdth_r), textFontName, textFontStyle, 0))) +
SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust(" " + $feature.Test4Result_D2, clmwdth_r), textFontName, textFontStyle, 0)))

counter+=1
}

// Final concatenated string
// This is where everything is pulled together for the final table - sample ID, column headers, iif statement is used to include multiple depths - if D2 is null only table results 1 (row 1) are included, if D2 is not null table results 1 (row 1) and table results 2 (row 2) are included
// Add a "\n" (carrige return) between each table row
// The LIN -3 is needed when using the 'Consolas' font to account for row height. 
// The LIN leading value can be adjusted based on the type of font and font size selected.
 "<LIN leading = '-3' leading_type = 'extra'>" + SetTextColor(black, FormatBO(white, black, 1, 0, FormatFont(ljust($feature.SampleID, clmwdth_s), textFontName, textFontStyle, 0))) + "\n" + h1 + h2 + h3 + h4 + h5 + "\n" + IIF(IsEmpty($feature.D2), table_result1, table_result1 + "\n" + table_result2) + "</LIN>"

 

 

 

 

This is what the label looks like with the code: 

Screenshot 2024-07-17 111923.png

Would like the table columns and rows to be uniform minus the Sample location on top. Look at attached image. There is also a field for Exceeds (Y or N), and it would be nice to highlight the ones that exceed. 

 

 

 

Tags (1)
0 Kudos
Christopher_Spadi
Occasional Contributor

Was able to figure out. 

Christopher_Spadi_0-1721430871436.png

 

0 Kudos
jcarlson
MVP Esteemed Contributor

Looks great! Nice work!

- Josh Carlson
Kendall County GIS
0 Kudos
Christopher_Spadi
Occasional Contributor

If anyone has a tip on how to get rid of the small gaps between the rows, please let me know. Everything I tried made the label disappear. 

0 Kudos