How to auto-generate 50 state maps in Tableau

Recently I fell in love with the small-multiples types of graphs that show each individual state level metrics separated into a grid-style layout. Being the data hacker that I am, I decided to use my rusty JavaScript skills to auto-generate 50 individual state-level maps from one Tableau viz.

Note: The following is a guest post by Tableau enthusiast Ben Sullins.

Recently I fell in love with the small-multiples types of graphs that show each individual state level metrics separated into a grid-style layout. Being the data hacker that I am, I decided to use my rusty JavaScript skills to auto-generate 50 individual state-level maps from one Tableau viz.

Here's how I did it:

  1. Build a Tableau viz with a map of the United States (or whichever country you wish)
  2. Use JavaScript to generate an image for every state from that Tableau viz
  3. Place these images on a page and style accordingly so they are responsive to the user’s screen size

1. Build a Tableau viz

Here what I’ve done is take the regional view that comes with the Tableau Desktop samples. It shows obesity rates for every county in the US. Once we have this, we really are done with Tableau at this point. Simply publish this to Tableau Server or Tableau Public and move on to the next step.

2. Use JavaScript

Before we dive in here, remember what master Yoda says about the force of JavaScript:

“You must unlearn what you have learned” – Yoda

Steps:

  1. Get a list of states for which we want to generate maps
  2. Pass these states into Tableau via the URL to filter the viz
  3. Load these images on to our page

So let’s begin. Get a list of states. For this, I went into my Tableau viz, dragged State on the Rows shelf, then exported the data. In Excel, I created a formula to put each state in quotes with a trailing comma, and pasted that into my codepen

var states = [
'Alabama',
'Arizona',
'Arkansas',
'California',
'Colorado',
'Connecticut',
'Delaware',
'Florida',
'Georgia',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Ohio',
'Oklahoma',
'Oregon',
'Pennsylvania',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming'
];

Now that we have our list of states, we need to call Tableau and pass this in as a filter. This can be done a few ways, but for our purposes, I wanted to keep it simple and just use a “for loop." This is a basic concept in nearly every programming language that allows you to execute a piece of code repeatedly until the “for” condition is met. More on that here.

for (i = 0; i < sortedStates.length; i++) { 
      //parse the array of states and assign the current state
      var state = sortedStates[i];
      //get the url of our viz with the state filter added
      var url = "https://public.tableau.com/views/Regional_207/map?:showVizHome=no&:embed=yes&:toolbar=no&:format=png&State="+state;

       //add some HTML to load the image into our "tiles" container
      $("#tiles").append("<div class='tile' style='opacity:0;' id='tile-"+i+"'><span class='tile-title'>"+state+"</span><img src='"+url+"'><div class='cover'></div></div>");

    };

In this snippet above, we’re looping through our list of states one at a time, parsing the individual state, generating a URL, then adding an image to the “tiles” container where we’ll house our final result.

When we added the images to our page they had an opacity of 0, which makes them invisible. This is so we can control the loading of images on the page and make it more smooth for our users.

$('#tiles').imagesLoaded()    
  
    //when the loading is complete do this
    .done( function() {

      //set the "opactity" to 1 which makes the tile visible
      $(".tile").each(function() {
        $(this).fadeTo("slow",1);

      });
})

This function above is executed after the previous loop is completed (which adds all of the images to the page) and simply fades the tiles to be visible. This section uses another JavaScript library named imagesLoaded and can be found here.

The last step is to wrap this whole thing up in a function and call it. This isn’t totally necessary, but in following with common JavaScript form, I thought this would be nice. If we wanted to do anything more advanced like add a callback function after everything is done, we could do so using this structure.

//run this baby
loadImages(sortedStates);