Add Tableau Viz to your Dashboard Extensions


Tableau Viz provides a lightweight method for creating visualizations in Tableau. You provide a declarative description of graph or chart, and then call a method to render the description as an SVG image that you can embed in your dashboard extension. The description includes the data (or programmatically adds the data) and specifies the type of chart you wish to create and how it should be encoded. This feature is available through the Dashboard Extensions API and employs the same visualization pipeline that Tableau uses.

In this section


What you need to get started

Tableau Viz is integrated with the Tableau Dashboard Extensions API. To add visualizations to your extension requires the following versions of Tableau and the Dashboard Extensions JavaScript library. Tableau Viz version 2 introduces support for combination charts, multiple panes, and dual-axes visualizations.

Tableau Viz (version 1):

Tableau Viz (version 2):


The components of a Tableau Viz

There are three main steps in creating a Tableau Viz image.

graph LR A:[Create input specification] --> B:[Call createVizImageAsync] --> C:[Display SVG in dashboard extension]

Input specification

A Tableau Viz is defined by a specification. This is the inputSpec that you pass as an argument to the createVizImageAsync method. The inputSpec is a JavaScript object that contains the embedded data and visual specification details. There are two main parts to the inputSpec:

The inputSpec is a structured JavaScript object. In these examples, the data values are statically assigned as part of the specification. In many cases, you would probably programmatically assign the values based upon mark selection in the dashboard or based on some other selection criteria.

The following example shows an inputSpec for Tableau Viz version 1. This example creates a simple bar chart.

Example inputSpec (version 1)


            var yourEmbeddedDataSpec = {
                description: 'A simple chart with embedded data.',
                data: {
                    values: [
                        { Category: 'A', Sales: 28 },
                        { Category: 'B', Sales: 55 },
                        { Category: 'C', Sales: 43 },
                        { Category: 'D', Sales: 91 },
                        { Category: 'E', Sales: 81 },
                        { Category: 'F', Sales: 53 },
                        { Category: 'G', Sales: 19 },
                        { Category: 'H', Sales: 87 },
                        { Category: 'I', Sales: 52 }
                    ]
                },
                mark: tableau.MarkType.Bar,
                encoding: {
                    columns: { field: 'Category', type: tableau.VizImageEncodingType.Discrete },
                    rows: { field: 'Sales', type: tableau.VizImageEncodingType.Continuous, hidden: true},
                    color: { field: 'Sales', type: tableau.VizImageEncodingType.Continuous, palette: 'tableau-map-temperatur'},
                    text: { field: 'Category', type: tableau.VizImageEncodingType.Discrete },
                    size: { field: 'Category', type: tableau.VizImageEncodingType.Discrete}
                }
            };

For Tableau Viz version 2, an inputSpec supports combination charts, multiple mark types in the same visualization. The following example specifies a bar chart and an area chart.

Example inputSpec (version 2)


    const vizInputSpec = {
        version: 2,
        description: 'Example QQConcat viz',
        data: {
          values: [
            { Segment: 'Consumer', ShipMode: 'First Class', Category: 'Technology', Profit: 11560.75, Sales: 61089.43 },
            { Segment: 'Corporate', ShipMode: 'First Class', Category: 'Technology', Profit: 7235.75, Sales: 39201.43 },
            { Segment: 'Home Office', ShipMode: 'First Class', Category: 'Technology', Profit: 8706.75, Sales: 39074.43 },
            { Segment: 'Consumer', ShipMode: 'First Class', Category: 'Office Supplies', Profit: 7734.74, Sales: 48200.43 },
            { Segment: 'Corporate', ShipMode: 'First Class', Category: 'Office Supplies', Profit: 6299.74, Sales: 31579.43 },
            { Segment: 'Home Office', ShipMode: 'First Class', Category: 'Office Supplies', Profit: 4366.74, Sales: 21552.43 },
            { Segment: 'Consumer', ShipMode: 'First Class', Category: 'Furniture', Profit: 2078.74, Sales: 49880.43 },
            { Segment: 'Corporate', ShipMode: 'First Class', Category: 'Furniture', Profit: 929.75, Sales: 35077.43 },
            { Segment: 'Home Office', ShipMode: 'First Class', Category: 'Furniture', Profit: 58.74, Sales: 25773.43 },
            { Segment: 'Consumer', ShipMode: 'Second Class', Category: 'Technology', Profit: 14430.75, Sales: 72942.43 },
            { Segment: 'Corporate', ShipMode: 'Second Class', Category: 'Technology', Profit: 6819.74, Sales: 41912.43 },
            { Segment: 'Home Office', ShipMode: 'Second Class', Category: 'Technology', Profit: 4902.75, Sales: 27366.43 },
            { Segment: 'Consumer', ShipMode: 'Second Class', Category: 'Office Supplies', Profit: 9752.74, Sales: 71757.43 },
            { Segment: 'Corporate', ShipMode: 'Second Class', Category: 'Office Supplies', Profit: 9809.74, Sales: 62810.43 },
            { Segment: 'Home Office', ShipMode: 'Second Class', Category: 'Office Supplies', Profit: 7506.74, Sales: 26115.43 },
            { Segment: 'Consumer', ShipMode: 'Second Class', Category: 'Furniture', Profit: 763.74, Sales: 86799.43 },
            { Segment: 'Corporate', ShipMode: 'Second Class', Category: 'Furniture', Profit: 1596.74, Sales: 41403.43 },
            { Segment: 'Home Office', ShipMode: 'Second Class', Category: 'Furniture', Profit: 1865.74, Sales: 28086.43 },
          ],
        },
        vizlayout: {
          title: 'Example QQConcat viz',
        },
        columns: [
          { field: 'ShipMode', type: tableau.VizImageEncodingType.Discrete },
          { field: 'Sales', type: tableau.VizImageEncodingType.Continuous },
          { field: 'Profit', type: tableau.VizImageEncodingType.Continuous },
        ],
        rows: [{ field: 'Segment', type: tableau.VizImageEncodingType.Discrete }],
        encodingaxis: 'columns',
        defaultencoding: { mark: tableau.MarkType.Bar },
        encodings: [
          {
           mark: tableau.MarkType.Bar,
          },
          {
            mark: tableau.MarkType.Area,
            color: { field: 'Category', type: tableau.VizImageEncodingType.Discrete, palette: { name: 'green_orange_cyan_yellow_10_0' } },
          },
        ],
      };

