Decorate Your Own Tree – A Walkthrough

Hello!

I had rather a good reaction for my latest fun viz – decorating your own Christmas tree in Tableau! So much so that I thought I would write a little blog walking through how I made it:

I am primarily using Parameters, Transparent Layers and Map Layers for this viz, and a lot of the concepts here are similar to the Bob Ross viz I did a while back – although you will be pleased to hear this one is simpler!

So here goes nothing:

Draw a Tree

This was the simplest bit – get the shape of a tree! I did this in Figma using just 4 triangle shapes with rounded edges. For now I didn’t do the base as I only want the user to be able to select the tree when interacting:

Then with the four triangles selected – I grouped them and exported as a png file.

Tree done!

Get Some Coordinates

I used the ever trusty automeris tool following CJ Mayes method, to get 999 points plotted in the shape of a tree. This provided me with a list of X and Y coordinates, which I then also added a unique ID to:

Coordinates done!

Plot those Coodinates

So now I have my data, I am going to plot them in Tableau. This is where it differs a bit from the Bob Ross viz as I will be using Map layers to do this.

First I need a calculated field called ‘Tree Dots’:

TREE DOTS: MAKEPOINT([X]/1000,[Y]/1000)

This is a ‘Make Point’ function that will convert my X and Y coordinates into a map coordinate. Also because Latitude and Longitude have set limits (-90 to 90 and -180 to 180 respectively) I need to reduce the values in my data set so that they will fit on a map. As my data is static I can use a random large number to do this – I chose 1000.

I can then drag this calculation onto the canvas, and I will do it three times (to make sure Tableau knows this is a map-layer viz when we change it later). I will ‘flip’ the axes, add ‘ID’ to the detail shelf (so all marks are shown) and finally reverse the Y-axis so that the tree is the right way up:

We will format this later – but that is the basic tree in Tableau – Done!

Add some Bling

Now we need to be able to put decorations on the tree! I am going to have three types: Baubles, Tinsel, and Toppers and I will use a map layer for each of these. I will walk through setting up the ‘Bauble’ layer as the other two work in exactly the same way.

First the set up, I need to have a number of parameters and calculations set up to work this.

pType is the parameter I will use to determine which type of decoration to place.

pBauble is used to determine which Bauble colour is placed.

pBaublePosition is the parameter that will hold ALL the positions of the baubles the user has placed. It starts out as blank as there is nothing on the screen – as the user adds Baubles I will add to this string with the format:

‘{‘ [ID] ‘}’ [pBauble] ‘~’

ID is placed in between curly brackets so we can easily search for it, and pBauble denotes the type of Bauble. The ‘~’ at the end serves to split up the elements. An example with two baubles could be:

{134}Bauble3~{165}Bauble3~

Next we need some lovely string calculations.

BaubleType:

if contains([pBaublePosition],'{'+ID+'}') then mid([pBaublePosition],FIND([pBaublePosition],'{'+[ID]+'}')+len('{'+[ID]+'}'),7)
end

This calculation is to decide what Bauble type should be at each point (and null if none) by searching for the ID of the point in the pBaublePosition parameter, and pulling out the bauble type next to it. I have made sure all of the Bauble Types will be 7 characters in length so I can hard code as 7 in the above.

XBauble

if contains([pBaublePosition],'{'+[ID]+'}') then [X] end

This basically makes a point if an ID exists in the pBaublePosition parameter, and leaves null if not.

BaubleUpdate

if [pType] = 'Bauble' then
if contains([pBaublePosition],'{'+[ID]+'}') then
replace([pBaublePosition], '{' + [ID] + '}' + [pBauble] + '~',"")
else [pBaublePosition] + '{' + [ID] + '}'+[pBauble]+'~'
end
else [pBaublePosition]
END

This is the calculation we use to pass to the pBaublePosition parameter – so updating the data when a user clicks a point.

It first checks if ‘Bauble’ has been chosen as the main type. If so, then it checks if the current ID already exists in the parameter – if it already exists then it will replace the entry with a blank (therefore removing the bauble from the tree). If it doesn’t exist – then it adds the ID and Bauble Type to the end of the parameter string.

With these in place, we can then make the basic functionality work.

First rename one of the other map layers to be ‘Baubles’. Add ID and BaubleUpdate to detail, and BaubleType to shape. Then in the shapes legend, you set the ‘Null’ values to be a transparent shape, and the other types to be the images you want displayed:

Here you can see the baubles appearing where they exist in the parameter, but everything else hidden. We will format this better later!

Next we want to set up a parameter action so we can actually change things on the tree. This is pretty straightforward and looks like:

This runs from the sheet your tree is in, and will pass the ‘BaubleUpdate’ value into the pBaublePosition parameter – this will either add a bauble to the list or remove if you have clicked for a second time:

To test this out you need to do a couple of things. Add ‘BaubleUpdate’ to your ‘Tree’ layer, and disable selection of the ‘Bauble’ layer on the worksheet. Then you can try the action out:

Here you can now see the red baubles appearing on the tree! What did we actually do:

Disabled selection of the ‘Baubles’ layer – this means you can only select the ‘Tree’ layer and there is no confusion.

Added ‘BaubleUpdate’ to the ‘Tree’ layer – as this is the only layer we can select, we need to add the calculation required to pass through to the parameter.

