This week’s challenge was a guest post by Lisa Hitch to generate a pareto chart, but adding visual clues via background colours and lines to highlight the key areas of focus.
Ultimately, this was a relatively simple table calculation challenge, requiring just 2 calculations.
Just to see what these are doing, add Customer ID into Rows and Sales onto Text. Sort by Sales descending (this is a key feature in getting the pareto chape we need).
Create another field
cust count
COUNTD([Customer ID])
and add this into the table (we ultimately don’t need this field, but just creating so it’s clear what’s happening.
Add a Running Total quick table calculation to the cust count field – the field will now show a cumulative total down the table
Also create a field
total cust
TOTAL(COUNTD([Customer ID]))
Add this to the table too – every row reports the same – the total number of distinct customers int he data set.
Now adding Running Sum % of Customers into the table, you can see that the result of this field is a calculation of cust count and total cust. We could have broken it down like this, but I chose to just use a single calculation.
We could apply similar principals to the Sales field so you can see how this is derived, but hopefully you get the gist. Ultimatel, the data we need is below
On a new sheet, add Running Sum % of Sales to Rows, Running Sum % of Customers to Columns and Customer ID to Detail. Adjust both the table calculation to be explicitly computing by Customer Id and apply a sort on the Customer ID pill, to be sorted by Sales descending.
Change the mark type to Area and adjust the colour and set opacity to 100%.
To set the background colours, we’ll used fixed reference bands.
Right click the X-axis and Add Reference Line. Select Band and then set a constant from 0 to 0.1 and colour as required.
Repeat the process 4 more times, creating bands for 01-0.2, 0.2-0.8, 0.8-0.9 and 0.9-1.
The add reference lines to provide the 20% & 80% intersection lines. This time, select the Line option and again use constants, but rather than fill, select a thick white line
Again repeat to create a line at 0.8 on the X-axis. Then add reference lines to the Y-axis at the same intervals.
Add an annotation to the point where the X-axis = 20%. Use the tooltip to find the exact point where % of customers = 20% (this can be a bit fiddly), then right click and Annotate > Mark. Edit the annotation as required, then format the resulting text box as required. Repeat for the point at which the Y-axis = 80%.
Finish off by hiding all tooltips, removing all gridlines & row/column dividers, and fixing both axes from 0-1. Then add to a dashboard and you’re done.
For this week’s challenge, Yoshi introduced the new 2026.2 feature – the drive time selection tool. As a result you’ll need at least Desktop or Desktop Public v2026.2 to complete it. At the point of writing, it’s not available via Tableau Public web authoring, which also means you can’t interact with my published version on Tableau Public. You’ll need to download it to try it out.
Building the map
After connecting to the grocery store data, we need to define the location of each store to add to the map
Store Location
MAKEPOINT([Latitude],[Longitude])
Add this to the Detail shelf and the set the map background layer (Map menu > background layers) to streets, with a 30% washout. Uncheck all options except the top 3.
Add Object ID to Detail and Storename and Address to Tooltip. Change the mark type to circle and adjust colour as required, reducing opacity to 75% and adding a border. Adjust size as required too.
Create a new location for the Union Station, using the coordinates provided in the requirements
Union Station
MAKEPOINT(38.8977, -77.0063)
Drag this onto the map and drop when the ‘Add a marks layer’ option appears. This will create another marks card.
Change the mark type of this card to shape and select a star shape. Change colour and size. Adjust tooltip to read the word ‘Union Station’.
We now need to isolate the District of Colombia region. I confess, I got so far with this, but couldn’t get the area outside of the map to not be visible, so had to check out Yoshi’s solution.
Connect to a version of Superstore Data. Create a field
DC
IF [State/Province] = ‘District of Columbia’ THEN [State/Province] END
Make sure this field is assigned a geographic role of State/Province (right click field > Geographic role)
Drag DC onto the canvas to create another map layer. Change the mark type to Map. The shape of DC should be displayed.
Reduce the opacity of the colour to 0% and add a border.
Create another field
Not DC
IF [State/Province] <> ‘District of Columbia’ THEN [State/Province] END]
Set this to have a geographic role of State/Province.
Add this to the canvas, and set the mark type to Map.
Set the colour of this to a pale grey at 100% opacity with no border or halo. The move this marks card so it is below the DC one. This should make the border appear as the ‘DC’ card is now ‘on top’. Remove row/column dividers.
Set Disable Selection against both the DC and Not DC marks cards via the context menu against the card name
Adjust the map via zoom to ensure it fills as much as the canvas as possible, then update the map options (Map menu > map options) to ensure you can’t pan/zoom. Map should be pinned into position, and only the selection toolbar should be enabled, which includes the drive time selection tool.
Building the KPI
The number of stores is just the auto-generated count of the dataset. But we’re going to use a Set to capture the stores selected.
Create a set by right clicking o Object ID > Create > Set
Selected Stores
Don’t make any selections initially
Create field
# Selected Stores
SUM(IIF([Selected Stores],1,0))
Add this field and dc-grocery-clean.csv(Count) to Text. Change the mark type to shape, and assign a transparent shape. Set the canvas to Entire View and format the text as required and align the label top left.
Adding the interaction
Add the 2 sheets side by side on a dashboard using layout containers. Create a dashboard set action
Select Stores
On select of the Map sheet, add values to the set Selected Stores. When the selection is cleared, remove all values.
And that should be it. My published viz which you can download is here.
For this week’s challenge, Lorna asked us to complete the challenge by not using LoDs or Table Calcs. Parameters and parameter actions were necessary though (originally I started without using them either, as I misread the information).
Building the core bar chart
As mentioned, we’re going to use parameters to capture the info we need. So start by creating
pSelectedSubCat
string parameter to store the name of the Sub-Category selected – default to Storage
pSelectedSales
float parameter to store the Sales value of the selected sub category. Set this to 224,645 which is the value associated to Storage and set the display format to $ with 0dp.
The plan is that when ‘No Comparison‘is selected, the pSelectedSubCat will contain nothing ie an empty string of ” “, and pSelectedSales will be 0.
Based on this, we need to define the value to display in the bar, which typically is the difference between the Sub-Category sales and the sales of the pSelecedSubCat (ie the value in pSelectedSales). But in the event No Comparison is selected, we just want the sales. So create
is if we have a value in pSelectedSales, return the difference between the Sales value and it, otherwise just return Sales.
Set a custom number format of “$”#,##0;-“$”#,##0;””
Note the last setting after the 2nd “;” is the formatting for a 0 – in this case I’ve set it to ” ” ie nothing/<empty string>, so a value won’t get displayed against the bar of the selected Sub Category
Add Sub-Category to Rows and Difference to Columns. Explicitly sort the Sub–Category pill to be sorted by Salesdescending
Show mark labels, and widen the bars a bit. Adjust bar colour as required. Add a column grand total, and display at the top (Analysis menu > totals > show column grand totals, then Analysis menu > totals > column totals to top)
We’ve done this as we need the additional row at the top of the chart to align with the ‘No Comparison’ option in the selector we’ll build, but we don’t want the bar to show. To get rid of it, click on the bar and then select Hide from the ‘automatic’ drop down
which gives us
Hide the Sub-Category row heading and axis (uncheck show header from the pills). Remove all gridlines, row/column dividers and axis rulers/zero lines etc.
We’ll come back to this sheet later.
Building the selector sheet
We’re going to build this using a dual axis of a bar chart and a shape.
On a new sheet, add Sub-Category to Rows and again sort by Sales descending.
Double click into Columns and type MIN(-1.0)
Change the mark type to bar and widen each row a little. As before, add Column Grand Totals to the top.
Create a new field
LABEL: Sub Cat
IF MIN([Sub-Category])<>MAX([Sub-Category]) THEN “No Comparison” ELSE ATTR([Sub-Category]) END
If we just add Sub-Category to the label, the grand total row will show as ‘All’. The above is a sneaky way to change the word ‘All’, as in the ‘grand total’ row, all the Sub-Categories are ‘known about’, so the MIN(Sub-Category) and MAX(Sub-Category) are different.
Add this field to the Label shelf, and align left centre (the axis is -ve, so the alignment has to be to the left, even though it’s displayed on the right).
We need to be able to identify which row (including the grand total row) has been ‘selected, so create
Is Selected SubCat
ATTR([Sub-Category]) = [pSelectedSubCat] OR ([pSelectedSubCat]=” AND [LABEL: Sub Cat ] = ‘No Comparison’)
And add this to Colour, and colour the True to match the bar chart colour you chose, and Null and False to white (so it ‘disappears)
Now create a secondary axis by double clicking into Columns and type MIN(-0.9). Change the mark type to Shape. Remove Label: SubCat from the marks card. Create a duplicate of Is Selected SubCat so you have Is Selected Subcat (copy) and add this field to shape and to Colour and set the colour and shape as required
Make the chart dual axis and synchronise the axis. Hide all the axis and the row headings and remove all row/column dividers, gridlines etc.
Building the dashboard and adding the interactivity
Create a dashboard and using a horizontal layout container arrange the Selector sheet and the Bar sheet side by side, ensuring both ‘fit entire view, which will make sure the rows all align with each other.
We need to change the values of the pSelectedSubCat and pSelectedSales parameters on click of either chart. When we do this, we need to pass the relevant values into the parameter. Because we also have to handle the ‘grand total’ row, we need some additional fields for this
Sub Cat for Param
IIF([LABEL: Sub Cat ]=’No Comparison’,”,ATTR([Sub-Category]))
ie use ‘nothing if the ‘grand total’ is clicked, otherwise use the Sub-Category
similarly
Sales for Param
IIF([LABEL: Sub Cat ]=’No Comparison’,0,SUM([Sales]))
ie use 0 f the ‘grand total’ is clicked, otherwise use the Sales value of the Sub-Category
Add both these pills to the Detail shelf of the All marks card on the Selector sheet, and to the Detail shelf on the Bar sheet.
On the dashboard, create a dashboard parameter actions
Set Sales Value
On select of either sheet, set the pSelectedSales parameter, passing in the value from the Sales for Param field aggregated at the SUM level. Set to 0 when selection cleared.
Set Sub Cat
On select of either sheet, set the pSelectedSubCat parameter, passing in the value from the Sub Cat for Param field. Set to “” when selection cleared.
Finally, as we are already differentiating the ‘selection’ through different colours, we don’t want the click to ‘hihglight’ the mark. Create a new field
Dummy
“HL”
and add this to the Detail shelf on both sheets
Then create a dashboard Highlight action
Highlight
On select of either sheet, target either sheet but only with the selected Dummy field.
And that in principle should give you a functioning solution. The only extension I made, as to make the Tooltips on the bar chart make sense depending on what was being viewed. This involved building up a series of Tooltip Text fields. Check out my solution if you need to see the details.
Kyle took inspiration from the 2026 FIFA World Cup for this week’s challenge, looking at how many miles each team need to travel between their base camp and the stadiums where their group matches are being held. He sourced some data which he provided for download.
Modelling the data
The data provided contained 3 sheets. Kyle gave some hints on how he’d used the data, but nothing specific, so I just related the sheets in the following way, to see whether this would be enough.
I related Schedule to Base Camp, but BEFORE I applied the relationship join condition, I pivoted the Schedule data (as Kyle had hinted this may be required). I did this by
Adding Base Camp to canvas
Then adding Schedule to canvas
Then clicking on the Team A and Team B columns in Schedule, and selecting Pivot
The renamed Pivot Names field heading to Team A | B
and renamed Pivot Values field heading to Team1 (I couldn’t call it Team as this field already exists in Base Camp)
I then created a relationship between Base Camp.Team and Schedule.Team1
The add Venues to the canvas a relate to Schedule on the Venue field.
Creating the Map with all locations
For the maps we need to work with spatial data, and need to define the location of each base camp and each venue. The data sets had longitude and latitude fields for both types of location, but for some reason, both the longitude fields were resolving as string fields. So I had to change these to geographic fields by the following steps
right click Base Camp > Longitude, and change data type > number (decimal)
then right click field again , geographic role > latitude
repeat same 2 steps for the Venues > Laitude (Venues) field.
On a new sheet, add Venue Location to Detail, and Venue to Detail. Change the mark type to circle. Adjust the map background layers so only the Base, County/Region Names and State/Province border options are selected (Map menu > background layers)
Create a parameter to store the name of the selected team we want to focus the data for
pTeam
string parameter defaulted to ‘Austria’
Create a field
Is Selected Team?
Team = [pTeam]
Add this to Colour and Size and adjust accordingly. Make sure the ‘true’ is listed first so that the marks for the selected team are ‘on top’ . This will require the Size to ‘be reversed’
Remove all text from the Tooltip
Drag Base Location onto the display and drop it when ‘Add a Marks Layer’ option appears, which will create a 2nd marks card
Drag this card to be beneath the Venues one. Change the mark type to circle. Add Team to Detail. Add Is Selected Team to Colour and Size. Add Training Site and City to Tooltip and update accordingly.
Then click on the context menu of the Venues marks card, and disable selection
Nowt drag Line on to the canvas to make another marks layer. Again move this marks card to the bottom of the list, so it’s beneath the Base Camp marks card. Add Team to Detail and Is Selected Team to Colour. Create a copy of Is Selected Team (right click field and duplicate to create Is Selected Team (copy)) and add this to Size and adjust. I found I needed a copy so I could have different sizes between the circles and the lines Add Training Site and Distance to Tooltip and update the Tooltip accordingly. Remove row & column dividers.
Creating the ‘Team specific’ map
The easiest way I found to do this initially, was just to duplicate the sheet with the above map, and then add Is Selected Team to the Filter shelf, and set to True. This gives us the display we need, but tooltips need changing.
Re-enable the Venues marks card. We’ll need to display information about the match on the venues tooltip, wihich includes details for the teams playing.
As we initially pivoted the data, this information is now across 2 rows, so we need to create fields to capture both the teams on each row. I used FIXED LoDs for this:
Team A
{FIXED [Match]:MIN(IF [Team A | B]=’Team A’ THEN [Team_1] END)}
Team B
{FIXED [Match]:MIN(IF [Team A | B]=’Team B’ THEN [Team_1] END)}
Add these to Tooltip, along with Training Site, Date, Time (Local) and Distance. Format the Date field to “Month, Day Year” format, and custom format the Time (Local) field to h:nn AMPM. The adjust tooltip to suit.
Now do similar to the Line marks card – add Match to the Detail shelf as a blue disaggregated discrete pill, and then add Team A, Team B, Venue, Date and Time(Local) to the Tooltip and update accordingly.
Create the Bar Chart
On a new sheet, add Is Selected Team and Team to Rows and Distance to Columns. Sort descending. Order so Is Selected Team : True is listed first.
Make the rows a little wider. Add Is Selected Team to Colour. Add Team to Label. Adjust Label so the team name is aligned left and coloured in white bold text. Adjust the Tooltip. Add a Reference line to the Distance axis to show per cell the value of the sum of the distance. Don’t show line or tooltip.
Format the reference line, so the numbers are aligned in bold font, middle right
Hide the Is Selected Team, Team and Distance headers & axis (right click pill > uncheck show header). Then remove all row/column dividers and gridline, axis rulers etc.
Finally create 2 fields
True
TRUE
False
FALSE
and add these to the Detail shelf (we’ll need them later to ensure the bar doesn’t highlight when we select values).
Creating the match cards
On a new sheet, add Is Selected Team to Filter and set to true.
We need to identify which match is match 1st, 2nd and 3rd. I did this using the dates, but in hindsight could have used the Match field which just contains an unique number per match… anyway…
Match 1 Date
{FIXED [Team_1] : MIN(Date)}
Match 3 Date
{FIXED [Team_1] : MAX(Date)}
Match No for Team
IF [Date] = [Match 1 Date] THEN ‘Match 1’ ELSEIF [Date] = [Match 3 Date] THEN ‘Match 3’ ELSE ‘Match 2’ END
Add Match No for Team to Filter and set to Match 1.
Chang the mark typeto shape and set to use a transparent shape (see here for more details on this). Then add Match No for Team, Match, Venue, City (Venues), Distance, Date and Time(Local) to Label. Format the date and time field as you did above.
Create a field
Opponent
IIF([Team_1]=[Team A],[Team B],[Team A])
and add this to Label too. Then adjust the label as required, and align middle left. Don’t show tooltips.
Duplicate this sheet and change the filter to select Match 2 for match 2, and then repeat for Match 3 so you have 3 separate sheets for the matches.
Creating the ‘team’ sheet
On a new sheet, add Is Selected Team to Filter and set to True. Set the mark type to shape and use a transparent shape. Add Team, Distance, Training Site and City to Label and adjust and format accordingly, aligning left middle. Don’t show tooltips.
Building the dashboard and adding the interactivity
I set the background of the dashboard to dark grey and then used layout containers to organise the content, using padding and rounded corners to style as required. The layout of my dashboard is pictured below. It will take some time to get this layout just right, and you might find that in Desktop some text doesn’t display but will when published on Public.
Add a parameter dashboard action to change the team when the bar chart is clicked on
Set Team
on select of the bar chart sheet, set the pTeam parameter with the value from the Team field.
To prevent the selected bar from being ‘highlighted’ when clicked, add a dashboard filter action
Deselect Bar
On select of the bar chart on the dashboard, target the bar chart sheet directly, setting fields true = false.
After a couple of weeks off due to holiday, it was my turn to set the challenge. When browsing around for inspiration, I came across this stem & leaf Power BI WOW challenge by Meagan Longoria, which in turn was inspired by a Tableau WOW challenge set by Yusuke in 2024.
So I thought it would be fun to go ‘full circle’ and see if I could recreate Meagan’s challenge in Tableau, which builds on Yusuke’s challenge, as this requires the ‘leaves’ to be spread across multiple rows.
Defining the calculations
The data set provided contains a rows uniquely identified by a Row ID, and each row defines a Species of Iris and the Petal length, which is a decimal number in cm.
To build the stem and leaf chart, we need to first identify the Stem and then the Leaf. If the length is 4.6cm for example, then the stem is 4 and the leaf is 6.
Stem
INT([Petal length (cm)])
Format this to a number with 0 dp and move to the ‘dimensions’ section of the data pane (above the line).
Leaf
INT(ROUND(([Petal length (cm)] – [Stem])*10,0))
Again, format this to a number with 0 dp and move to the ‘dimensions’ section of the data pane (above the line).
Note – Originally my function was INT(([Petal length (cm)] – [Stem])*10), but I found in some occasions this wasn’t given me the right values eg 4.1 was reporting a Leaf of 0, due to the precision of the original number stored. Using the ROUND function to convert the number to have 0 dp resolved this.
Put all these fields into a table like below, so we can start to sense check the other calculations we’ll need.
The final chart will plot the ‘leaves’ as points on an X and Y axis. The central ‘spine’ of the chart is where X=0, and the leaves are the plotted with the position based on the Stem value and then which row and column the leaf is in. Records associated to the Iris-versicolor Species will be plotted on the left side (negatives) while the Iris-virginica Species will be plotted to the right (positives).
The leaves need to organised into rows of 10 per Stem, per Species, sorted by the Leaf value (smallest first). To manage this, we first need to understand how many leaves are associated with each Stem and Species, and give them a ‘counter’ (ie index) per Stem/Species cohort.
Leaf Index per Stem
/* For each stem per species, index the leaves from 1 to however many there are in the cohort. */
INDEX()
Add this into the table, and adjust the table calculation so it is computing by Leaf and Row ID only and add a Custom Sort by Leafascending
We now want to identify which ‘row’ (per stem) the leaf will sit on based on it’s index number. If there’s more than 10 leaves per stem, then we need to plot on multiple rows, where the row count starts at 1. Dividing Leaf Index per Stem by 10 will help us do this, but as all leaves indexed from 1-10 need to be on the 1st row, we need to subtract 1 from the index before we divide. We can then convert to a whole number with the INT function, but as we want rows to start at 1, we then need to increment.
Leaf Row Number
INT(([Leaf Index per Stem]-1)/10) + 1
Eg
Leaf Index = 4 -> subtract 1 = 3 -> divide by 10 = 0.3 -> apply INT function = 0 -> add 1 = row 1
Leaf Index = 10 -> subtract 1 = 9 -> divide by 10 = 0.9 -> apply INT function = 0 -> add 1 = row 1
Leaf Index = 11 -> subtract 1 = 10 -> divide by 10 = 1.0 -> apply INT function = 1 -> add 1 = row 2
Add this into the table and apply/verify the table calculation settings are as above.
We then want to identify which column each leaf should be in, which should be a number between 1 and 10 for Iris-virginica and -1 to -10 for Iris-versicolor. We can use the modulo (%10) function for this, based on the Leaf Index per Stem value, to find the remainder if the index is divided by 10. Similarly to before, as all leaves indexed from 1-10 need to be in the equivalent numbered column, we first need to subtract 1 from the index before we find the remainder, but then we need to add 1 to the final result, to get the desired result.
This is essentially just taking the Leaf Column Number and making it negative for the Iris-versicolor Species. We’ve wrapped it in a FLOAT to make the number decimal, as we need the axis to be able to handle decimal values later on.
For the Y Axis, we’re going to plot the leaves on rows at intervals of 0.2 related to the stem position
Y Axis
MIN([Stem]) + (0.2 * [Leaf Row Number])
Add these into the table and apply/verify the table calculation settings are as above.
Building the viz
Now we have the core data we need, we can start to build the viz
On a new sheet, add Species, Row ID, Stem and Leaf to Detail. Then add X Axis to Columns and Y Axis to Rows. Adjust the tableau calculation settings as before (remembering to apply the custom sort too!)
Change the mark type to circle. Add Species to Colour and adjust as required, adding a coloured border. Set the sheet to Entire View. Increase the Size a bit, then move Leaf from Detail to Text. Align middle centre and bold and allow labels to overlap. Reverse the Y Axis.
Fix the Y-Axis from 2.5 to 7 and set the tick marks to occur at intervals of 1.
Format Petal length (cm) to be a number with 1 dp, then add to Tooltip and adjust accordingly.
Set the background of the worksheet to pale blue. Remove column gridlines. Set the row gridlines to be a pale blue. Remove zero lines, axis rules & tick marks.
To plot the Stem value, double click into the Columns and manually type MIN(0.0) to create a second axis. Remove all the fields except Stem from the marks card of this axis. Change the mark type to shape and use a transparent shape. Move Stem onto Text and align middle centre and increase font size and make it bold. Clear all the text from the Tooltip associated to this mark.
Make the chart dual axis and synchronise the axis. Then add a Reference Band to the X-Axis which plots at -0.5 to 0.5, formatted with a blue line and a pale yellow fill.
Finally, hide all the axes (uncheck show header) and remove row & column dividers.
Add to a dashboard, using containers to organise the content. Use a horizontal container above the main viz to add text fields to label the parts of the chart. Ensure the chart specific title, the label headings and the chart itself are in a vertical container which can then have formatting applied (border/ curved edges etc). My dashboard item hierarchy is shown below
Sean used some Super Bowl data for this week’s #WOW2026 challenge , using Gantt charts to display ‘arrowed bars’.
Creating the calculations
It took me a little bit of time to understand what I needed from the data to create the required visualisation, so let’s tackle that first.
We need to know the Season and the number of the Super Bowl in roman numerals. The Super Bowl field has this info as it displays <Super Bowl Number as integer> (<year>) ie 4 (1970) – the 4th Super Bowl for Season 1970.
To quickly generate the data I needed, I used the Split function on the Super Bowl. field (Right click > Transform > Split). This automagically generates fields Super Bowl – Split 1 containing the numeric number and Super Bowl – Split 2 containing the year.
I simply renamed Super Bowl – Split 2 to Season, but for completeness, this is what the calculated field looks like
I then renamed Super Bowl – Split 1 to SB Number (int) and changed the data type from string to whole number. Again the field looks like
SB Number (int)
INT(TRIM( SPLIT( [Super Bowl], “(“, 1 ) ))
But I want the number in the format SB + roman numerals. A quick search on the web, and I found the required logic needed to make the conversion, so I created
SB #
“SB ” + // Thousands Place CASE INT([SB Number (int)] / 1000) WHEN 1 THEN “M” WHEN 2 THEN “MM” WHEN 3 THEN “MMM” ELSE “” END +
// Hundreds Place CASE INT(([SB Number (int)] % 1000) / 100) WHEN 1 THEN “C” WHEN 2 THEN “CC” WHEN 3 THEN “CCC” WHEN 4 THEN “CD” WHEN 5 THEN “D” WHEN 6 THEN “DC” WHEN 7 THEN “DCC” WHEN 8 THEN “DCCC” WHEN 9 THEN “CM” ELSE “” END +
// Tens Place CASE INT(([SB Number (int)] % 100) / 10) WHEN 1 THEN “X” WHEN 2 THEN “XX” WHEN 3 THEN “XXX” WHEN 4 THEN “XL” WHEN 5 THEN “L” WHEN 6 THEN “LX” WHEN 7 THEN “LXX” WHEN 8 THEN “LXXX” WHEN 9 THEN “XC” ELSE “” END +
// Ones Place CASE INT([SB Number (int)] % 10) WHEN 1 THEN “I” WHEN 2 THEN “II” WHEN 3 THEN “III” WHEN 4 THEN “IV” WHEN 5 THEN “V” WHEN 6 THEN “VI” WHEN 7 THEN “VII” WHEN 8 THEN “VIII” WHEN 9 THEN “IX” ELSE “” END
Let’s add the fields we need into the table; add Season and SB# into Rows and sortSeason to be listed descending.Then add O/U Line to Rows as a discrete dimension (blue dis-aggregated pill).
Note – I added the results of the 2026 Super Bowl into the provided data set.
We need to compare the O/U Line number with the combined score of the match. The score can be found in the Final field which has info of the winning team and score eg for PHI 40-22, the combined score is 40+22 = 62. I again used the Split functionality to extract the data needed.
The automatically created field Final – Split 2 contains the 2nd half of the score. I renamed this and changed the data type to a whole number
Result Part 2
INT(TRIM( SPLIT( [Final], “-“, 2 ) ))
I then ‘split’ Final – Split 1 again. The automatically created field Final – Split 1 – Split 2 contains the 1st half of the score. I again renamed and changed data type to int.
Result Part 1
INT( SPLIT( [Final – Split 1], ” “, 2 ) )
I then created
Combined Score
[Result Part 1] + [Result Part 2]
and
O/U Difference
[Combined Score]-[O/U Line]
Pop these onto the table along with the Result field and we have all the fields we need to build the viz
Building the viz
ON a new sheet, again add add Season and SB# into Rows and sortSeason to be listed descending.Then add O/U Line to Rows as a discrete dimension (blue dis-aggregated pill). Add Combined Score to Columns and change the mark type to shape. Add Result to Shape and set the filled arrows shapes accordingly. And add Result to Colour and adjust that too.
Add O/U Line to Columns which will create a 2nd marks card. Click on this marks card, and change the mark type to Gantt Bar. Remove the Result pill that is now listed on the Detail shelf (keep the one on Colour). Add O/U Difference to the Size shelf, and then click on the Size shelf, and reduce the width a little.
Make the chart dual axis and synchronise the axis. Remove the Measure Values pill from the colour shelf of the All marks card.
Now add O/U Difference to Columns and change the mark type to bar. Remove the Result pill from this card. Adjust the colour and reduce the Size.
In the solution, these bars have rounded ends, so add another instance of O/U Difference to Columns. Change the mark type to Circle, and set the Colour to match the bars. Make the char dual axis and synchronise axes. Adjust the size of the circle and/or bar marks, so the circle makes the bar look like it has a rounded end.
And that’s the crux of the challenge. Formatting changes include
Set background colour of worksheet
Remove all gridlines, zero lines, axis rules/tick marks
Remove all row & column dividers
Add row banding
Add Season to Filter and exclude 1967
Adjust axis titles
Adjust formatting style of the Season, SB #, O/U Line values
Add title and description
And then add to a dashboard, and you’re all set. My published viz is here.
Lorna set this week’s challenge inspired by a challenge first set in 2018 that was a ‘combo’ challenge with Prep : use Prep to generate the data set, then visualise. In this instance, we’re doing all the data calculations in Desktop itself (and adding on a few extra too).
Building out the calculations
We need to find the first purchase date per customer, so we use a FIXED LOD for this (we’ll be using a lot of these 🙂 )
First Purchase Date
{FIXED [Customer ID]: MIN([Order Date])}
We then want, for each customer, then next purchase date, which is the earliest order date, where the date is after the first purchase date
IF SUM([First Purchase Sales]) >= SUM([Second Purchase Sales]) THEN ‘First Purchase Higher than Second Purchase’ ELSE ‘Second Purchase Higher than First Purchase’ END
Let’s put all this into a table
To determine the type of outlier, we need more fields. We need to get a value for the average of all the First Purchase Sales
Avg First Purchase Order Value
{AVG([First Purchase Sales])}
note this is a short notation for {FIXED:AVG([First Purchase Sales])} and is an instruction to average across the whole data set, as we want a single value that is the same for all the rows of data. We also need
Avg Second Purchase Order Value
{AVG([Second Purchase Sales])}
Pop these into the table too
and we need to know what the standard deviation is for each value, which again are essentially ‘a constant’ across the whole data set
First Purchase Std
{FIXED :STDEV([First Purchase Sales])}
and
Second Purchase Std
{FIXED :STDEV([Second Purchase Sales])}
And now we can determine the outlier type for each customer
Outlier Type
IF SUM([First Purchase Sales])>=10000 OR SUM([Second Purchase Sales]) >= 10000 THEN ‘High Purchase Outlier’ ELSEIF SUM([First Purchase Sales])> (SUM([Avg First Purchase Order Value])+ (3*MIN([First Purchase Std]))) AND SUM([Second Purchase Sales]) > (SUM([Avg Second Purchase Order Value]) + (3*MIN([Second Purchase Std]))) THEN ‘Outlier’ ELSEIF SUM([First Purchase Sales])> (SUM([Avg First Purchase Order Value])+ (3*MIN([First Purchase Std]))) THEN ‘First Purchase 3STD Outlier’ ELSEIF SUM([Second Purchase Sales]) > (SUM([Avg Second Purchase Order Value]) + (3*MIN([Second Purchase Std]))) THEN ‘Second Purchase 3STD Outlier’ ELSE ‘Within Range’ END
Add the Outlier Type into the table and also add to Filter and show the filter, and do some checks on the different types
We’ve got all the data, now we can build.
Building the chart
ON a new sheet, add First Purchase Sales to Columns and Second Purchase Sales tp Rows. Add Customer ID to Detail. Add Purchase Diff to Shape and adjust accordingly. Hide the null indicator
Add Difference Between Purchases to Size and adjust mark size range to suit
Add Outlier Type to Colour, and then add another instance of Purchase Diff to Detail, then click on the ‘detail’ icon to the left of the Purchase Diff pill on the marks card, and change it to Colour, so 2 pills are on the Colour shelf. Adjust colours to suit.
Add Outlier Type to Filter and show the filter and uncheck the High Purchase Outlier option. Then add Customer Name to Tooltip and adjust to suit.
To make the diagonal ‘reference line’, add another instance of First Purchase Sales to Rows. This creates another marks card. Remove all fields from this card, except Customer ID and change the mark type to Line. Remove all text from the Tooltip for this marks card.
Make the chart dual axis and synchronise the axis.
Format the chart by
hide the second axis (uncheck show header)
set the row and column dividers to not display on the header sections (but to display on the pane sections)
Set background of worksheet to grey, but set the pane background to white
And that should be the build
Create dashboard, and use a horizontal layout container. In the right hand side, add the viz. In the left side, add a vertical container and use text objects to display the information, and add the filter control into this section too. Use a blank object to make a vertical divider, and add a border around the ‘parent container’.
It’s Tableau Conference week, so this week’s challenge, set by Yoshi, was presented as part of the live session at #TC26. Yoshi set 3 levels of the challenge, to represent session data from TC25. I managed to get through the Basic and Bonus challenges
Building the Basic KPI sheet
After connecting to the data set, create a new field to determine if the session is AI related or not
AI-related
CONTAINS([Title], “AI”) OR CONTAINS([Title],”Agent”) OR CONTAINS(IFNULL([Topic],”),”Agentic Analytics”) OR CONTAINS(IFNULL([Topic],”),”Artificial Intelligence”)
Add this to the Text field on a new sheet, then adjust the text to include the rest of the words, adjusting the font style and colour as required.
Building the basic calendar sheet
Format Start Time and End Time to custom date format of hh:nn, and format Date as mmm dd
On a new sheet add Date as a discrete exact date (blue pill) to Columns and Start Time as a continuous exact date (green pill)to Rows, and edit the Start Time axis so it is reversed.
Add ID to Detail and change the mark type to circle. Create a new field
Index
INDEX()
and add this to Columns
Add AI-related to Colour and adjust accordingly. The edit the Index table calculation so it is computing by Id and AI-related only and sorted by the min value of AI-related descending, so the AI related sessions are listed first
Format the Start Time axis, so the Scale is formatted as h AM/PM and change the font style to larger, blue and bold
Format row and column dividers in the pane only to be thicker blue lines, with no dividers on the headers
Add thin blue gridlines to the Rows and remove column gridlines and zero lines
Edit the Start Time axis again, and set the Tick Marks to start at 08:00 and display every 2 hours
Remove the axis title. Hide the Index axis (right click, uncheck show header). Format the Date header fields (large, blue, bold) and remove the Date label (right click – hide field labels for columns).
Add Title, Description, Start Time and End Time to Tooltip and adjust accordingly.
Add both sheets onto a dashboard, and add an additional Text object to contain the additional explanation.
As before, add this to the Text field on a new sheet and adjust text to contain the additional wording and formatting.
Building the Bonus Calendar Sheet
Start by duplicating the basic calendar sheet. Add Session Duration to Size.
The sessions need to be sorted by the longest durations first, while still be grouped with AI -related sessions listed before non AI session. Create a new field
Sort
[Session Duration] + (INT([AI-related])*100)
I’m basically creating a numeric value to sort by, based on the duration. adding 100 if the session is AI related, ensuring the Sort value for even the shortest AI session (20 mins) will be larger than the longest non AI session (90 mins).
Adjust the Sort property on the Index field table calculation, to now sort by the minimum of Sort descending
Adjust the tooltip to include the Session Duration, and you should be done.
Duplicate your basic dashboard, then use the ‘object swap’ feature to change the 2 vizzes
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
For this week’s community challenge, we’re recreating radar charts using fellow Tableau Ambassador and Visionary, Johan de Groot‘s, map layers technique, which he has blogged about here.
Modelling the data
I provided 3 sets of data in one excel workbook
Gridlines : a basic template to help build the radial gridlines
Engagement Survey Data – Filled : for use with the filled area chart radar display
Engagement Survey Data – Line: for use with the non-filled line chart radar display
The Engagement Survey Data – Line data contains an extra ‘Dummy’ theme which has values that exactly match the values associated to Theme ID 1. This helps ensure the lines ‘join up’ once plotted.
Each Engagement Survey Data needs to be related to the Gridlines data by a custom calculation of 1 = 1
Building the Filled Area Radar Chart
Model the data as described above using the Engagement Survey Data – Filled data set.
Create a new parameter
pArea
string parameter, which can be populated as a list using the Add values from option, and then removing the Whole Company and Benchmark options. Default to Finance
Drag Point to the Detail shelf. Change the mark type to Polygon and add Theme ID to the Path shelf.
Set opacity on Colour to 30% and add a black border. Set the the Background Layers (Maps > Background Layers) to show nothing: untick all options. Also remove all map options ( (Maps > Map Options -> uncheck all options.) Remove row/column dividers.
Create a new field
Area to Display
IF Area = ‘Benchmark’ OR [Area] = ‘Whole Company’ OR [Area] = [pArea] THEN [Area] END
and add to Colour. Exclude the Null option that display (right click -> exclude; this will automatically add the pill to the Filter shelf). Adjust colours as required.
Add this to the view as a new marks layer (drag onto canvas and drop when you get the option displayed)
This will create a new marks card – add Theme ID to the Detail shelf.
Adjust the size and colour of the spokes as required.
Create a new field
Outer Points
MAKEPOINT(cos([Angle]), Sin([Angle]))
Add this as another marks layer. Change the mark type to circle. Reduce the opacity to 0% and size to as small as possible. Add Themes to the Label shelf.
(If you wish, you can format the text to wrap a bit, by creating
Label – Theme formatted
REPLACE([Themes],” “, “ “)
and putting this on the Label shelf instead
You can adjust the labels using the label alignment options, but you may need to manually move the labels to get them positioned in an acceptable place.
Create a new field
Radar Labels
IF [Theme ID]= 1 AND [Position] <=10 THEN MAKEPOINT(cos([Angle])*[Position], Sin([Angle]) * [Position]/10) END
and add as another marks layer and change mark type to circle. Again reduce opacity to 0% and size as small as possible.
Create a new field
Value Axis
IF [Position]%2 = 0 THEN [Position] * 10 END
and add to the Label field of the Radar Labels marks card as a Continuous dimension (unaggregated green pill)
To add gridlines, create
Grid Lines
IF [Position]<=10 THEN MAKEPOINT(COS([Angle])*[Position]/10, SIN([Angle]) * [Position]/10) END
and add as another marks layer. Change the mark type to polygon, and add Position to Detail and Theme ID to Path. Set the colour to pale grey at 5% opacity and add a darker grey border.
Finally add Value to the Tooltip of the original Point map layer marks card and adjust tooltip. Then make all the other may layers ‘disabled’ so the can’t be clicked on.
Show the pArea parameter and change the values to see the areas change. This is now the core ‘filled’ radar, which you can add to a dashboard.
If you duplicate the sheet for the radar chart you’ve just made, and change the original Points marks card from Polygon to Line, you will find that the lines don’t join up. This is why we need to adjust the source data to introduce a ‘Dummy’ theme with the values that match the first theme.
Model the data as described above using the Engagement Survey Data – Line data set.
Create all the same fields as detailed above, but some are adjusted as follows :
There is a slight difference here, in that 1 is subtracted from the count of themes, as we don’t want to be counting the ‘Dummy’ theme, otherwise we get an extra ‘spoke’.
Label – Theme Formatted
IF [Theme ID]<> 10 THEN REPLACE([Themes],” “, “ “) END
adjusted to only return labels that aren’t related to the Dummy theme.
When you add the Point field as the first map layer, change the mark type to line instead of polygon to get the display below.
Then continue to build as described above. Adjust the colourings and amount of opacity as you see fit.