In Spring ’22, you can extend the power of Lightning Web Components (LWC) to Tableau CRM dashboards and build even richer and more customized analytics apps. The options with LWC and Tableau CRM are many. You can create customized reusable extensions, such as charts, widgets, and even Tableau data visualizations, and bring them directly into your dashboards to provide a seamless experience for your end users.

There are two main types of Analytics LWCs: those that attach to a query (also known as a “step” in Tableau) and those that do not.

Typical use cases for LWCs with a step include a custom data visualization, a custom control, a list view, or a custom table with additional functionality. These LWCs get notified instantly when the associated query updates its results. This means that you can take advantage of all of Tableau CRM’s faceting, filtering, bindings, and interaction — all without writing a single line of code! In addition, there are also APIs to get the query’s selections, metadata, and selection mode; if you want to allow users to use your LWC to filter other widgets, then you want to implement setSelection to notify the dashboard when the selection has been updated.

The second type of Analytics LWC has no query attached to it, and this can be used for generic dashboard behaviors. Some examples include a back button, a tray of all existing filters, a custom table where you want to write all your data query logic directly using Lightning Data Service, Apex wire adapters, or external APIs.

How LWC for Tableau CRM works

To make a LWC available within the Tableau CRM dashboard, we’ll need to define a series of attributes for the js-meta.xml file.

First of all, we need to make the component compatible with the dashboard designer UI by adding the target attribute analytics__Dashboard.

<targets>
    <target>analytics__Dashboard</target>
</targets>

To expose the configuration options, we need to add the targetConfigs attribute. Here we can define whether or not we are querying data from our dataset by setting the attribute hasStep to true or false.

Finally, we can expose the property value to the dashboard by including the details.

<targetConfigs>
    <targetConfig targets="analytics__Dashboard">
        <hasStep>false</hasStep>
        <property name="title" type="String" label="Title" description="Title of the component" required="true" />
    </targetConfig>
</targetConfigs>

In order to power up our LWC, we can expose the property in the .js file with the @api annotations.

Properties are key to making your code reusable. If you find yourself hard coding any strings or numeric values, add a property for it in the js-meta.xml file. You can always add a default value, so that it doesn’t have to be configured on setup. The great part about doing this is that when the business requirements or the parent dashboard change, you don’t have to change your code at all. All properties can be updated from the Dashboard Designer UI without having to even look at the code (assuming that you gave them a good enough description). This will also help to make sure that your code is reusable across many dashboards, including dashboards, datasets, and use cases that you haven’t even begun to think about yet!

Let’s look at an example

To illustrate the art of the possible with LWC and Tableau CRM, let’s look at a Play button example. In Tableau CRM, we have created a dashboard with three widgets:

  • A chart showing opportunity value and number by account
  • A list widget showing close date (Year-Month)
  • A component widget with our Play button

The Play button is using the query data from the list widget, meaning that when you click play, it will select and run through every single date in the list widget.

The Play button is a really fun and unique example because it attaches to a query, but it does not do any rendering of the underlying data. The query can be attached to one or more other widgets to display the various selections (including the current selection), but it doesn’t have to be. It could also be a hidden query that hides how the magic happens. This component is a great tool to unlock your inner data storyteller!

Note: You can find the playButton LWC example in GitHub.

playButton.js-meta.xml

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Play Button</masterLabel>
    <targets>
        <target>analytics__Dashboard</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="analytics__Dashboard">
            <hasStep>true</hasStep>
            <property name="delay" type="Integer" label="Delay (ms)" description="Delay between steps in milliseconds." min="1" default="2000" />
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

playButton.js

import { LightningElement, api } from 'lwc';

export default class PlayButton extends LightningElement {
  @api results;
  @api metadata;
  @api selection;
  @api setSelection;
  @api selectMode;
  @api getState;
  @api setState;
  @api delay;
  @api curSelectionIndex = 0;
  @api myTimer;

  resetCounter() {
    this.curSelectionIndex = 0;
    this.setSelection([this.results[this.curSelectionIndex]]);
  }

  stopPlaying() {
    clearInterval(this.myTimer);
  }

  startPlaying() {
    if (this.curSelectionIndex >= this.results.length - 1) {
      this.curSelectionIndex = 0;
    }

    this.setSelection([this.results[this.curSelectionIndex]]);
    let that = this;

    function stepForward() {
      if (that.curSelectionIndex >= that.results.length - 1) {
        clearInterval(that.myTimer);
      } else {
        that.curSelectionIndex += 1;
        that.setSelection([that.results[that.curSelectionIndex]]);
      }
    }

    this.myTimer = setInterval(stepForward, this.delay);
  }
}

playButton.html

<template>
  <div>
    <lightning-button-icon
      icon-name="utility:jump_to_left"
      variant="border-filled"
      alternative-text="Reset"
      title="Reset"
      onclick={resetCounter}
    ></lightning-button-icon>
    <lightning-button-icon
      icon-name="utility:stop"
      variant="border-filled"
      alternative-text="Stop"
     
      title="Stop"
      onclick={stopPlaying}
    ></lightning-button-icon>
    <lightning-button-icon
      icon-name="utility:play"
      variant="border-filled"
      alternative-text="Play"
     
      title="Play"
      onclick={startPlaying}
    ></lightning-button-icon>
  </div>
</template>

Adding to an existing dashboard

After you have installed this component in your org, you can then add it to any dashboard. The fastest way to get up and running is to just use an existing dashboard, or one from an app or dashboard template. Once you find one you like and edit it with the Tableau CRM Dashboard Designer, just follow these steps:

  1. Find a query you want to use. An easy way to do this is to click on a widget that uses it, then click the Query tab at the top right, and remember its Label or ID.
  2. Drag a component from the left toolbar to an empty spot on the canvas.
  3. Click the Configure button on the component.
  4. Click the Lightning Components Tab.
  5. Choose “Play Button” and click “Done.”
  6. On the next screen, select “Existing Query” (if you don’t see a tab bar, then click “Change Data Source” at the top).
  7. Click on the query from Step 1.
  8. Optionally, resize and move the Play button to a good spot on the dashboard.
  9. Optionally, click on the LWC and expand “Component Attributes” at the right and modify the default interval delay to speed things up or slow them down.

Now, click “Preview” and hit your Play button to see it in action. Then, unleash your inner Hans Rosling and tell everyone an exciting story about what’s going on in your dashboard!

Getting started

If you want to learn more about how to use LWC in Tableau CRM, you can read the release notes and check out the developer documentation. You can also check out more LWC code examples in the sfdx-analytics repository on GitHub.

Learn MOAR this week

Product Managers and Developer Relations are back to share the latest features and functionality to help you develop faster with new content from Developer Relations covering their favorite new features. Make sure to check out Release Readiness Live on Friday February 4th at 9:00 PST. Lastly, and keep an eye on the Salesforce Developers blog for more posts on Spring ’22!

To learn even more, check out the Spring ’22 trailmix.

About the authors

Rikke Hovgaard works as a Solution Architect Director on the Tableau CRM product team. She focuses on helping customers get the most out of their data regardless of the complexity. You can follow her on Twitter @HovsaRikke or salesforceblogger.com.

Ed Mengel is a Senior Director of Product Management on the Tableau CRM team. He loves building features that make data more fun and engaging. He has been working on Tableau CRM for almost ten years, and has been working from home since before it was cool! He sometimes tweets as @edmengel, and posts a few helpful video tutorials at EdForceAnalytics on YouTube.

Get the latest Salesforce Developer blog posts and podcast episodes via Slack or RSS.

Add to Slack Subscribe to RSS