How to Add A Legend to the Esri Story Map Tour App

hands on a small map and a compass

When Esri released the Story Map templates, they became one of the hottest things in the GIS community. They offered a variety of templates, including the Map Tour. I used this template to create an interactive map guide to a popular water trail in our community. One component that was always missing was a legend.

Recently, I figured out how to use the Esri JavaScript API to add this component to the map. In this article, I’ll walk you through that process. You can see this solution in action by viewing this map.

View the code on GitHub

It is important to note that the Story Map Tour template is now considered part of the “Classic Story Maps.” These, along with other products, are built on the 3.x version of the ArcGIS JavaScript API. Esri is focusing development on products using the 4.x version of the API. But if you’re planning on supporting the Classic Story Maps for a while, then I hope you’ll find this guide useful.

Setting Up File Structure

We are going to start by adding a couple files to the project:

  • custom-style.css => place custom CSS rules
  • custom-script.js => place code to build map legend

Both of these files will be placed within the app/ directory of the project. Within the index.html file, there are the loadCSS and loadJS functions, which we’ll use to load our custom-style.css and custom-script.js files.

Around line 124 of index.html, we’ll add the following line to load our custom stylesheet:

loadCSS("app/custom-style.css");

Around line 1251 of index.html, we’ll add the following line to load our custom Java Script file:

loadJS('app/custom-script.js');

The next step is to create our HTML elements that will contain the legend, as well as let the user show/hide the legend.

Adding Legend Markup

We’ll add a button element that is located on the top-left of the map, near the zoom controls. When users click on this button, it will either show or hide the legend. We’ll also add a up/down icon, to help the user understand what the button does.

screen shot of a story map with legend
Map Tour with legend component

Near line 320 in index.html, we’ll add the following code inside of the <div=”mapPanel”> element, but before the <div id=”mainMap”> element:

<!-- Custom Map Legend -->
<div id="legendContainer">
   <!-- users click on button to open/close legend -->
   <button id="toggleLegend">Legend   <i id="legendBtnState" class='fa fa-arrow-down'></i></button>
   <!-- container for indiviual legend elements -->
   <div id="legendDiv"></div>
</div>
<!-- ./ Custom Map Legend -->

The Map Tour application includes Font Awesome, so we’ll use that library to display our up/down arrows.

There are a few CSS rules I’ve developed for these HTML elements. But rather than list them here, please see the custom-style.css file on GitHub.

Creating the Legend Component

I’ve had the opportunity to add custom JavaScript code to a few of the Esri Story Map templates. There are multiple “developer extension events,” which are places to hook your custom code into the application. I’ll admit it can be tricky to know which event to hook into.

In our custom-script.js file, we’ll add the following code, using guidance from the Developer Guide from Esri for the Story Map Tour.

require(["dojo/topic"], function(topic) {

   // The application is ready
   topic.subscribe("maptour-ready", function(){
   
   }); // end maptour-ready

}); // end require statement

The majority of the code to add the legend will be placed within the maptour-ready event. But outside of that event, we’ll create some variables to reference HTML elements for the button that will be clicked to open/close the legend, as well as the up/down arrow.

// legend toggle button element
const legendToggleBtn = document.getElementById('toggleLegend');
// legend toggle arrow icon element
const legendToggleIcon = document.getElementById('legendBtnState');

At the very end of the maptour-ready event, we’ll add the following code to change the display of the legend button from none to inline-block after the Story Map loads.

// show legend toggle button on "desktop" view after app loads
if (!document.body.classList.contains('mobile-view')) {
   legendToggleBtn.style.display = 'inline-block';
}

To create the map legend component, we’ll need to gain access to the webmap object of the Story Map application. We’ll also need to use the ArcGIS JavaScript API’s require statement to add the esri/dijit/Legend component. We’ll create a map legend object, and then call its startup function to initialize it. When constructing the legend, we’ll specify which webmap we’re working with, as well as what DOM element we want to place the legend within. All of the code to create and control the legend will go within the maptourready event.

// load Esri JS API modules
require(["esri/dijit/Legend"], function(Legend) {

   // web map object
   const webmap = app.map;

   // legend object
   // see https://developers.arcgis.com/javascript/3/jsapi/legend-amd.html
   const mapLegend = new Legend({
      map: webmap
   }, "legendDiv");

   // Finalizes the creation of the legend . Call startup() after creating the widget when you are ready for user interaction.
  mapLegend.startup();

}); // end require

Now that we have created the legend, we need to add the function that opens and closes the legend. Initially, the legend is closed. We will connect a “toggle” function to the button element that will open or close the legend, as well as change the arrow icon between up/down. This icon was added by the client to help users understand that the button open/closes the legend.

// toggle dispay for map legend when user clicks on <button id="toggleLegend"> element
function toggleMapLegend() {
   // container for map legend
   const mapLegend = document.getElementById('legendDiv');

   // toggle visiblity
   if (mapLegend.style.display === 'none' || mapLegend.style.display === "" || mapLegend.style.display === " ") {
      // show legend
      mapLegend.style.display = 'block';

      // change legend toggle icon
      if (legendToggleIcon.classList.contains('fa-arrow-down')) {
         // remove down/open arrow
         legendToggleIcon.classList.remove('fa-arrow-down');
      }

      if (!legendToggleIcon.classList.contains('fa-arrow-up')) {
         // add close/up arrow
         legendToggleIcon.classList.add('fa-arrow-up');
      }
   } else {
        // hide legend
        mapLegend.style.display = 'none';

        // change legend toggle icon
        if (legendToggleIcon.classList.contains('fa-arrow-up')) {
           // remove down/open arrow
           legendToggleIcon.classList.remove('fa-arrow-up');
        }

        if (!legendToggleIcon.classList.contains('fa-arrow-down')) {
           // add close/up arrow
           legendToggleIcon.classList.add('fa-arrow-down');
        }
     }
} // end function

// add event listener for "click" event
legendToggleBtn.addEventListener('click', toggleMapLegend);

Now, we have customized the Esri Story Map Tour application to have a toggable map legend. You can view sample code at my GitHub repository.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s