Published on

How to Create a Responsive KPI Dashboard with the Tableau JS API

Authors

Our Goal

To create a responsive grid of dashboards. The dashboards will be created in Tableau, hosted on Tableau Server and embedded via the Tableau JS API. This allows us to leverage the best of both worlds #winwin

With Tableau we can quickly create great visuals and by leveraging the APIs developed by the Tableau team we can use the latest web tech to display our work in a more delightful way.


Prerequisites

This tutorial could be written using Tableau Public instead of Tableau Server, but I want to provide you with a walk through that’s more production ready. While the refactoring needed to use Tableau Public is not extensive it’s still there and I don’t want you to miss out because you didn’t have this POC working against a non-Public instance.

Tableau

We need the real deal Tableau Desktop and not Tableau Public for this example so you can publish to a Server other than Tableau Public.

Tableau Server

If you don't have a Tableau Server to experiment with, you can get your own free, development environment by signing up for the Data Dev Program.

If you do have a Tableau Server to experiment with I would recommend either publishing this dashboard for this example to the Default project or a Sandbox project so you avoid confusing anyone.

Chrome or Firefox

I would encourage you to use Chrome in the off chance you aren't already, but you can also use Firefox.

Visual Studio Code

VS Code is a fantastic text editor. There are heaps of benefits from working with VS Code. Any screenshot taken of my editor will be of VS Code. Apologies in advance if you’re envious of the editor setup I have. It’s been heavily customized.

Node

Node is what allows us to execute the scripts locally to see how our code is coming along. We also need Node in order to install all of the dependencies for our application.

React Dev Tools

This is an optional install, but one you’ll want is you’re planning to do any future React development. The React Dev Tools allow you to see the State of your application from React’s perspective, which is different from how the Browser see it. This extremely helpful when debugging and/or optimizing your React code base!


Step-by-step

Get Inspired

KPI Designs

A fun way to kick off any creative pursuit is with a jaunt through Dribbble, Behance, or another platform showcasing the best styles of today's designers. So, take a minute to browse. Educate yourself by seeing how other creatives are approaching a similar design challenge by searching for “Grid Layout” or “Dashboard KPIs”.

Code Examples

If you'd like to see examples of the code behind the designs, a good place to go is Code Pen. Like any good site with content worth browsing, you could search for "Grid Layout” at the top and pull back page after page of examples.

If you find an example you like in Code Pen you can dive deeper by following up with a search on CSS Tricks. The folks that post there are top-notch, cutting edge devs. This means some of what they say may be over our heads, but they know this fact and a, therefore, no stranger to explaining concepts to newbs 👶


Setup

Tableau Dashboards

Who else but Andy Kriebel to supply us with the perfect example? Here is a link to the Twitter thread that inspired me to create this tutorial. And here’s an example I’ve modified to make this walk through easier for you.

So, go ahead and download my modified workbook and publish the dashboards to your Server.

Development Environment

Let start by creating a directory (or folder) on your computer to put all of our code.

Create new folder

Create new folder

Make sure the folder’s name is all lower case without any spaces.

I’m going to give my folder the name of “responsive-grid-example”.

Next we’ll want to open that folder from VS Code.

Open folder in VS Code

Open folder in VS code

Now we’re going to run "npx create-react-app ." from the terminal.

This will create all of the boilerplate code we need to get started.

Create React App

Create React App

Once all of the packages are successfully installed you should see text that reads “Happy Hacking!”.

That’s your cue to start the React application to make sure all is well.

To do this run “npm start” in the terminal.

Start the React App

Start the React App

After everything loads up, your browser will open and display the spinning React Logo.

With everything up and running we need to do a little clean up. Running “create-react-app” installs more than this example requires.

Let’s clean that up so that we’re starting fresh.

At this point we’re ready to begin writing our own code.


JavaScript

Add the Tableau JS API to the index.html file

Insert Script Tag

Insert Script Tag

<script src="https://us-east-1.online.tableau.com/javascripts/api/tableau-2.min.js"></script>

Create a components folder within the src folder and create a Grid component file there.

Create a components folder

Now collect all of the embed links from your dashboards to create create an array of link. This array or urls will be assigned to the constant “dashboards” in your Grid.js file.

Collect the share links and create an array of strings out of them

The array should look like this when you’re done…

const dashboards = [
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi1',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi2',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi3',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi4',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi5',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi6',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi7',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi8',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi9',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi10',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi11',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi12',
]

You'll just want to make sure you replace the text in front of "/views" with your own server name and remove all of the text to the right of and including the “?”.

Now import the Grid component into your App component.

Import Grid into App

Now create a Card component in the same folder as your Grid component.

Create your Card component

The code will look like…

import { useRef, useEffect } from 'react'

const { tableau } = window

export default function Card({ dashboard }) {
  const ref = useRef(null)

  useEffect(() => {
    const viz = new tableau.Viz(ref.current, `${dashboard}`, {
      hideTabs: true,
      hideToolbar: true,
      width: '290px',
      height: '180px',
    })

    return viz
  })

  return <div ref={ref} />
}

Now we need to update our Grid component to import our Card and render a single dashboard.

Now that we’ve displayed a single dashboard, we can step it up to map over all of the dashboard urls in our array. This will create a Card component for each element of the array.

The code will look like…

import Card from './Card'

const dashboards = [
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi1',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi2',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi3',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi4',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi5',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi6',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi7',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi8',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi9',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi10',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi11',
  'https://10ax.online.tableau.com/t/developmentonlydev595736/views/SocialMediaKPIs/kpi12',
]

export default function Grid() {
  return (
    <>
      {dashboards.map((dashboard) => (
        <Card dashboard={dashboard} />
      ))}
    </>
  )
}

Now that we’re rendering multiple Card components we need to give them each a unique id so React can keep track of them. We’ll do this with UUID.

Let’s install the package.

Setup UUID

And with that we can see that each of our Cards has a unique id in its key prop

Inspect the unique IDs

CSS

The next step is to layout the Cards in a grid.

For this we need to install another package, style-components.

Setup styled-components

We’re aaalmost ready to implement our layout, but first I’m going to add a styles folder and create a GridStyle.js file.

Create a GridStyle file

Here’s the GridStyle.js code:

import styled from 'styled-components'

const Grid = styled.div`
  display: grid;
  max-width: 1100px;
  margin: auto;
  grid-gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
`
export default Grid

Now we can apply the style by importing it into the Grid component.

Import the GridStyle

Now let’s do the same for our Card.

Here’s the CardStyle code:

import styled from 'styled-components'

const Card = styled.div`
  margin: auto;
  padding: 16px;
  border-radius: 5px;
  box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
`

export default Card

And that’s that! You now have a responsive array of cards being pulled from Tableau Server.

Responsive Grid

Congratulations 🥳 You now have a very useful component you can incorporate into larger React applications or build off of this project. I’ll share a few ideas of how you and I might build off of this project.

If you’d like to clone the code to pull down the finished project, have at it GitHub


In case things didn’t work out for you…

Taking Things Further

  • Create a responsive grid out of the KPIs in this P&L Dashboard.
  • Pull the list of dashboards through via the JS API instead of creating a hardcoded list.
  • Create a nice header and footer for this page
  • Add card titles with fonts you don't have access to within Tableau
  • Create a modal pop out when a user selects one of the dashboards from the Grid
  • Deploy your code so others can see what you're created

Thanks for reading! Hit me up on Twitter or LinkedIn for more direct questions or feedback 👋