For this week’s challenge, Kyle took the challenge I posted the previous week about building a radar chart with map layers, and used a viz extension to build the chart instead – a stroke of genius!
If you want to use this method within your organisation for use on Tableau Cloud or Tableau Server, you’ll need to factor in licensing costs for the extension, and you also might need to agree access with your security team. The map layer solution I blogged about here, works as part of the product itself.
After connecting to the dataset (I used the Engagement Survey Data – Filled sheet), click Add Extension from the marks card dropdown
search for radar in the resulting Add an Extension dialog, and then select the Radar option by LaDataViz. and then select Open on the resulting screen
The presented sheet will give some prompts to get started, but due to the requirements of this challenge, we need to build some calculations first.
The user need to be able to select the business function (Area) to display, so right click Area and then Create Parameter to create
pSelectArea
string parameter defaulted to Whole Company. As the parameter is created from a field, the list of available options is pre-populated. Delete the Benchmark entry from this list.
We only want the selected Area and the ‘Benchmark’ option to display on the chart, so create
Area to Display
[Area]=’Benchmark’ OR [Area] = [pSelectArea]
Add this the Filter shelf and set to True
The chart displays the ‘Benchmark’ as an area bounded by a dashed line. This is achieved by setting the Benchmark value as a target, so we need to define that value in its own calculation
Target
IF [Area]=’Benchmark’ THEN [Value] END
set this to % with 0 dp.
We also want to isolate the values associated with the selected area too
Selected Value
IF [Area] = [pSelectArea] THEN [Value] END
set this to % with 0 dp too.
Add Themes to the Spokes shelf, Selected Value to the Values shelf and Target to the Target shelf
We’ve got all the info we need, now just to format the display, so select Format Extension and apply the following properties
Radar tab
Line Style = Linear
Fill opacity = 10
Range: uncheck auto, set min =0, max = 1
Marker = None
Expand the Target section, and set Fill Opacity = 2
Grid tab
#Lines = 10
Spacing = 0
Style = Straight
Labels tab
Spokes section : Orientation = Horizontal
Labels section : check the Labels checkbox, Font style = bold
Number format : Style = Percentage
Expand the Axis section, check the Axis Labels checkbox,
Line: uncheck the Show Line checkbox
Number Format : style = percentage
Finally, adjust the Tooltip, and then that should be it – just need to add to dashboard and show the pSelectArea parameter
This week’s WOW challenge for community month, saw Sean partner with Tableau Visionary and ‘Hall of Famer’, Linsdsay Betzendahl to deliver this double challenge – creating a Mekko chart with staggered labels AND a stacked bar chart with staggered labels.
There was quite a lot going on in this challenge, and I had utilised all the concepts in the past, but did still need a refresher to remind how to get things done. So I did draw on the links provided in the challenge, as well as blogs I’ve written for other WOW challenges, specifically
The link in the challenge downloaded a CSV file to connect to. Once connected, the instruction was to pivot the data, so all the ‘types of death’ columns were transposed from rows into columns. In the data source pane, multi-select all the ‘Total Dead xxxx’ columns then right-click and select pivot
I then renamed the Pivot Field Names column as Disaster Type Raw and Pivot Values as Decadal Deaths.
In the Data pane, I then created a group against the Disaster Type Raw field, called Disaster Type. Every value was grouped, even if it only contained a single entry, just so I could display the name of the disaster in the way that matched the solution
Building the calcs for the Mekko chart
A Mekko chart is based on % – in this instance, the height of the chart is split based on the % of deaths by type per decade, while the width is based on the % of total deaths per decade. For this we’ll need some table calculations, so building out a tabular view to check the values is always something I find very valuable.
Change the Year field to be discrete, then add to Columns. Add Disaster Type to Rows and Entity to Filter and restrict to World. Add Decadal Deaths to Text.
Add this into the table and then adjust the table calculation so it is computing by Disaster Type only, which essentially means based on the layout of this table view, that each column should be adding up to 100%
This is giving us the value we need to plot on the Y-Axis of the chart (ie the height)
To determine the value to plot on the X-Axis, we need several calculations. First we need to know the total deaths per decade
Total Deaths per Decade
{FIXED [Year],[Entity]:SUM([Decadal Deaths])}
Add this into the table. The value should be the same for every row for the same year.
Then we need to know what this value is as a % of all the deaths across all the decades
% Total Deaths per Decade
SUM([Total Deaths per Decade]) / TOTAL(SUM([Total Deaths per Decade]))
Add this into the table, and adjust the table calculation so that it is computing by Year, which means the values per row should add up to 100%
To build a Marimekko chart, which is a variable width chart, we need to use the cumulative value of this %, so we plot points from the start up to 100%. So we need
Running Sum % Total Deaths per Decade
RUNNING_SUM([% Total Deaths Per Decade])
Add this into the table, verify the table calc is computing explicitly by Year as described above for both the nested calculations, and we should see the values increasing up to 100%
Now typically this would be enough for the chart and is what is mentioned in the referenced blog posts for building these charts. However, due to the staggered labelling requirement, we need to go a step further, as the value we plot on the X-Axis needs to be used for both the Mekko chart and the ‘pointers’ associated to the staggered labels. As these labels are centred, we need to plot our point midway
Mekko – Plot Point X Axis
[Running Sum % Total Deaths Per Decade] – ([% Total Deaths Per Decade]/2)
ie take the running sum value, but subtract half of the % value for the decade.
As before add to the table, setting all nested table calculations to be computing by Year.
Now we have all this, we can start to build out the chart
Building the Mekko chart
On a new sheet, add Entity to Filter and restrict to World. Add Year to Detail and Disaster Type to Colour, and adjust colours to suit.
Then add Mekko – Plot Point X-Axis to Columns. Adjust the table calc, so both next calculations are computing by Year only. Then add % Decadal Deaths to Rows and adjust the table calc to be computing by Disaster Type only. Change the mark type to bar and adjust the sort on the Disaster Type field to sort by field Decadal Deaths ascending
Then add % Total Deaths per Decade to Size. Adjust the table calc so it is computing by Year only. Then click on Size and change the option from Manual to Fixed and align Centre, so the width of the bar is stretched equally, either side of the central plot point. Add a white border via the Colour shelf.
Add Decadal Deaths and Total Deaths per Decade to Tooltip and update as required.
Add Disaster Type to Label, then adjust the Label settings so the label is only displayed based on the maximum value of the Year field, and match the mark colour.
At this point, while the labels are displayed, they aren’t in the required location. To resolve this, start by extending the X axis to be fixed to end at 1.2 (right click axis > Edit)
This extends the axis, giving some ‘space’ in the chart for the labels. Trying to adjust the alignment of the labels doesn’t work though, so move them manually. Click on the label so the cursor changes to a cross, and then drag the label to the side to reposition it.
Do this for all the labels displayed in the solution, doing your best to align them vertically. Once done, then in the label settings, uncheck the ‘allow labels to overlap other marks’ option, so the other values disappear.
Now we have the Mekko chart, we now need to handle the staggered labelling.
Mekko – Label Position YAxis
IF INDEX()%2 = 1 THEN -0.1 ELSE -0.3 END
We’ll index the year from 1 to 13, and every odd number index will have the label positioned at -0.1 and even at -0.3
Add this to Rows which will create a 2nd marks card. Remove all the fields except Year and Total Deaths per Decade from the card.
Adjust the table calc to explicitly compute by Year, and then change the Size from Fixed to Manual and reduce the slider to as small as possible. You should now have your label ‘pointers’
Move the Year and Total Deaths per Decade pills onto the Label shelf, then set the Label settings, so All labels are shown, they can overlap other marks, and adjust the alignment, so they’re not skewed (you may need to find you have to click the sideways position first before you can get the alignment working)
Adjust the formatting of the label, then edit the Mekko – Label Position Y Axis axis so that it is fixed to start at -0.5, and the title and tick marks are removed, so the axis looks to disappear.
Finally tidy up by removing all gridlines, row and column dividers and hiding the Mekko – Plot Point X Axis axis.
Add to a dashboard, and include the requested citation to the data source. I added this within a floating text box with a show/hide button.
Building the calcs for the Bar chart
The bar chart employs similar principals as the Mekko chart, we need to calculate a position to plot the point on the X-axis, but the bar has a fixed height and not split. Let’s start with getting the calcs we need again.
Build a table with Entity on Filter (filtered to World), Year on Rows and Disaster Type on Columns. Add Decadel Deaths onto Text and then add % Decadel Deaths into the table, and adjust the table calc so it is computing by Disaster Type. Due to the layout of this table, the values in each row now add up to 100%.
The % Decadal Deaths defines the ‘width’ of each segment in the bar chart, so one again we need a cumulative value to help determine the plot point.
Running Sum % Decadal Deaths
RUNNING_SUM([% Decadal Deaths])
Add to the table and ensure all the table calcs for the nested calcs are all computing by Disaster Type.
And as before, as we need a ‘central’ point to plot, create
Bar – Plot Point X Axis
[Running Sum % Decadal Deaths] – ([% Decadal Deaths]/2)
Add to the table and ensure all the table calcs for the nested calcs are all computing by Disaster Type.
There is an additional requirement for this chart, to restrict what is displayed based on the Year selected. Create a parameter based off of the Year field
pYear
integer parameter, defaulted to 2020 (formatted without thousand separators), that lists the values
Then create a field
Show Last 3 Decades
[Year]>= [pYear]-20 AND [Year]<=[pYear]
and add to the Filter shelf and set to True.
For the label pointer position, we also need a similar field as before, but only want labels to show when the % is over 4%, so create
Bar – Label Position Y Axis
IF [% Decadal Deaths] > 0.04 THEN IF INDEX()%2 = 1 THEN -0.1 ELSE -0.3 END ELSE NULL END
format to show 2dp, then add to the table, and ensure all table calcs are computing by Disaster Type.
Values will only display if the % Decadal Deaths value is >4%, and the value alternates based on the index position.
Building the bar chart
The steps are very similar to the Mekko chart, except this time, we need the Year dimension on Rows and we can ‘hard code’ a ‘y-axis’ by double clicking into Rows and typing MIN(0.5). This axis is then fixed from 0 to 1 to provide some spacing. Bar – Plot Point X Axis is on Columns and % Decadal Deaths is on Size with the size once again Fixed and centred. This time to Disaster Type field is sorted by Decadal Deaths descending.
Add Bar – Label Position Y Axis to Rows to create the 2nd marks card, and again apply similar steps as above to end up with labelled pointers. I set the axis of this measure to be fixed from -1
The you just need to tidy up the formatting by removing the gridlines, axis lines, row/column dividers and hiding the various axis. Then add to a dashboard and show the parameter.
For this week’s challenge we’re using the Superstore data set to simple averages with weighted averages
Connect to the data and on a new sheet add Order Date to Filter and select the last 3 months in your data set (I had the 2025.3 instance of Superstore, so the data was filtered to Oct, Nov & Dec 2025.
Simple Average
In the data we have, a single Order ID can have multiple order lines (ie Products), and the quantity of each product can differ. Different discounts can be applied to each product. In the example below, we are at the lowest ‘grain’ of the data, ie each row in the table is equivalent to a single row in the raw data set. As a result the SUMs and the AVG values are identical. This order has 5 order lines. (Note, the Discount field has been formatted to a % with 1 dp).
If this data is summarised just at the Order ID level, the SUM and AVG differ, as you would expect.
The AVG([Discount]) is automatically being computed by Tableau as SUM(Discount) / number of rows associated to the Order ID, which is 280/5 = 56%.
This is the ‘simple’ average and is taking no account of the Quantity associated to each order line.
Weighted Average
We need to get the average based on the fact that in this example, there are actually 26 ‘items’ ordered across the 5 order lines, so we need the following
At the raw line level, the Discount is being multiplied by the Quantity (so a weighting is being applied per line as the quantities and discounts can vary). This is then being aggregated (ie summed up) and then the average is determined by dividing by the total number of items ordered. So based on the example we have (2*0.2) + (3*0.8) + (5*0.8) + (9*0.8) + (7*0.2) = 15.4 which is then divided by 26 = 0.592 or 59.2%
Building the Viz
Add Discount to Columns and change the aggregation to Average. Then add Quantity to Rows and change that aggregation to Average too. Add Order ID to Detail. Change the mark type to circle.
Create a new field
Difference from correct metric
ABS([Weighted Avg] – AVG([Discount]))
Add to Tooltip and then create
Is difference?
ROUND([Difference from correct metric],3)<>0
note – I am rounding here as I was getting some anomalies to Erica’s solution due to very very small differences
Add to Colour and adjust to suit. Reduce the opacity and size as desired. Add Discount toLabel (aggregated to Average). Set the Label to display only when highlighted.
Add Difference from correct metric to Filter
Remove row/column dividers and adjust Tooltip as required.
Name the viz Simple Avg or similar and then duplicate the sheet. Replace the AVG(Discount) pills on the Label and Columns shelf with the Weighted Avg pill. Adjust tooltip and rename axis title. Name this sheet Weighted Avg or similar.
Creating the Viz in Tooltip
On a new sheet, add Order ID, Category to Rows and then Quantity and Discount into the table aggregated at the Average level. Remove row banding and column dividers and adjust row dividers. Name the sheet Order Details or similar.
On the Simple Avg sheet, edit the Tooltip and insert the Order Details sheet, adjusting the width if required.
Repeat on the Weight Avg sheet.
Creating the Dashboard
Using layout containers, create the desired arrangement. My hierarchy is below
I used blank objects with a grey background to create the horizontal and vertical ‘lines’, using outer padding to help. Here’s an example of the top horizontal line. The height of the object is 134 pixels, but I’ve added 130 px top padding, making the ‘line’ 4px wide.
Add a highlight dashboard action that applies when a mark is selected
And that should then be done! My published viz is here.
This week’s #WOW2026 challenge was inspired by the annual viz challenge held at the Japanese TUG. It took me a bit longer than 10 minutes to build though!
I’ve built this using 3 sheets – a sheet for the section of the calendar above the displayed bar chart, the bar chart and then the section of the calendar below the bar chart.
Building the Calendar Sheets
On a new sheet, add Order Date at the month-year level to Filter and select December 2025. Then add Order Date at the Weekday level to Columns and Order Date at the Week (number) level to Rows. Additionally add Order Date at the month-year level to Columns as a discrete (blue) pill positioned first.
Create a parameter
pSelectedDate
date parameter defaulted to 10 Dec 2025
and show this parameter on the view.
Create a new field
Is Selected Date
[pSelectedDate] = [Order Date]
Change the mark type to circle then add Is Selected Date to colour. Adjust colours to suit and add a dark border to the circle. Set the sheet to entire view. Add Order Date at the Day level to Label and align middle centre.
We want the calendar to show ‘no selected date’, so will utilise 01 Jan 1900 as a ‘null’ date. We also want the calendar to only show the dates related to the week of the day selected and any previous in the month. So create
Show Top
[pSelectedDate] = #1900-01-01# OR WEEK([Order Date])<= WEEK([pSelectedDate])
and add to the Filter shelf and set to True
We also need all the days of the week to display, even if there aren’t sales on those dates. Eg, set pSelectedDate to 03/12/2025 and we lose the ‘Sunday’ column.
To resolve this, select the Show Empty Columns from the Analysis > Table Layout menu
Adjust Tooltip to suit.
Hide the Order Date column heading (right click > hide field labels for columns). Adjust the format (font size) of the other labels. Hide the WEEK(Order Date) row heading (right click, uncheck Show Header). Hide row & column dividers.
Create fields
True
TRUE
False
FALSE
and
Date for Param
IF [Order Date] = [pSelectedDate] THEN #1900-01-01# ELSE [Order Date] END
Add all these to the Detail shelf, setting the Date for Param field to be a discrete (blue) exact date.. They’ll be needed for the interactivity later.
Name this sheet Top or similar, then duplicate the sheet and change the Show Top filter to be False. Then hide the header labels (uncheck Show Header). Remove the True & False fields form the Detail shelf. Name this sheet Bottom or similar.
Building the bar chart
On a new sheet add Is Selected Date to the Filter shelf and set to True. Add Sales to Columns and Region to Colour and add Region to Label. Expand the width to make the bar wider.
Add Order Date to Tooltip and adjust Tooltip to suit. Set the background colour of the worksheet to dark grey, then format axis to have white font. Remove gridlines.
Building the dashboard
Use a vertical container, add the Top sheet and then then Bottom sheet underneath. Remove all padding from these sheets, and remove the title
Then add a horizontal container between the 2 calendar sheets. Add a text object and adjust text as required and reference the pSelectedDate parameter. Then add an image object, and select the image you hopefully downloaded from the link in the challenge page. Then add the bar chart, removing the title and setting to fit entire view.
Remove all padding for each object in this container and set the background colour of the text and image objects to the same dark grey as the bar chart.
Change the colour of the font in the text box, and I set some inner padding on the text object and the bar chart (10 pts all round) just for some extra breathing room. If need be, set the background colour of the bar chart object too.
Change the date in the pSelectedDate parameter and watch the bar chart move
Adding the interactivity
Add a dashboard parameter action
Select Date
on select of the Top or Btm sheets, set the pSelectedDate parameter by passing the value from the Date For Param field.
Also add a dashboard filter action
Unhighlight Top
On select of the Top sheet on the dashboard, target the Top sheet directly, explicitly setting the True field to False. Show all values when selection cleared.
Finally, we need to make the horizontal container disappear when no date is selected (ie the pSelectedDate parameter is set to 01 Jan 1900).
Create a new field in the data set
Is Not Null Date
[pSelectedDate] <> #1900-01-01#
then back on the dashboard, select the whole horizontal container, and from the Layout pane, check the option to control visibility using value, and select the Is Not Null Date field
When the date is 01 Jan 1900, this whole section will now disappear. You should be able to click dates now, and get the functionality as expected.
Once done, you can tidy up the dashboard by removing the container with all the filters and legends, adding a title, and adding some extra padding and background colours as required.
For this week’s challenge, Yoshi got us creating gauge charts using Tableau’s radial viz extension.
Modelling the data
Yoshi provided a version of the Superstore dataset along with a Budget csv. After downloading, I related the 2 files within Desktop using the following relationships pictured below
Building the gauge chart
On a sheet, select the Add an extension option from the mark type dropdown and then select the Radial (by Tableau) option, and click Open on the resulting screen
Add Measure Names to Ring and Measure Values to Angle and then add Measure Names to filter and retain the Sales and Budget options only.
Click Format Extension and then set the options as follows
Total angle (degrees) : 180
Starting angle (degrees) : 270
Ring padding : 30
Segment padding : 5
Segment labels : Ring and Angle Values
Font : size 9
Centre size (%) : 50
Show centre label: on
Automatic font size: on
Edit colours and select appropriate colours
Adjust the order of the Sales and Budget pills in the Measure values pane if required
Add Region, Segment, Category and Order Date at the month-year level to the Filter shelf. Set Category to Furniture and Order Date to December 2025.
Format the Measure Values pill on the Angle shelf so that it displays the numbers as $ with 0 dp.
Create a new field
Acheivement %
(SUM([Sales])/SUM([Budget])) / 2
format this to % with 1 dp and add to the Centre shelf. Note, the division by 2 is necessary due to their being 2 measures (and therefore 2 marks) displayed and the number duplicating itself.
Create another field
Tooltip – Achievement %
(SUM([Sales])/SUM([Budget]))
Format this to % with 1 dp and add to the Tooltip shelf along with Sales, Budget and Category. Update the Tooltip to suit. Edit the title to reference the Category field, and then name this sheet Gauge – Furniture or similar.
Then duplicate the sheet. Change the Category filter to Office Supplies and name the sheet Gauge – Office. Repeat to create a version for Technology. So you should end up with 3 sheets, one for each Category. Apply the Region, Segment and Order Date filters to be shared across all 3 workbooks.
Building the bar chart
Create a field called
Sales Rank
RANK(SUM([Sales]))
and change it to be discrete (right click > convert to discrete)
Add Category to Columns and Sales Rank to Rows and Sub-Category to Detail. Set the table calculation associated to Sales Rank to be computing by Sub-Category only.
Double click into Columns and manually type MIN(1) to create a ‘fake axis’. Change the mark type to bar and edit the axis to be fixed from 0 to 1. Widen each row slightly. Then move Sub-Category to Label
Then via the Colour shelf, reduce the opacity to 0% and remove the border
Now add Sales to Columns. and on the Sales marks card, move Sub-Category back to Detail, and rest the opacity to 100%
Colour the bars as required. Add Budget to the Detail shelf, then add a reference line to the Sales axis, which shows the Budget per cell as a line with a fill below of light grey.
From one the gauge sheets, set the Region, Segment and Order Date filters to also apply to this sheet.
Add Achievement % to Tooltip and adjust the Tooltip on the Sales marks card only. Remove all the text from the Tooltip on the MIN(1) marks card.
Then format the sheet by
editing Sales axis and removing the axis title
editing the MIN(1)axis and removing the title and tickmarks
hide the sales Rank header (right click pill > uncheck show header
hide the Category header
remove row & column dividers
Then add the Gauge sheets into a horizontal container on a dashboard, setting the container to ‘distribute contents evenly’. Add the bar chart underneath, but I ‘floated’ it into position as each gauge chart object takes up more vertical space than necessary (the size of the object doesn’t adapt to the fact you’re only showing half a circle).
Lorna wanted us to practice layout containers this and also sprinkled in a bit of new functionality – rounded corners! As a result you’ll need to use Tableau Desktop v2026.1 to complete this challenge.
Lorna provided a starter workbook with all the required sheets – we had to build the dashboard.
Describing how to do this is tricky, so I’m going to show a picture of my item hierarchy, and then describe some key points.
Lorna challenged us to use no more than 11 containers. I have 12 as I’ve included my standard ‘footer’ in a horizontal container, which isn’t part of the solution. When working with containers, it’s often useful to add blank objects as placeholders to help ensure the layout. and while you add and position the actual objects. The blank objects then get deleted. Padding is very helpful to reposition objects and add whitespace, but getting the values right can take a bit of trial and error and lots of tweaking.
I have renamed all the containers and numbered them, so you can see the number there are. I’ve named them with an ‘h’ or ‘v’ prefix depending on whether the container is vertical or horizontal.
When dealing with tricky layouts, I always start with a floating container that is positioned at point 0,0 and has the height and width of the dashboard. In this case, this is the container labelled 1.vBase. When I add other containers/objects into this base container, they are set to be tiled. I remove the automatic ’tiled’ container that exists initially, and if any reappear as I’m adding objects, I delete them too.
To generate the bordered shadow effect around the Superstore Overview title, the 2.hHeader container has the following properties:
no border
background set to light grey
corners set to a radius of 5
outer padding all 0
inner padding all 0
The Superstore Overview title Text object that sits inside this container, then has the following properties
no border
background set to white
corner radius all 0
outer padding: left 5, top, bottom, right all 2
inner padding all 15
A similar principal is applied to the 11.hRightPane container and the Scatter plot object contained within. The 11.hRightPane container does additionally have a left outer padding of 5 and a bottom padding of 10.
The 4.vLeftPane container just has a right outer padding of 5. This along with the 5 left outer padding of the 11.hRightPane container above gives the 10 pixel spacing between the 2 columns of data in the main body of the chart. There will ultimately be 3 ‘KPI’ rows within this container, so the 4.vLeftPane should be set to distribute contents evenly (only apply once you’ve built all the rows as described below).
Each KPI ‘row’ is constructed in the following manner; I’ll describe the top row, but just repeat for the other rows:
5.hTopKPI-Outer has the following properties
no border
background of light grey
corner radius of 5 all round
outer padding all 0
inner padding all 0
The 6.hKPI-Inner then has the properties
no border
background is white
corner radius all 0
outer padding: left 5, top, bottom, right all 2
inner padding all 0
Having the 2 horizontal containers set up this way creates the bordered, shadowed effect.
The Total Sales CY vs PY sheet is then set to a fixed width of 140 and inner padding all round of 10.
The Sales % Change sheet is then set with a fixed width of 130, corner radius of 20 all round, and outer padding of left 15, top 80, right 15 and bottom 20. Note, I also reduced the label text on the sheet itself from 20 to 15 pt.
Finally the Sales over Time sheet is set to have inner padding of 15 all round.
Hopefully all this helps, though as mentioned, I can imagine they’ll be a bit of fiddling to get things right. My published viz is here.
This week’s challenge uses data I collated from the stats vest my daughter wears during her football matches and training sessions. The data provided is already pre-filtered to the 2024-25 season and her Reading U15 team.
If you want to watch a video which demonstrates the concept then this video by Andy Kriebel will help. But if you prefer to read, then carry on 🙂
Building out the calculations
In creating this chart we need to normalise all the different stats we want to show; that is we want to convert every measure into a spread between 0 and 1. To do this we calculate the difference between the value and the minimum value as a proportion of the full range of values (that is the difference between the min and max values). We use table calculations for this.
Total Distance (km)
(SUM([Distance – Total (KM)]) – WINDOW_MIN(SUM([Distance – Total (KM)]))) / (WINDOW_MAX(SUM([Distance – Total (KM)])) – WINDOW_MIN(SUM([Distance – Total (KM)])) )
format to 4 dp
Distance / Min (m)
(SUM([Distance per Min]) – WINDOW_MIN(SUM([Distance per Min]))) / (WINDOW_MAX(SUM([Distance per Min])) – WINDOW_MIN(SUM([Distance per Min])) )
format to 4 dp
HSR Distance (m)
(SUM([HSR – Total (M)]) – WINDOW_MIN(SUM([HSR – Total (M)]))) / (WINDOW_MAX(SUM([HSR – Total (M)])) – WINDOW_MIN(SUM([HSR – Total (M)])) )
format to 4 dp
HI Distance (m)
(SUM([HI Distance – Total (M)]) – WINDOW_MIN(SUM([HI Distance – Total (M)]))) / (WINDOW_MAX(SUM([HI Distance – Total (M)])) – WINDOW_MIN(SUM([HI Distance – Total (M)])) )
format to 4 dp
Max Speed (m/s)
(SUM([Speed – Max (m/s)]) – WINDOW_MIN(SUM([Speed – Max (m/s)]))) / (WINDOW_MAX(SUM([Speed – Max (m/s)])) – WINDOW_MIN(SUM([Speed – Max (m/s)])) )
format to 4 dp
NOTE – in my solution I called these fields Norm – xxxx . After putting on the chart, I aliased them to the names above. Creating with the actual names I used is the simpler solution 🙂 I don’t know why I didn’t just rename them…
On a new sheet, add Game ID to Rows, and then add all the original key measures and their associated normalised values into the table, so each original measure is next to its normalised value. If you sort by one of the original measures from largest to smallest, you should see that the associated normalised value is distributed from 1 at the top of the list to 0 at the bottom.
The other key requirement for this viz is to identify a selected opposition. For this we create a parameter based on the Opposition field. Right click on Opposition > Create > Parameter and the following dialog with the list of opposition teams pre-populated will display. I set the default as Chelsea Ladies U14
Opposition Parameter
The create a new field
Highlight Match
[Opposition] = [Opposition Parameter]
Show the Opposition Parameter control and add Highlight Match to Rows.
Now we can start building the viz.
Building the chart
On a new sheet, add Game ID to Detail, then add Total Distance (km) to Rows. Adjust the table calculation of the field to be computing by Game ID.
Then add Distance / Min (m) onto the sheet, by dragging the field and dropping it on the y-axis when the 2-column icon appears
This will automatically add Measure Names and Measure Values into the display, including a Measure Values ‘box’
Adjust the table calc of the Distance / Min (m) field to compute by Game ID. Reorder the fields in the Measure Values box, and then change the mark type to line. Set to Fit Width.
Add the other 3 normalised fields into the view, by adding the field into the Measure Values box, and adjusting the table calc each time.
We now have the core viz, we just need to format it and add the additional features.
Show the Opposition Parameter control. Add Highlight Match to the Colour shelf. Adjust colours and re-order so True is listed first. Adjust all the table calcs in the 5 measures so they are also now computing by both Game ID and Highlight Match.
Now add H/A to the Detail shelf and change to be an Attribute (this means by default it is excluded from the table calcs, so we don’t need to make all those adjustments again). Then change the icon to the left of the pill from Detail to Colour, so there are now two fields on the Colour shelf. Adjust to suit.
Add Highlight Match to the Size shelf, and then adjust the size to be reversed, so the True lines are thicker.
Create a new field
Label: Opposition
IF [Highlight Match] THEN [Opposition] END
And add this to the Label shelf and set to be an Attribute. Adjust the Label property so it’s just labelling the line ends and label end of line. Ensure labels set to overlap to, and set font to bold and to match mark colour and align top right.
Alias the field H/A (right click field > aliases) so they display as Home and Away. Then add the following fields to the Tooltip : Category, Cup/League, H/A, Opposition, Round and Date. Also add the following measures to the Tooltip : Distance – Total (KM), Distance per Min, HI Distance – Total (M), HSR – Total (M), Speed – Max (m/s). Then adjust and format the Tooltip
To create the vertical lines, add another copy of Measure Values to the Rows which will create a Measure Values (2) marks card. Remove all the fields from this card except the Game ID. And then move Game ID to the Path shelf which has the effect of creating the vertical lines
Adjust the Colour of the line and then add Measure Names to the Label shelf. Set the label to Min/Max by pane, for the Measure Values field. Align centrally.
Set the chart to dual axis and synchronise the axis. Hide all the axis, and the Measure Names labels at the bottom (uncheck show header against the pills). Remove all row/column dividers and gridlines/zero lines etc. Set the background colour (if desired).
Adding the interactivity
Add the chart to a dashboard then create a dashboard parameter action
Set Opposition
On select of the viz, set the Opposition Parameter parameter, with the value from the Opposition field. Set the value to <empty> when cleared.
Adding the information panel
Add a floating Text object onto the dashboard. Copy and paste the information from the challenge page. Resize and reposition the text box as required. Set the background of the text object and add a border to make it prominent. Then from the context menu of the object, select the Add Show/Hide Button option. The Show/Hide object will appear as an X. Move this into the required position and re-adjust the text object to suit too.
And that should then be it. My published viz is here.
Sean based this week’s challenge on a scenario he’d faced with a client and requires the use of dynamic zone visibility (DMZ) and filter actions.
I’m going to attempt to be relatively brief for the vizzes/views that need building, as the main focus is on the dashboard itself.
Creating the Main KPIs
Connect to the data source and add a data source filter on Country/Region = United States so any data related to Canada gets excluded automatically from everything we build.
Create a new field
Profit Ratio
SUM([Profit])/SUM([Sales])
and format to % to 2 dp
On to a new sheet add Sales, Profit, Profit Ratio and Quantity onto the canvas. I just double-clicked each field and once all added used Show Me to display a Text table.
Move Measure Names to Columns and re-order the measures. Add Measure Names to Text too and modify the text so the Measure Names label is beneath Measure Values, aligned centrally and formatted as required. Set the sheet to Entire View. Format the Sales and Profit pills on this sheet to be formatted to $k to 1 dp.
The KPIs need to filter based on the state that will be selected in the map. We’re going to use a parameter to capture the state
pSelectedState
string parameter defaulted to <empty string?
And then we create
Is Selected State?
[pSelectedState]=” OR [State/Province] = [pSelectedState]
Add this to the Filter shelf and select True.
Format the sheet to remove row/column dividers and hide the Measure Names label header (uncheck show header on the pill).
Name the sheet KPIs-Main or similar.
Creating the Customer KPIs
Although not actually working on Sean’s solution, I believe the intention of showing KPIs on the ‘customer panel’ is to give a summary based on the selected customer. So to do this simply duplicate KPIs-Main and then add Customer Name to the Filter shelf and select all customers. Name the sheet KPIs-Customer or similar.
Creating the Map
ON a new sheet, double click State/Province to automatically create a map and then add Sales to Colour. (if the map doesn’t display the US, then you may need to edit locations – Map > Edit Locations). Adjust the background of the map and remove all city/state labels (Map > Background Layers). Name the sheet Map or similar.
Creating the Customer Orders list
On a new sheet, add Product Name to Rows and then Sales and Quantity as a table. As Is Selected State to Filter and set to True and also add Customer Name to Filter and select all values. Ultimately on click of a state in the map, this list needs to be filtered to just the orders associated to that state , and then additionally be able to be filtered by customer name
Creating the Reset Button
On a new sheet, double click into the space below the marks card and type ‘Reset’ to create a ‘dynamic’ pill. Then change the mark type to square and add this pill onto the Label shelf. Set the size to the largest possible and set the sheet to entire view. Format the label to be centred and larger. Then create a field
State-Reset
”
and add this onto the Detail shelf. This field basically contains an empty string, and we’ll use it later to ‘reset’ the pSelecedState parameter. Call the sheet Reset Button or similar.
Building the dashboard & interactivity
Using layout containers, build out the dashboard as required. I used a horizontal container in the middle of the dashboard which displayed the Map on the left and another Vertical Container on the right. The vertical container is the ‘customer panel’ and it then contained the Customer KPIs, and the Customer Orders sheets along with the Customer Name quick filter (set to a single value dropdown) and reset button in their own horizontal container. My hierarchy is shown below.
Add a dashboard parameter action to select a state
Set State
On select of the Map sheet, set the pSelectedState parameter with the value from the State/Province field. But on clearing the selected keep the current value.
Clicking on a State will now change the KPIs and the list of customer orders
But we also want the list of customers in the filter list to be restricted to those who have orders in the state, so adjust the quick filter settings so that it is set to only relevant values Also customise the control to so the ‘all’ option is not displayed.
Test this behaviour by selecting different States and then checking the values in the Customer Name filter control.
When the Reset button is clicked, we want the State to be deselected and the KPI values all reset, so create another parameter action
Reset State
On select of the Reset Button sheet, set the pSelectedState parameter with the value from the State-Reset field
If you test this out without selecting a Customer Name filter, then the behaviour will work as expected: click a state, KPIs/Orders List and set of customers in the filter change; click reset and KPIs/Orders List and set of customers in the filter all reset .
However if after clicking a state, a customer is then selected in the filter (which filters the Orders List and the Customer KPIs)
If I then click the rest button, the customer panel now shows all the info for the selected customer
and if I now select another state, the customer filter is retained, and if that customer has no orders for the state, I don’t get what I expect
We need to be able to essentially ‘reset’ the customer filter as well when clicking the reset button.
This was the trickiest part of this challenge, and I did try a variety of other ways of displaying the customer filter to see if I could crack it, but I did observe through playing with Sean’s solution and hovering the mouse, that the Customer Name filter was a standard quick filter. Eventually, with the clue being in the challenge title, I got there.
Add a dashboard filter action
Reset Customer Filter
On select of the reset button, target the Customer Orders, KPIs Customer but filter on selected fields where Customer Name = Customer Name
Finally we want the customer panel to only display once the map is clicked. For this, create a new field
State parameter is not empty?
[pSelectedState] <> ”
which will be true when pSelectedState contains the name of a state which happens ‘on click’ of the map. Then back on the dashboard, select the ‘customer panel’ container and on the Layout section, check the control visibility using value option and select the above field
And fingers crossed, you should now have a functioning viz. My published viz is here.
Erica set the challenge this week, which involved building the same visualisation in two ways – one using Table Calcs only and one using LODs.
To test the functionality and validate what’s going, I’m going to build the data out in a tabular format first.
The Table Calc Table
On a new sheet add Region and Category to Rows and Sales to Text. Sort by Sales descending. Then add Region and Segment to Filter, selecting all options, and show the filters.
Create a new field
Total Sales
TOTAL(SUM([Sales]))
and add into the table. This won’t be used later, but I’ve created so you can see the filtering behaviour.
This is a table calculation, and, by default when added to the table, it shows the total of all the rows against each row. We want to display the total per Region, so every row for a specific region shows the total of that region only. Adjust the table calc setting so it is computing by Category only.
Create a new field
TC – % of Sales
SUM([Sales]) / TOTAL(SUM([Sales]))
format to be % with 1dp and add into the table. By default it should have inherited the table calc settings we just applied for Total Sales, but if not apply the same settings, so it is computing by Category only.
If you do the maths taking the value in the Sales column and dividing by the value in the Total Sales column, you should be able to validate the result.
And if you test by adjusting the Segment and Region filters, everything should work as expected :
Filter out a Segment and the Sales and Total Sales adjust to exclude the value and the TC – % of Sales for a Region still totals 100%
Filter out a Region and that whole block is removed, but the values for all the other rows remain unchanged.
Now add Category to Filter and show the filter. Filter out a Category, and what we now see is the Total Sales now just reflects the total for the selected categories, and the TC – % of Sales still totals 100%. This isn’t the requirement. The % of Sales needs to calculate over all Categories regardless if it is excluded in the display.
To handle this, we create
TC – Filter Category
LOOKUP(MIN([Category]),0)
This is using a table calculation to basically return the value of the Category associated to the current row, which is basically looking up itself. However, as this is a table calculation, when added to the Filter shelf, it applies the filter after other computations (this is Tableau’s order of operations’), whereas the ‘quick filter’ applied above, is filtering the data first before then computing the total sales.
Remove Category from the Filter shelf, and add TC – Filter Category to the Filter shelf instead, selecting all options and showing the filter on the view. By default the table calc setting is set to table down which is fine – it is computing by both Region and Category. Now if you exclude a Category, the relevant rows disappear, but the Total Sales and therefore TC – % of Sales values remain unchanged.
The Table Calc Viz
The simplest way to build this (IMO) is to duplicate the table sheet then
Remove Total Sales and Sales
Move TC – % of Sales to Columns
Show mark labels
Adjust colour of bar
Adjust colour of worksheet background
Widen each row slightly
Make the width of bars slightly smaller
Edit title of % of Sales axis
Adjust fonts of label headers and bar label and axis labels (I set to 8pt)
The LOD Table
Let;s repeat this now using LODs instead.
On a new sheet, once again add Region and Category to Rows and Sales to Text. Add Region and Segment to Filter and show the filter options.
Create a field
LOD – Sales per Region and Segment
{FIXED [Region], [Segment]:SUM([Sales])}
Add into the table. With all segments selected, we can see the total sales for each Region listed
and filtering out a Segment, the totals adjust as required.
If we now add Category to Filter, show the options and filter one out, the totals now no longer change, as the LOD – Sales per Region and Segment doesn’t include Category in its definition – its FIXED to just account for changes to Region and Segment.
So we can now create
LOD – % of Sales
SUM([Sales]) / SUM([LOD – Sales per Region & Segment])
and format to % with 1dp and add into table to validate.
You can now apply similar steps to those detailed above to recreate the bar chart viz for this data.
And once done, add both charts onto a dashboard with their relevant filters.
In this week’s challenge Yusuke wanted us to ensure filtering by date didn’t actually exclude any dimension values (so null values displayed as 0) and average calculations then accounted for those null value entries too.
Setting up the core data requirements
Yusuke provided a link to a version of Superstore which I used, since the requirements included the Manufacturer field which isn’t in the usual Excel file. I first created the hierarchy of Category > Sub-Category > Manufacturer.
Category Hierarchy
Right-click the Category field and select Hierarchy > Create Hierarchy. Name it Category Hierarchy, then drag Sub-Category and Manufacturer to be positioned under the Category field.
The display shows the number of orders, so we need
#Orders
COUNTD([Order ID])
Add Category to Rows and then expand to display Sub-Category and Manufacturer. Add #Orders to Text and add Order Date as a discrete (blue) pill at the Weekday level. This table highlights the ‘gaps’ which we need to display as 0. It also shows us how many rows of data we should always expect regardless of the date being filtered.
A standard ‘quick filter’ on date will just remove the rows that aren’t included in the filter, so we need to handle the date filtering using parameters.
Add this into the table, and we can see we still have blank entries.
Now the trick here, which I have to admit I just couldn’t resolve until I looked at Yusuke’s solution, is to create a new field
Index
INDEX()
and add this to the Detail shelf, and all the gaps in the #Orders in Date Range measure will be replaced by 0.
Adding the average
Move the #Orders from the Measure Values section onto Tooltip.
The add column totals (Analysis menu > Show All Subtotals). Then go into the menu again and select Total All Using > Average. You’ll have totals at the Manufacturer level and the Sub-Caetgory level
Right click on the Total label in the Manufacturer column, and Format. In the left hand pane, update the Label to read Avg.
Repeat the same by formatting the Total label against the Sub-Category column.
Now format the numbers displayed by right-clicking on the #Orders in Date Range field on the Text shelf and formatting. In the left hand pane, select the Pane tab and set the format of the Numbers in the Default section to standard and the format of the Numbers in the Totals section to 2dp.
Formatting the rest of the table
Add #Orders in Date Range to Colour. Change the mark type to Square. Edit the Colour palette and select a diverging palette (eg red-blue-white diverging) but set the centre to 0 and check the include totals checkbox.
Format the table, and select the shading tab. Set the Total header to pale orage, and row banding to pale grey at band size 1.
Then select the borders option and set the default options against cell, pane and header to dark grey. Then add thicker orange borders against the totals, and remove row dividers. Add grey column dividers.
Hide the Order Date column heading (right click the Order Date label and hide field labels for columns). Right click the Order Date pill in Columns and format; set the Dates option to display abbreviation
Format the font of all columns to be the same (I used Tableau Medium, black).
We want to display a * to indicate null values, so create
Number prefix *
IIF(([#Orders in Date Range])=0,’*’,NULL)
Add to the label shelf and adjust the position of the fields on that shelf.
The create
Tooltip – 0 orders
IIF([Number Prefix ]= ‘‘, ‘* No orders found for this period’, NULL)
and add to the Tooltip shelf and adjust the Tooltip to suit. Then add Category to filter and select all options.,
Collages / expand the viz and adjust the dates to test the functionality and display.
Creating the date filter & Apply button
On a new sheet, double click in to the space below the Marks shelves and the type ‘Apply’. Move the field created from Detail to Label. Change the mark type to square, adjust the size to be as large as possible and then set the fit to entire view. Format the Apply label to be centred and larger font.
Add Order Date to the Filter shelf, select range oi dates and enter values from 11 Jul 2025 to 23 Jul 2025. Show the filter, and the add the Order Date filter to context.
Create new fields
Min Date
MIN([Order Date])
and
Max Date
MAX([Order Date])
and add both to the Detail shelf.
Create a new field
Colour
[Min Date]= [pMinDate] AND [Max Date]= [pMaxDate]
And add to the Colour shelf. Adjust the colour of the true option to pale grey. Then change the value in the Order Date filter, so the colour shows as false and adjust colour to orange. Hide the tooltip.
Finally create fields
True
TRUE
and
False
FALSE
and add both to the Detail shelf.
Building the dashboard
Use layout containers with padding to add the table viz and the apply button viz to a dashboard. Show the Category filter for the table viz, and the Order Date filter for the apply button viz. Below is how I arranged my layout containers
Create the following dashboard actions:
Set Min Date
On select of the Apply Button viz, target the pMinDate parameter passing in the value from the Min Date field.
Set Max Date
On select of the Apply Button viz, target the pMaxDate parameter passing in the value from the Max Date field.
Deselect Button
On select of the Apply Button viz on the dashboard, target the Apply Button sheet directly, selecting the fields True = False.
Finally add a floating text box to provide a key for the * indicator.