Embedding  Tableau Dashboards in React Web Applications

Embedding Tableau Dashboards in React Web Applications

Data Visualization in React Applications with Embedded Tableau Dashboards

Tableau is one of the most popular tools used for data visualization tools in the tech industry, it provides users with a wide range of features to explore, analyze and share data in the form of charts, graphs, and dashboards. One of the most powerful features of Tableau is its ability to embed dashboards into other applications, such as web applications built using React. In this article, we will discuss how to embed Tableau dashboards into React applications.

Create a React Component

export default function TableauDashboard() {
  return <div></div>;
}

Getting a Tableau Dashboard

As a react developer most times the dashboard will have already been created by a data analyst. You need to make sure that the dashboard is published to the Tableau Server or Tableau Online.

Obtain Embed Code

After publishing your dashboard, you will need to obtain the embed code. To do this, open the dashboard in Tableau Server or Tableau Online and click on the "Share" button. In the pop-up window, select "Embed Code" and copy the code provided.

in the Dialog box that appears copy the Embed Code. We are going to paste it into our React component

At this point, your component should look something like this.

export default function TableauDashboard() {
  return <div>
    <div class='tableauPlaceholder' id='viz1632385584499' style='position: relative'><noscript><a href='#'><img alt='Stub Data V ' src='https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;St&#47;Stubtest&#47;StubDataV&#47;1_rss.png' style='border: none' /></a></noscript><object class='tableauViz'  style='display:none;'><param name='host_url' value='https%3A%2F%2Fpublic.tableau.com%2F' /> <param name='embed_code_version' value='3' /> <param name='site_root' value='' /><param name='name' value='Stubtest&#47;StubDataV' /><param name='tabs' value='no' /><param name='toolbar' value='yes' /><param name='static_image' value='https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;St&#47;Stubtest&#47;StubDataV&#47;1.png' /> <param name='animate_transition' value='yes' /><param name='display_static_image' value='yes' /><param name='display_spinner' value='yes' /><param name='display_overlay' value='yes' /><param name='display_count' value='yes' /><param name='language' value='en-US' /><param name='filter' value='publish=yes' /></object></div>                <script type='text/javascript'>                    var divElement = document.getElementById('viz1632385584499');                    var vizElement = divElement.getElementsByTagName('object')[0];                    if ( divElement.offsetWidth > 800 ) { vizElement.style.width='1142px';vizElement.style.height='2020px';} else if ( divElement.offsetWidth > 500 ) { vizElement.style.width='1142px';vizElement.style.height='2020px';} else { vizElement.style.width='100%';vizElement.style.height='2527px';}                     var scriptElement = document.createElement('script');                    scriptElement.src = 'https://public.tableau.com/javascripts/api/viz_v1.js';                    vizElement.parentNode.insertBefore(scriptElement, vizElement);                </script>
  </div>;
}

Don’t worry we are going to clean it up

 useEffect(()=>{
   const divElement = document.getElementById("viz1632385584499");
    const vizElement = divElement.getElementsByTagName("object")[0];
    if (divElement.offsetWidth > 800) {
      vizElement.style.width = "1142px";
      vizElement.style.height = "2020px";
    } else if (divElement.offsetWidth > 500) {
      vizElement.style.width = "1142px";
      vizElement.style.height = "2020px";
    } else {
      vizElement.style.width = "100%";
      vizElement.style.height = "2527px";
    }
    const scriptElement = document.createElement("script");
    scriptElement.src = "https://public.tableau.com/javascripts/api/viz_v1.js";
    vizElement.parentNode.insertBefore(scriptElement, vizElement);             
  })

After removing the script tag, your return statement should look like this

 return (
    <div>
      <div
        class="tableauPlaceholder"
        id="viz1632385584499"
        style="position: relative"
      >
        <noscript>
          <a href="#">
            <img
              alt="Stub Data V "
              src="https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;St&#47;Stubtest&#47;StubDataV&#47;1_rss.png"
              style="border: none"
            />
          </a>
        </noscript>
        <object class="tableauViz" style="display:none;">
          <param name="host_url" value="https%3A%2F%2Fpublic.tableau.com%2F" />{" "}
          <param name="embed_code_version" value="3" />{" "}
          <param name="site_root" value="" />
          <param name="name" value="Stubtest&#47;StubDataV" />
          <param name="tabs" value="no" />
          <param name="toolbar" value="yes" />
          <param
            name="static_image"
            value="https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;St&#47;Stubtest&#47;StubDataV&#47;1.png"
          />{" "}
          <param name="animate_transition" value="yes" />
          <param name="display_static_image" value="yes" />
          <param name="display_spinner" value="yes" />
          <param name="display_overlay" value="yes" />
          <param name="display_count" value="yes" />
          <param name="language" value="en-US" />
          <param name="filter" value="publish=yes" />
        </object>
      </div>
    </div>
  );

Cleaning up the code

Now we want to edit the style property the way it should be in react, otherwise your app would be throwing errors.

So instead of having style="position: relative” in react we would have style={{position: "relative"}} as react expect inline style to be javascript objects

Now go ahead and update all the style attributes in your component. And Vola your component can be used anywhere in your project

your finished component should look something like this:

export default function TableauDashboard() {
  useEffect(() => {
    const divElement = document.getElementById("viz1632385584499");
    const vizElement = divElement.getElementsByTagName("object")[0];
    if (divElement.offsetWidth > 800) {
      vizElement.style.width = "1142px";
      vizElement.style.height = "2020px";
    } else if (divElement.offsetWidth > 500) {
      vizElement.style.width = "1142px";
      vizElement.style.height = "2020px";
    } else {
      vizElement.style.width = "100%";
      vizElement.style.height = "2527px";
    }
    const scriptElement = document.createElement("script");
    scriptElement.src = "https://public.tableau.com/javascripts/api/viz_v1.js";
    vizElement.parentNode.insertBefore(scriptElement, vizElement);
  });

  return (
    <div>
      <div
        class="tableauPlaceholder"
        id="viz1632385584499"
        style={{ position: "relative" }}
      >
        <noscript>
          <a href="#">
            <img
              alt="Stub Data V "
              src="https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;St&#47;Stubtest&#47;StubDataV&#47;1_rss.png"
              style={{ border: "none" }}
            />
          </a>
        </noscript>
        <object class="tableauViz" style={{ display: "none" }}>
          <param name="host_url" value="https%3A%2F%2Fpublic.tableau.com%2F" />
          <param name="embed_code_version" value="3" />
          <param name="site_root" value="" />
          <param name="name" value="Stubtest&#47;StubDataV" />
          <param name="tabs" value="no" />
          <param name="toolbar" value="yes" />
          <param
            name="static_image"
            value="https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;St&#47;Stubtest&#47;StubDataV&#47;1.png"
          />
          <param name="animate_transition" value="yes" />
          <param name="display_static_image" value="yes" />
          <param name="display_spinner" value="yes" />
          <param name="display_overlay" value="yes" />
          <param name="display_count" value="yes" />
          <param name="language" value="en-US" />
          <param name="filter" value="publish=yes" />
        </object>
      </div>
    </div>
  );
}