Category: Quick Tips

  • Text Bars

    Text Bars

    The most memorable Tableau trick that I encountered at DataFam Europe this year was something that I already knew of (vaguely), but seeing it twice brought it to my attention and now it won’t be pushed to the back of my trick cupboard again.

    This was presented both by Andy Cotgreave in DataFam Slam (minute 36:00), and by Nhung Le in Tremendous Tableau Tips (minute 20:00), with different context (you need to register for Salesforce+ to see the videos). I’ll discuss just the technique, and what it can be used for.

    So what are text bars? You can use a text field in Tableau to create a horizontal bar, and also manipulate its length using the data. This is possible due to the existence of the Unicode characters “█” (U+2588: Full Block) and “▒” (U+2592: Medium Shade).

    Let’s say we want to display our count of orders per customer, which is not a very large number, in bars within the table header. We create a calculated field:

    REPLACE(SPACE([No. of Orders]), ” “, “█”)

    The SPACE function returns a number of spaces as defined in the parameter that you give it (up to a limit, of course – don’t try to exceed 100 or so), and then we replace them with the Full Block character. The result is a text bar, that can be placed as a header in the rows of out worksheet:

    The label at the end is a simple concatenation:

    REPLACE(SPACE([No. of Orders]), ” “, “█”) + ”   ” + STR([No. of Orders])

    Another option is to use the text bar to display a percentage value, though it has to be rounded. In this example I am rounding to the nearest 5%, and filling up the 100% with the partially shaded bar:

    REPLACE(SPACE(ROUND(MAX([Profit Ratio], 0) * 20)), ” “, “█”)
    +
    REPLACE(SPACE(ROUND(20 – MAX([Profit Ratio], 0) * 20)), ” “, “▒”)

    Note the MAX function, which I am using to eliminate negative values.

    The end result is below. No concatenated label this time, because formatting the percentage value to a string is complicated, so I simply added the Profit Ratio value as the next field. The Segment field is there to show that the bars are within the header.

    Andy showed how text bars can be used within tooltips (before Viz in Tooltip was released), but I’m sure the community will think up other implementations, apart from the simple spicing up of a table that I showed, and probably using other special characters as well.

  • Tabbed Views

    Tabbed Views

    Every time we publish a workbook in Tableau, to Server, Cloud, or Public, we have the option to select the “Show sheets as tabs” checkbox. Obviously, this affects the display of the worksheet/dashboard tabs at the top of the view, but what else? And how has it changed over the years?

    Permissions

    A workbook with tabbed views counts as one entity for permissions. Any user who can access one view, can see all the others as well. They can also move between the views using the tabs, of course – that’s why the permissions can’t be separated: the display shows all the published tabs by default, so the user has access to them.

    If tabbed views are disabled, each view in the workbook has its own permissions. Users can’t move between them using tabs, and they have to exit back to the workbook level first – so permissions can be set separately, if required. I won’t go into detail about how to actually set permissions at the view level, the documentation is here.

    This enables the owner of the workbook, or administrator, to fine-tune the permissions if necessary, so some users don’t have access to certain dashboards, even in the same workbook – and in certain scenarios this is definitely a relevant use case.

    Dashboard Size

    The lesser known effect of setting tabbed views is the dashboard sizing. When tabbed views are on, all dashboards will be displayed as the same size in the browser, and if some have different sizes, the largest is used for all.

    What does this actually mean? If all dashboard sizes are set to “Automatic”, then there’s no problem. But suppose that you have one long-form dashboard in the workbook, with a fixed height of 3000 pixels that enables the user to scroll down. If tabbed views are on, all the dashboards will enlarge to 3000 pixels in height. And the same goes for the width, of course.

    If tabbed views are off, there are no such limitations, and every view can have a different size.

    Navigation

    One of the features that has changed over time is the navigation between views. In previous versions of Tableau, turning off tabbed views disabled the filter actions that navigate between views. I don’t recall in which version this changed, but now all the navigation options work even when tabbed views are off: filter actions, go to actions, and navigation buttons.

    This was actually a serious limitation in the past, because you nearly always had to compromise on something – the permissions, size, or navigation. Now that there are no limits on navigation, it’s much easier to decide which option to choose.

    One exception, of course – if tabbed views are off, you can’t navigate to a view for which you don’t have permissions. There are different results: a filter action simply won’t do anything, while a navigation button is grayed out and will display an “Access denied” message if clicked.

    Performance

    Even though there are still some resources on the internet saying that when you open a workbook with tabbed views, Tableau calculates all the dashboards in the workbook, that is totally incorrect.

    There is no difference in performance between tabbed and un-tabbed views. Tableau loads a view only when it is accessed by the user, and it always loads the workbook metadata when you access the first view – because it is stored as a single XML file. I have verified this using performance recordings, but it was always rather obvious: I’ve seen tabbed workbooks with 20-30 dashboards loading the first one in no time at all, so there’s no way all of them were calculated within that time. So don’t worry, if you have performance issues they won’t be caused by the tabs.

    Summary

    Tabbed ViewsNo Tabs
    PermissionsSame for all viewsCan be set separately
    Dashboard SizeBy largest viewIndependent for each view
    NavigationOKLimited only by permissions
    PerformanceOKOK

  • Nested Table Calculations

    Table calculations are one of the most used features of Tableau, but some of their capabilities are less well known, and I’d like to dwell on one of these: Nesting.

    Nesting table calculations occurs when one calculated field references another. That’s not a problem in itself, but what happens when we want each of these to behave differently? Compute the first using Table (across), and the second using Table (down)? I’ve found out that many developers don’t know how to do this, so here is a brief explanation.

    Let’s illustrate it using an example, based on Superstore data. I want to display sales by Product Sub-Category and period, and highlight the top 3 increases in sales for each period.

    I start by creating a simple table with sales by Sub-Category and Year:

    The first calculated field is the difference between each year and the previous year:

    Period Change:     ZN(SUM([Sales])) – ZN(LOOKUP(SUM([Sales]), -1))

    Note that this can easily be created using the Quick table calculation menu below, but then the next step would be impossible.

    Now I use this field in another table calculation:

    Period Change Rank:    RANK([Period Change]) <= 3

    This should return True for the top 3 changes per period (currently Year). I drag the field to Color, but after I set the colors that I want (green and white), I can’t get the correct results using the “Compute using” options.



    This is where the nested option is necessary, because the difference is calculated across the table (by rows), while the rank is calculated down (by columns). I open the “Edit table calculation” dialog box:

    Note that now there is a “Nested Calculations” dropdown, where I can choose the calculation option for each field, and now I can set “Table (across)” for Period Change and “Table (down)” for Period Change Rank. The result is now correct – the highlighted green cells are the top 3 increases for each year.



    To summarize – table calculations can be nested in two levels or more, and it is important to know that you have the option to set the “Compute using” option of each calculated field separately, enabling various types of analyses.

  • DATETRUNC

    One of the most underrated functions in Tableau, in my opinion, is DATETRUNC. Underrated, underused, and not understood. Recently I was disappointed to read a whole book about Tableau in which it wasn’t mentioned even once.

    Technically speaking, DATETRUNC “truncates” any date value to the starting point of the period: year, quarter, month, week, and so on. For example:

    NOW()29/08/2025 16:14:35
    DATETRUNC(“hour”, NOW())29/08/2025 16:00:00
    DATETRUNC(“day”, NOW())29/08/2025 00:00:00
    DATETRUNC(“week”, NOW(), “monday”)25/08/2025 00:00:00
    DATETRUNC(“month”, NOW())01/08/2025 00:00:00
    DATETRUNC(“quarter”, NOW())01/07/2025 00:00:00
    DATETRUNC(“year”, NOW())01/01/2025 00:00:00

    This is useful for calculations, but the real power comes from understanding that DATETRUNC is a hierarchical function, because it actually returns the parent of the date at the given level. So if we want to check if [date 1] and [date 2] are both in the same month – meaning that both have the same parent month – we can use   DATETRUNC(“month”, [date 1]) = DATETRUNC(“month”, [date 2])

    … instead of what I have seen too many times:  
    MONTH([date 1]) = MONTH([date 2]) AND YEAR([date 1]) = YEAR([date 2])

    If we want to group dates by month, we can use DATETRUNC(“month”, [date]), and that’s it – we’ve created a parent field for [date] at the month level.

    This is especially useful in creating relationships for date fields in data sources, for example when one table is at the timestamp level (transactional data) and the other at the quarterly level (quarterly goals). Just create a relationship calculation with DATETRUNC(“quarter”…) on both sides, and it works.

    There are countless other examples, but the important thing is to understand the main idea: DATETRUNC doesn’t just change the date value, it raises it to a higher level in the hierarchy.

    Now go out and use it.

  • Workbook Locale

    Many times, I’ve encountered Tableau developers struggling with the date formatting in their workbooks, mostly as it defaults to the US format (mm/dd) instead of what they need – and then they waste time setting custom formats for date fields in various worksheets.

    The solution to this, and one of the lesser known features of Tableau Desktop, is the “Workbook Locale” setting, located under the “File” menu.

    The “Automatic” option defaults to your computer’s regional settings, but if you select “More” you can choose your language, and then all date and number formats in the workbook will use that setting by default.

    Even less known is the fact that this setting, at the workbook level, overrides any other regional locale. So if you save the workbook with a locale other than “Automatic”, the date and currency format is fixed, even after publishing to Tableau Server or Cloud.

    The order of precedence is listed below, and documented here:

    1. Workbook locale (set in Tableau Desktop)
    2. Tableau Server User Account language/locale settings
    3. Web browser language/locale
    4. Tableau Server Maintenance page language/locale settings
    5. Host computer’s language/locale settings

    The bottom line – you can control everything using Workbook Locale, so use it, unless you need varying formats for users in different languages or countries, of course.

  • Tooltip = Axis ?

    Tooltip = Axis ?

    Tableau has many little quirks. With time you get used to them, but for new developers some of the small stuff can be very frustrating at first, and a nudge in the right direction always helps. So here’s one of them.

    In Tableau charts, any numbers appearing in tooltips are formatted using the “Axis” format, and not the default “Pane” format. So if you want your chart label to show “24.1%”, and the axis to have 0%, 5%, 10%, etc., your tooltip will show “24%”, which is a bit strange. See the example below:

    The best solution in such a scenario is to duplicate the relevant field, so basically you’re using two different fields – one for the label and axis, and another for the tooltip. Now you can set the axis format for the tooltip field (“Profit ratio (copy)” in the example below) without causing your axis to show unnecessary digits.

    Is there a reason for this functionality? Logic says that the tooltip format should be similar to the label, not the axis (which is usually more “rounded”), but maybe there’s something hiding behind it. And there’s been an Idea (now on the Salesforce IdeaExchange) about changing it for 12 years…

  • Tableau Cloud 💔Static Files

    A nice feature of Tableau (Server) is that you can create data sources with multiple connections, including to files – for example a few database tables, joined/related to a static Excel file (because there’s a small set of data that’s not in your DB), or maybe to a shapefile.
    Then you can publish the data source, check the “Include External Files” box, and when refreshing your extract (or connecting live), the file is simply there. Static.


    Database tables with a relationship to Excel

    The Publish Data Source dialog box

    But what happens when you publish the same data source to Tableau Cloud?

    It turns out that this doesn’t work. The documentation states very clearly that it should work:

    But after testing thoroughly, and opening a case with Tableau Support, I can confirm that this causes an error on Tableau Cloud.
    If you publish a refreshable/live data source with a static file included, even after checking “Include External Files”, any attempt to connect or refresh extracts returns an error, as Tableau Cloud tries to access the file(s).

    This happens both with direct database connections and with Tableau Bridge. Now, obviously, from a technical point of view you can use a Bridge connection to connect to the file on a UNC path, but probably that’s exactly what the developer of the data source was trying to avoid.

    Why is this an issue?

    One of my customers is migrating from Tableau Server to Cloud, and has dozens of data sources that include static files. They discovered the problem only after trying to refresh the extracts on Cloud. All of them now have to be modified – mostly by loading the file into a database table.

    This issue is a major difference in functionality between Server and Cloud, but it is undocumented and doesn’t appear in any migration guides. So it’s important for the community (that’s you – my readers) to know about it, and take it into account for future migrations, at least until the documentation is corrected.

  • DZV is great, but…

    DZV is great, but…

    Dynamic Zone Visibility (or DZV) was introduced by Tableau back in 2022, and is a great feature. It enables you to display or hide any dashboard object, or container, based on the value of a parameter, or a calculation that uses a parameter.

    What most developers I’ve worked with don’t know, however, is that hiding a worksheet using DZV does not prevent Tableau from retrieving the data for the worksheet. So, for example, if you are using a parameter to switch between 5 different displays (so 4 are hidden), the data for all of them is being calculated every time you refresh the dashboard, or change a filter value, even if only one is visible. That’s a x5 performance hit!

    In order to test this thoroughly, I created a workbook with two worksheets: “All Routes”, which is quite slow, and “Bus Calendar”. I also created a parameter with two values (“Times”, “Map”) for switching between them, and the necessary calculated fields:

    Parameter
    One of the boolean fields

    I then created three dashboards:
    1. A dashboard displaying both sheets, with no DZV.
    2. A dashboard switching between both the sheets, using only DZV.
    3. Like no. 2, but adding a context filter on each sheet, using the same boolean field as the DZV, so the data is filtered out when the sheet is hidden.

    Filtering on the “Show map” field
    Context filter

    I then used a Performance Recording to see what happens under the hood. Note that Tableau uses caching, so when a worksheet’s data has already been retrieved using a specific filter, it won’t execute the query again. The results are below:

    DZV Performance Recording

    So what happened?

    • I opened the filtered DZV dashboard first, with “Times” selected in my parameter. Only the “Bus Calendar” query was executed.
    • I changed a filter that affects both sheets. Again, only the “Bus Calendar” query was executed.
    • I switched my parameter value to “Routes”. You can see in the screenshot above that only the “All Routes” query (the long green bar) was executed.
    • Now I opened the unfiltered DZV dashboard, changed the filter, and it immediately executed the queries for both worksheets, even though only “All Routes” was visible.
    • Lastly, I opened the dashboard that displays no sheets. No queries were executed, because both sheets already had the data.

    Obviously this is just a quick scenario. I’ve checked this much more thoroughly on both Desktop and Server, and you can easily check for yourselves using Tableau’s Performance Recording tools (more about that in a future post).

    For now, I’m not telling you not to use DZV. It has great advantages over the old “hack” of filtering worksheets (which I used here), in that you can hide other objects as well, and you don’t need to hide the worksheet title in order to make it disappear. Just bear in mind that hidden worksheets are still calculated, and that affects performance, especially if you have a lot of data.

  • Find in Data Pane

    Tableau always release new versions with a list of new and exciting (or not so) features, such as this, but there are sometimes really helpful additions or modifications that are unlisted, and even undocumented.

    I always start using a new version of Tableau Desktop almost immediately, because as a consultant I have to keep up to date. So when version 2025.2 came out I was working with it within a day, and suddenly saw a new menu entry:

    "Find in Data pane"

    My first reaction was “Is this what I think it is?”.
    My second was to click on it.

    It’s definitely what I thought. No more searching for a field from your worksheet in the Data pane, in order to check the formula. Click on “Find in Data pane” and it finds the field immediately.

    For me, as a consultant, this is a game-changer. I spend hours with my clients, when something isn’t working as they expect, checking their calculated fields, and we always start from the worksheet rows, columns, and marks. Now we can save time and jump straight to the field, without scrolling or typing in the search box.

    Unfortunately this is currently relevant only for Tableau Cloud users, because Server doesn’t have a 2025.2 version, but it’s a great new feature. And I haven’t found it in the documentation yet…

  • Click on “Use Extract”

    One of the infuriating behaviors I encountered early on with Tableau was when I was working with an extracted data source in Desktop. I would be creating worksheets, calculated fields, and dashboards, and then I needed to check something in the data source.

    So I went to the Data Source page, dug into the structure, found what I wanted – but I didn’t change anything. However, when I wanted to return to my worksheet, Tableau decided that something had changed, and started the dreaded extract refresh…

    What do you do in this situation? Wait 10 minutes for it to finish? Cancel and remain stuck in Live mode?

    There’s a solution:

    Cancel.

    If the worksheet starts processing in live mode, Cancel again.

    Now go to the data source’s right-click menu, and check the “Use Extract” option. Your extract still exists, so you are returned instantaneously to extract mode as if nothing has happened. Problem solved.

    I’ve seen this happen literally hundreds of times, especially while working with others, and most developers think they have no option except wait for the extract to finish. So I hope this small tip helps someone…