How to make location-aware Tableau dashboards

In the great book Made to Stick by Chip and Dan Heath, they have a great story about a local newspaper in a small town that says they would literally print names from the phone book if they could. They know that when people see their name, or the name of someone they know, there is an emotional attachment that gets the reader to care about the content. The same is true in data-viz land.

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

One lesson I learned a long time ago was that we are all vain when it comes to data viz. Generally, we all care more when a data viz is about us. I’ve seen this over and over again at clients when I build the famous “me” dashboard which shows an employee's relative tenure compared to others in the company.

Of course, this isn’t my revelation. In the great book Made to Stick by Chip and Dan Heath, they have a great story about a local newspaper in a small town that says they would literally print names from the phone book if they could. They know that when people see their name or the name of someone they know, there is an emotional attachment that gets the reader to care about the content. The same is true in data-viz land.

So recently, when I was doing a Makeover Monday on corporate tax havens, I thought, what better way to get people to care than to make it personal? What I wanted to do in this viz was have it automatically detect the reader's location and filter to his or her state.

This is the most basic, straightforward way to do this I have found (keeping it simple was another one of the Made to Stick rules).

For this to work you’ll need:

  1. A viz with some location property you want to filter on
  2. A website to host the viz
  3. A few lines of JavaScript (which has nothing to do with Java, so don’t worry :))

First, we need a viz

  1. Create a viz
  2. Add a “State” parameter
  3. Create a calc that uses the State parameter to filter the viz

Next, a site to host it

I use WordPress, but wish I was using Jekyll (le sigh).

If you don’t have your own site, you can use codepen.io and that’s also where you can find my code.

Last, some JavaScript

If you’ve never written JavaScript before, have no fear! It’s one of the most common and relatively easy to understand, albeit rather ugly, programming languages. It really is the language of the web, and today, it has extended beyond just web pages into server-side programs using node.js. First, an analogy to clarify one thing about JavaScript: Java is to JavaScript as ham is to hamster.

If you don’t care about learning how this works, you can copy paste my code below into your site and simply replace the variable values with your own. If you are a curious mind, which I know you are, then read on.

The basic idea here is to:

  1. Ping a remote service from the reader's web browser to get the location
  2. Parse the response containing the location information
  3. Use the reader's location to localize our viz

So on your page, first you’ll want to include the JavaScript framework JQuery if it’s not already included. Do that by adding the following reference to JQuery in your <head> tag:

<script src="https://code.jquery.com/jquery-3.1.0.js">

On our web page, in the HTML <body>, we’ll need to add some objects to contain our location information. These are all for testing except the <iframe> which is where the actual Tableau viz is loaded. So if you don’t want to see all of that, go ahead and remove it. I personally like to have it there while I’m developing, then when I publish I remove it.

<h3>Client side IP geolocation using <a href="http://ipinfo.io">ipinfo.io</a></h3>
<hr/>
<div id="ip"></div>
<div id="address"></div>
<div id="locationChoice"></div>
<hr/>Full response: <pre id="details"></pre>
<!-- this is the iframe that will hold the viz -->
<iframe id="viz" frameborder="0" marginheight="0" marginwidth="0" allowtransparency="true"></iframe>

Next, we want to setup some variables to store the values we’ll need to load the viz. In JavaScript, we need to first start out with a <script> tag that will contain all of our code. Then we’ll add the variables and assign them values.

  // TODO: enter your viz URL, parameter name, and geo-level of the parameter.
  // JavaScript is case sensitive, enter the paramLevel exactly as described
  var vizUrl = "https://public.tableau.com/views/LocationAware/viz"
  var vizParam = "StateFilter"
  var paramLevel = "region" //city, region, country, postal
  var size = ["100%", "900"] // width, height in double quotes

  //WARNING: don't change this
  var vizUrlSuffix = "?:embed=y&:showVizHome=no&:hoswidtt_url=https%3A%2F%2Fpublic.tableau.com%2F&:tabs=no&:toolbar=yes&:animate_transition=yes&:display_static_image=no&:display_spinner=no&:display_overlay=yes&:display_count=yes&:loadOrderID=0&"

Notice that paramLevel specifies the geographic role of the parameter we want to pass in. This is important, and you can only use the values in the comments there, exactly as typed.

Now let’s make the request to the geolocation service and get our reader's location. We do this using a JQuery function $.get(). This function basically makes a request to the URL we provide and then parses the response into an object/variable called “response” which we specified in the what is known as a “callback." (Thanks to ipinfo.io for its support!)

//This part gets the location and updates viz with the location parameter
$.get("http://ipinfo.io", function (response) {

$("#ip").html("IP: " + response.ip);
$("#address").html("Location: " + response.city + ", " + response.region);
$("#locationChoice").html("location choice: " + response[paramLevel]);
$("#details").html(JSON.stringify(response, null, 4));

//this part gets the viz and updates the iframe
$("#viz")
.attr("src",vizUrl + vizUrlSuffix + vizParam + "=" + response[paramLevel])
.attr("width", size[0])
.attr("height", size[1])
.style("display: block; margin: 0px; padding: 0px; border: none; width:"+size[0]+"; height:"+size[1]);

}, "jsonp");
</script>

Now we’re ready to test our viz! Make sure your HTML document has closing tags for the </body> and </html> elements and you are ready to open it in a web browser and test. If you don’t have a web server to use, try using Firefox locally and just opening the file. Sometimes browsers block local access so if you want to do this in Chrome or others, then you might need to adjust the security settings.

Here is the full code of our page. Feel free to reuse this without any attribution in any manner you wish. The simplest way is to just copy/paste this entire snippet into a page and replace the parameter values to fit your needs.