Thursday, November 8, 2012

Dashboard Images Revealed

Some interesting dashboard image facts:

You can embed images in your dashboards. OK, that's not news. Things you may not realize:

  • You can embed images in your dashboards. OK, that's not news.
  • You can specify a PDF as the image file, but Tableau won't produce an image.
    (you can embed the PDF in a Web Page component)
  • Once you've inserted the image Tableau doesn't show you the image's source, so there's now way to tell what file is being shown.
  • Tableau doesn't forget the images you've put in the Image component—if you add a second image, Tableau remembers the name of the first; add a third, the second is remembered, etc.
    So be careful about using placeholder images, their ghosts will be lurking about.

Revealing your Dashboards' Images

The Ruby script below will scan the current and all descendant directories for TWBs and for each one found will identify the images and report on them with the Workbook, Dashboard, and Image details. The information is captured as data in the CSV file "TCC_DI.csv", which you can analyze with Tableau.

# TCC_DI.rb - this Ruby script Copyright 2012, Christopher Gerrard # - show the images in the Workbooks' Dashboards require 'nokogiri' require 'open-uri' $twbCnt, $twbNum, $recNum = 0, 0, 0 def init $f ="TCC_DI.csv",'w') $f.puts 'Record #,Workbook,Workbook Dir,Dashboard,Image,Image Dir' unless $f.nil? print "\n\tScanning for Dashboard images\n\t" end def showImages twb doc = Nokogiri::XML(open(twb)) $twbCnt += 1 dashes = doc.xpath('//workbook/dashboards/dashboard' ) if dashes.length > 0 then $twbNum += 1 twbName = File.basename(twb) twbDir = File.dirname(twb) end dashes.each do |d| dName = d.xpath('./@name').text images = d.xpath('//zone[@type="bitmap"]') images.each do |i| iName = i.xpath('./@param').text print '.' imgName = File.basename(iName) imgDir = File.dirname(iName) $f.puts "\"#{$recNum+=1}\",\"#{twbName}\",\"#{twbDir}\",\"#{dName.gsub('"','""')}\",\"#{imgName}\",\"#{imgDir}\"" if $recNum.modulo(72) == 0 then print "\n\t" end end end end init Dir.glob("**/*.twb") {|twb| showImages twb } $f.close unless $f.nil? plural = if $twbNum == 1 then '' else 's' end puts "\n\tDone.\n\tFound #{$recNum} images in #{$twbNum} Workbook#{plural} of #{$twbCnt} Workbooks scanned" if $recNum > 0 then puts "\tTCC_DI.csv contains the image names & the Dashboards containing them." end


No Workbooks are harmed during the revealing of the Images.

Your workbooks are unaffected, nothing is done to them.

How to use TCC_DI.rb

  • Prerequisites
    • Minimal technical skills.
    • Have Ruby installed and ready to run.
    • Have the Nokogiri Ruby gem installed—it's used in the XML parsing.
    • Have TCC_DI.rb in place—it doesn't matter where, or what name you use, as long as you know where it is.
      You can copy the code above and paste it into your favourite text editor.
  • Running TCC_DI.rb
    • Open a command prompt.
      (you can run it otherwise, but this is simple and straightforward)
    • CD to the directory containing the Workbooks you're interested in.
    • Run it: "[path to]\ruby    [path to]\TCC_DI.rb"
    • Note, TCC_DI.rb also looks through all the directories below the current one.
  • Presto. You now have a TCC_DI.csv file containing the information about your Dashboard images, if any.

The usual caveats.

TCC_DI.rb works fine with the limited testing it's been through, but it's definitely not bulletproof and hardened. It's only been run against Tableau v7 Workbooks, and it's entirely possible that images in other Tableau version Workbooks, or images coded in the TWBs in a manner other than the one in my sample TWBs not found might not be detected.

I hope it works for you, but make no guarantees. If you do use it and make improvements I hope that you'll post them back here as comments so I can learn from them, and hopefully other people can benefit from them too.


  1. What's that about placeholder images and 'remembering'?

    1. Placeholder images are temporary images put into dashboards, e.g. if the image intended for display isn't available when the dashboard is created it helps to use another image (preferably with the same dimensions) to hold the image's place (space) in the dashboard until the real image is available.

      By 'remembering' I mean that Tableau keeps track of the separate images you specify as the source for an individual dashboard image component. I was surprised when I discovered that Tableau does this, and can't see any real reason for the component's image source history being preserved when the twb is saved. Most likely there isn't much harm in doing do-the extra content in the twb is unlikely to be a burden, and nobody ever uses unsavory temporary images as placeholders (do they?)-but neither do I see any benefit from it.

      All in all, it's just one of those little things that pops up now and again, like the orphan Worksheets that tended to pile up until v6 (I think) took note and alerted the User when the last dashboard referencing the hidden worksheet was about to be deleted. I only found out about the orphans when I was building TWIS so that I could see what worksheets were in what workbooks and dashboards.

  2. Hey Chris -- really fantastic blog. I'm using Tableau 8 Server and you seem to be the expert on image embedding.

    Do you happen to know if there's a way where I can insert a column which would insert pictures from derived URLs? The URLs in question would be calculated from Product_ID which are already in my dashboard.

    It would seem that I can view the images within a workbook as a Web Object, but that requires clicking and I can only look at a single Product. What I want is for my users to be able to view all of our products simultaneously, so the images (thumbnails) would load in a single shot upon opening the workbook.

    Is this doable? Thanks very much for the help!