Quick "Hackathon" Release - Tableau Flow Maps

Hey, I'm alive. It's been a bit too long since I've posted here, but 2022 was an amazingly productive and eventful year...

It's been.... quite a year. More on all that soon, I'm working on a 2022 retrospective and will go into depth on those topics (c'mon, it's really an excuse to talk about all things Rabbit).

This post is about a quick < 2 week side project I undertook in order to clear my head from some of the other side projects that have been kicking around (CanvaSQL was a break from Rabbit dev, and this was a break from CanvaSQL dev, lol) as well as address something that had been vexing me in my day job toolchain...

2014 Tableau Conference - feels like 3 lifetimes ago

Tableau. Love it or hate it, it's a thing.

A pretty damn useful thing actually. I have a long history with it and the company, but that's a story for another day...


Cost concerns and recent BigCo ownership drama aside, it can get you very far in terms of Business Intelligence Reporting. Easy to learn, a high ceiling to master, and you can build a great many divergent and impressive things with it.

But that kind of flexibility has some trade-offs.

Something that has always bugged me, but I could never quite put my finger on it, is it's ability to create a very unique form of exceedingly opaque cascading spaghetti logic - due to the nature of it's user facing interaction systems and how they weave together.

Let's take a look at these 3 "systems" real quick so I can explain myself...

Dashboard actions

Dashboard actions allow you to make any graph/widget (worksheets in Tableau speak) an event source for an arbitrary number of other worksheets.

This is actually pretty awesome and makes creating context action / intuitive feeling UI designs super easy. i.e. User clicks on the bar for "North America Region" you can then filter everything else to only show "North America" Sales data, etc.

**It's implemented with regular boring UI dialog boxes and not any kind of cool interactive "direct manipulation" style like I would try and design - but I'm getting off topic...
Setting up a dashboard action filter, with these exciting dialog boxes that make it super easy to understand the relationships between sources and targets as they relate to the visual dashboard. Not!

Parameter Mutation

Another lever that you have are your disposal for user interactions is via Parameters (which are essentially global variables). Commonly (in these scenarios) they are:

  1. Presented as a hardcoded UI input dialog to the user (free form text, drop-down, radio button, etc) - interacting with this input changes the parameter in turn executing any Tableau calculations that use it.
  2. Via a special Dashboard action that takes the worksheet input and instead of sending it to other worksheets as a filter or a conditional highlight - will mutate a specific parameter with the specified field value - this in turn causes a cascading execution of any logic that users it like above.
Here we see the "Commission Rate" parameter as an input float slider - its value is used in the calculation of several other things in this dashboard. But where is it used? Which ones?From this view - who the fk knows!

Individual Worksheet Filters on a dashboard

Last but not least we have worksheet filters. But unlike Dashboard Action Filters we talked about above - they are unconcerned with the context of the dashboard and it's contents.

Worksheet filters can be for single worksheets, multiple worksheets, entire data sources, or all linked data sources - and none of this has anything to do with the dashboard itself. The dashboard is merely a container here and the logic is elsewhere.

Here we see the "Year" dropdown filter on the right. It's actually a child filter for the top graph, but since they share that field as a filter on their respective worksheets it controls all 3 - but you'd be hard pressed to see that unless you clicked around a bit or went back to the worksheet to examine the filter config...
Jumping to that top worksheet the filter came from, I can now see that the "Year" filter is configured to also control these other worksheets - but remember this logic is independent from the dashboard itself...

Ok, now that we've got that out of they way - I'm sure you can smell the punchline from a mile away...

Your Dashboard Logic - Now Fully "Complected"!

COMPLECT. From Latin complectī (“to entwine, encircle, compass, infold”), from com-(“together”) and plectere (“to weave, braid”). See complex.

These 3 interwoven systems provide the dashboard creator a flexible palette to craft the data-interactive user experience of their dreams, no? Well, kind of - but possibly at the cost of braiding all those things together accidentally.

In a complex dashboard - the problem is that we now have several systems with direct AND indirect actions (of the 1st and 2nd orders) occurring - that for all intents and purposes need to be reasoned about in the developers head in order to keep them straight. This is the only place the holistic interaction model really exists.

This can be compounded when coming back to a dashboard after many months to fix a bug, make a change - or maybe even transferring ownership over to someone else. Explaining the "action cascade chain" in a document can be arduous and not as useful as you'd think. They almost have to step through all the objects and unpack them in their head to "see" it.

Cognitive Overhead Tech Debt or Incidental Complexity?

Zooming out - there is no easy way inside Tableau to see these relationships all at once. Which ones cascade into others, which ones clash, etc. Not to mention asking "What If" questions, like:

"If my user interacts with Worksheet X on dashboard Y show me ALL the  relevant things that happen behind the scenes"

I spent some time sketching out how I could make this kind of logic more "observable" in a small UI viewer. Which is always a cool exercise - because it forces you to ask the question:

"Well, what is actually important?"

A question which is much more enlightening than a laundry list of things that you want to surface. Mission oriented, so to speak.

Some of the sketches and notes from the project trying to figure it out before any code was written. Note - all are much more complex than the finished product, since the complexity didn't add enough visual "user value" to justify the extra dev time.

Lots of graph paper and Clojure later...

Enter the "Tableau Flow Maps" viewer...

After that large prelude / problem statement, I almost don't even have to explain what it does. Ah ha!

It reads in your Tableau workbook file (not the packaged TWBX archive, just the base TWB file) and presents one flow map for each dashboard. It's a fairly simple "boxes and lines" style UI that is all about relationships.

A colorful loom of downstream actions and filters

There are 3 columns:

  • Inputs - source worksheets, filter widgets, parameters (ones used explicitly and implicitly via parameter actions)
  • Actions - the literal configured dashboard actions that some of these reactions flow through / were created by
  • Outputs - the target worksheets on the dashboard that react to the inputs

Clicking on any of the boxes will show upstream and downstream items involved (including indirect / implied ones - which are probably the most invisible ones in the native Tableau UI).

Here we can see that clicking on the "Simple Graph" worksheet will not only cause a Highlight action on all 4 worksheets - but also will change a parameter which in turn will cause the bottom 3 worksheets to re-render as well...

Give it a try with your Tableau TWB files here, or run it locally from the release binary (JAR file).