For more information about the inputSpec for version 1 and version 2, see Tableau Viz Reference.


Call createVizImageAsync

After you create the inputSpec you pass it as an argument to the createVizImageAsync method. Tableau Viz version 1 and version 2 use this same process. The createVizImageAsync method returns an SVG image that can be used by the extension. This example takes the yourEmbeddedDataSpec that was defined in the previous step, and uses that to describe the chart to create.

 tableau.extensions.createVizImageAsync(yourEmbeddedDataSpec).then((svg) => {
     ...         
            });
  

Display the SVG image in the dashboard extension

The asynchronous method returns an SVG image as the promise. Here is one way of taking that SVG and embedding it as a an element in your extension web page. In this example, the svg is converted to a JavaScript Blob, and the Blob is used as the image data source in the hosting dashboard extensions page.

            tableau.extensions.createVizImageAsync(yourEmbeddedDataSpec).then((svg) => {
                console.log(svg);
                var blob = new Blob([svg], { type: 'image/svg+xml' });
                var url = URL.createObjectURL(blob);
                var image = document.createElement('img');
                image.src = url;
                image.style.maxWidth = '100%';
                var vizApiElement = document.getElementById('viz-container');
                vizApiElement.appendChild(image);
                image.addEventListener('load', function () { return URL.revokeObjectURL(url); }, { once: true });
            }, (err) => {
                console.log(err);
            });

Tableau renders an image that looks something like this (version 1):

Tableau Viz SVG image



The following shows what a version 2 inputSpec looks like when rendered by the createVizImageAsync method.

Tableau Viz v2 SVG image




What’s next?

Now that you have seen the basic steps for adding a Tableau Viz to a dashboard extension, you can try adding Tableau Viz to your own dashboard extensions, or to one of the samples.


Troubleshoot Tableau Viz images in dashboard extensions

You can use the same tools that you use to debug dashboard extensions to debug problems that occur when you use Tableau Viz to create images. For information about debugging your extension, see Debug Extensions in Tableau Desktop and Debug Extensions in Tableau Server and Tableau Cloud.

Tableau Viz Error Messages

The following is a list of common error messages that you might encounter and includes steps for fixing those errors. The error messages appear in the Console window when you use the Chrome or Chromium debugging tools.

For specific issues with the current release, see Tableau Viz - Known Issues.

Invalid Palette Name

Error: internal-error: {"vizapiErrorMsg":"Invalid Palette Name"}

Be sure that you use one of the palette names listed for the color key under encoding in the inputSpec. See Encoding. Note that the palette must be supported by the version of Tableau that you are using, and that the palette colors are subject to change. In addition, there are some palette colors can only be used for continuous or discrete fields, but not for both.

Encoding column (or row) has invalid type

Error: internal-error: {"vizapiErrorMsg":"Encoding columns has invalid type. Accepted values are Continuous and Discrete"}

When you encode the fields in the inputSpec, you need to make sure that the discrete fields (blue pills) and continuous fields (green pills) are mapped to the correct types: tableau.VizImageEncodingType.Discrete and tableau.VizImageEncodingType.Continuous.

Invalid JSON

The inputSpec is a JavaScript object that Tableau converts to JSON for processing. The inputSpec needs to be in the correct format and must include all required elements. You must encode columns and fields. For the list of required elements, see Tableau Viz Reference.