Once the user clicks, the update gets passed through to the ‘pBaublePosition’ parameter, and the ‘Shapes’ will update on the ‘Bauble’ layer based on this.

You can also show the ‘pBauble’ parameter and test that changing this will also work:

This is a fair amount of work done. This section can be repeated for the ‘Tinsel’ and ‘Topper’ layers (you may need to add an extra layer), and add in the ‘pType’ parameter to check all that works:

Bar some formatting – this is the main job done, so what now?

Move to the Dashboard

Next we want this on a dashboard page, rather than a worksheet. First of all I created a background in Figma which matches the size of the dashboard I wanted (1200 x 800) and I added this as a floating image covering the dashboard. This background included the original tree I drew to get the plots:

Then I am going to float my ‘Tree’ worksheet on top of the tree image and size it until all the points fit nicely on the tree. to do this:

  1. Make the background of the ‘Tree’ worksheet Transparent so we can see through it
  2. Hide the X and Y axes and get rid of all gridlines and axes lines, so all we can see are the points. Also hide the title.
  3. Once the tree is in a position you like – then change the shape of the top layer to be a transparent icon, so that you can’t see all the little circles (you can still click them)
  4. Adjust the size of the Bauble/Tinsel/Topper marks to be an appropriate size for the dashboard.
  5. Convert the Worksheet actions previously made to be Dashboard actions so that they work on this new dashboard (do this by changing the ‘source sheets’ from a specific sheet to the dashboard you are working on):

With these set up, and with the parameters shown, the same functionality should work:

A couple of things still to do. First is to sort out the worksheet selection. You can see in the above that the decorations are ‘greyed’ out, this is due to the mark the user selects staying ‘selected’ and messing up the other visuals.

I have a standard trick I use for sorting these out (one I picked up from Marc Reid) which involves putting a calculated field containing ‘True’ in the detail of the tree worksheet, and having a filter action that puts ‘True’ equal to an equivalent ‘False’ field – this has the effect of deselecting any marks as soon as they are selected:

With this now working, the last thing I want to to is get rid of the parameter drop downs, and have the image selections instead. This is quite straightforward but does involve using a separate data set.

Add the Menu – Type Select

The dataset I will use is:

Very simple – but it allows me to build the menu views I would like and all the wording matches what I have in my parameters. For the type select menu, it is simple and I need only one calculated field:

TypeSelected: [pType] = [Value]

This is used to highlight the Type that we have selected – i.e. the one that equals the parameter value. I can then build the following view:

Notice the “” in the column and row, this allows me to create a ‘Square’ that will fill the cell contents, but not spill over to other cells (try this without and see what happens!).

The ‘Value’ will be used in a parameter action to change the ‘pType’ parameter later.

Add the Menu – Decoration Select

This view is slightly more complicated, and uses a few more calculations:

BaubleType/TinselType/TopperType:

if [Value] = 'Bauble' then [Value2] end

For each of the Specific types, this will provide a value if the overall type is selected, or null if not.

X/Y:

FLOAT(if contains([Value2],'1') then 1
elseif contains([Value2],'2') then 2
elseif contains([Value2],'3') then 1
elseif contains([Value2],'4') then 2
end)

These two fields calculate the square grid I want to place the pictures on, using the numbers in the value to assign X and Y values.

Value2Selected:

CASE [pType]
when 'Bauble' then
if [Value2] = [pBauble] then 'Selected!' end
when 'Tinsel' then
if [Value2] = [pTinsel] then 'Selected!' end
when 'Topper' then
if [Value2] = [pTopper] then 'Selected!' end
End

This checks which decoration type is selected in order to display the ‘Selected’ text.

Size/Size (Copy):

These are just set to 1 and are used to independently size the icons. I use this method as the slider didn’t get me a big enough icon.

With these formulae set up, the worksheet is a dual axis chart that looks like this:

The first ‘X’ marks place the specific icons of the decorations on the page and the second ‘X’ places the grey square and the ‘Selected’ text behind the decoration so the user knows what has been selected.

‘Value2’ in this instance is used to pass to the relevant parameters.

Add the Menu – Clear Tree

The final sheet is a button to clear the tree:

Super simple – and contains a ‘Blank’ calculated field (”) which will be passed to the three Position parameters to clear them.

Put it all together

Now these are built, we can move them onto the dashboard and set up the relevant actions:

This parameter updates the type of decoration used.

Three very similar actions update the Bauble, Tinsel or Topper items.

Three actions are also used to clear the ‘Position’ parameters by sending through a blank field when the clear sheet is selected.

All of the three new menu sheets also use the ‘True’/’False’ filtering trick in order to always show the sheets as Deselected.

And with this – we should be there!!

Final dashboard is here: Decorate Your Own Tree

Note: On reading this you may question ‘Why use 3 map layers for the decorations, can’t it be done in 1?’ – and the answer is simply, Yes! You could do all the decorations in one map layer and have a few less calculations. The main reason I did this initially was that I wanted to have the layers in a particular order – i.e. I always wanted the ‘Topper’ on top of the ‘Bauble’ and them on top of the ‘Tinsel’. I realise in retrospect that I could have done this with just ordering the marks on one layer! However the method I used does mean you are able to have multiple decorations on a single mark (if you wanted!) – so that is my excuse!

I hope you found this useful and/or interesting! If you have any questions or comments on this – please let me know!

Thanks,

Ant.

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 )

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