Select to view content in your preferred language

Add a timeline bar to your pop-up with Arcade

930
0
12-29-2021 08:06 AM
by Anonymous User
Not applicable
4 0 930

About

Maps are a great tool for showcasing where something occurred, but it is often a challenge for digital cartographers to highlight when something occurred and the temporal tends surrounding it. While the Map Viewer in ArcGIS Online supports dynamic charts, I was looking for different ways to graphically present this information using the new Arcade content block options.

MikeSchoelen_0-1640792547342.png

Ideally, I wanted an Arcade expression that would iterate through my temporal data, and generate a color-coded table for each year, as seen above. I also wanted the code to work for any dataset, without having to make significant modifications.

The full resulting Arcade expression is at the bottom of the article (along with a shout-out for the Product Engineer who inspired this), but let me walk you through what is happening and how to make this work in your own map.

Getting Started

We start with the data. In my example, I'm using some temporal data from CDC on Lyme Disease incidence rates from 2010-2019. The schema is simple to work with:

NamePopulationF2010F2011F2012...
Maine132836142.1060.3066.60

 

Once this layer is added to Map Viewer, we select the layer from the table of contents and select the + Add content option. Here we see a new option for Arcade. Now is where the fun begins.

MikeSchoelen_1-1640793025475.png

The Inputs

The script is written for users to give four inputs:

  1. The labels for the table as an array.
    For example: ["2010","2011","2012","2013"]

  2. The fields of the dataset that align with the labels.
    For example: [$feature.F2010,$feature.F2011,$feature.F2012,$feature.F2013]

  3. The color ramp and data classification breaks that you'd like your data to follow. While this seems complex at first, the expression is only asking for a data range and the corresponding background color of the block. You can get color ramp values that match your map from this webpage.
    For example with the line: yearinput<= 10 && yearinput> 5, "#c8e7ff", data values between 10 and 5 will be assigned a background color of #c8e7ff. You only need to change the underlined content.

  4. Similarly, the next function changes the color of the text itself, with white text on dark colors, and black text on light colors. Sections 3 and 4 should correspond with each other. 
    For example: yearinput<= 10 && yearinput> 5, "black"

Depending on the classification of your colors, you can add and remove lines from these functions, as necessary. 

But that is it! The Arcade script handles the rest. It will count the number of categories and design a table divided into equally spaced sections. Then it applies the labels at the bottom of the table. 

The result is a bar that is data-driven and can be surrounded by other blocks in the popup, like text, charts, and tables.

MikeSchoelen_0-1640792547342.png

It can even be added as a piece within other HTML content:

MikeSchoelen_0-1640793476104.jpeg

 

The full expression

 Here is the full expression for you to modify:
(Note: This expression was updated on 31 DEC 2021)

 

 

// Define the years of the timeline.
// The script will iterate through this array
var yearsArray = ["2010", "2011", "2012", "2013"];

// Define the matching fields containing the values
var valuesArray = [$feature.F2010, $feature.F2011, $feature.F2012, $feature.F2013];

// Specify the colors and corresponding value ranges in the color ramp
// For HEX values matching ArcGIS colors, visit: https://developers.arcgis.com/javascript/latest/visualization/symbols-color-ramps/esri-color-ramps/
function computeCellBackgroundColor(yearValue) {
  var color = When(
    yearValue < 5,
    "#f5ffff",
    yearValue <= 10 && yearValue > 5,
    "#c8e7ff",
    yearValue <= 15 && yearValue > 10,
    "#9bd0ff",
    yearValue <= 20 && yearValue > 15,
    "#6db8ff",
    yearValue <= 25 && yearValue > 20,
    "#40a0ff",
    yearValue <= 30 && yearValue > 25,
    "#3b94eb",
    yearValue <= 35 && yearValue > 30,
    "#3687d7",
    yearValue <= 40 && yearValue > 35,
    "#307bc3",
    yearValue <= 45 && yearValue > 40,
    "#2b6eaf",
    yearValue <= 50 && yearValue > 45,
    "#2968a5",
    yearValue <= 55 && yearValue > 50,
    "#26629b",
    yearValue <= 60 && yearValue > 55,
    "#245b91",
    yearValue > 60,
    "#215587",
    "grey"
  );

  return color;
}

// Define the color of the text in each cell, based on the background color
function computeCellTextcolor(yearValue) {
  var color = When(
    yearValue < 5,
    "black",
    yearValue <= 10 && yearValue > 5,
    "black",
    yearValue <= 15 && yearValue > 10,
    "black",
    yearValue <= 20 && yearValue > 15,
    "black",
    yearValue <= 25 && yearValue > 20,
    "white",
    yearValue <= 30 && yearValue > 25,
    "white",
    yearValue <= 35 && yearValue > 30,
   "white",
    yearValue <= 40 && yearValue > 35,
    "white",
    yearValue <= 45 && yearValue > 40,
    "white",
    yearValue <= 50 && yearValue > 45,
    "white",
    yearValue <= 55 && yearValue > 50,
    "white",
    yearValue <= 60 && yearValue > 55,
    "white",
    yearValue > 60,
    "white",
    "grey"
  );

  return color;
}

// NO USER MODIFICATION BELOW THIS LINE!

// Build the style string for the top cell
function buildTopCellStyle(width, textColor, backgroundColor) {
  var cellStyle = 'style="';
  cellStyle += "text-align:center;";
  cellStyle += "font-size:24px;";
  cellStyle += `width:${width};`;
  cellStyle += `background:${backgroundColor};`;
  cellStyle += `color:${textColor};`;
  cellStyle += '"';
  return cellStyle;
}

// Cell width in percent based on how many cells we have
var cellWidth = `${floor(100 / Count(yearsArray))}%`;
console("The width of each unit will be " + cellWidth);

// Assemble the top and bottom cells by iterating thru the years
var topCells = "";
var bottomCells = "";
for (var index in yearsArray) {
  console("Building div for year " + yearsArray[index]);
  console("The year value is " + valuesArray[index]);

  // Assemble the top cell
  var value = valuesArray[index];
  var topCellTextColor = computeCellTextcolor(value);
  var topCellBackgroundColor = computeCellBackgroundColor(value);
  var topCellStyle = buildTopCellStyle(cellWidth, topCellTextColor, topCellBackgroundColor);
  var topCell = `<td ${topCellStyle}><b>${value}</b></td>`;
  console("Adding the following cell to the top cells" + topCell);

  // Assemble the bottom cell
  var bottomCell = `<td style="text-align:center;">${yearsArray[index]}</td>`;
  console("Adding the following cell to the bottom cells" + bottomCell);

  // Assemble to the top and bottom cells
  topCells = topCells + topCell;
  bottomCells = bottomCells + bottomCell;
}

var table = '<table style="width:100%;">';
table += `<tr>${topCells}</tr>`;
table += `<tr>${bottomCells}</tr>`;
table += "</table>";

return {
  type: "text",
  text: table
};

 

 

And a shout-out to @DaveNyenhuis for inspiration. He created a Dashboard list format that operates in a very similar fashion! And a shout out to @FredericAubry for the assistance with formatting and best practices!

MikeSchoelen_1-1640793673471.png