Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents
minLevel1
maxLevel7

You can find a live code example that details how to embed the dashboard in your dashboard installation.

If your dashboard is installed locally with all the default settings, to access the example go to http://localhost:8224/pi_embed_example/.

Embedding A Panintelligence Chart

Step 1 - Ensure your dashboard is running in HTTPS

See Configuring HTTPS for more information.

Step 2 - Configuring the Dashboard

By default, embedding the dashboard in an iframe will no longer work without configuration. This is by design to provide the most secure out of the box configuration.

We have implemented click-jacking protection in the form of the recommended 'frame-ancestors'. By default, this is configured to disallow any embedding from any site. This can be changed via the Panintelligence Configuration Tool.

Using the Configuration Tool

On Windows

You can get to the Configuration Tool via the Start menu:

...

Or by navigating to the Dashboard installation folder. On Windows, the default location is C:\Program Files\Dashboard\Dashboard:

...

Info

Please ensure that you run configuration-tool-GUI.exe as an administrator.

On Linux

Double click configuration-tool-GUI.AppImage.

...

Editing the CORS / Frame Ancestors / Trusted Hosts and the Cookie settings

...

Info

If you need embedding to work with Internet Explorer, you must set X Frame Host option too. Keep in mind that we do not maintain support for Internet Explorer.

From the Trusted Hosts dropdown you’ll see the following values:

  • none: No embedding allowed

  • self: Embedding allowed from the same host

  • custom: Embedding allowed from the hosts specified in the space separated list

Note

Protocol (http/https) is required for trusted hosts / frame ancestors when using a wildcard.

Using environment variables

Settings can be applied via environment variables and this is true for these fields too:

Code Block
languagebash
PI_TOMCAT_FRAME_ANCESTORS="http://localhost:5000 https://my.awesome.app"
PI_TOMCAT_COOKIE_SECURE=true
PI_TOMCAT_COOKIE_SAMESITE=none

...

Table of Contents
minLevel1
maxLevel7

You can find a live code example that details how to embed the dashboard in your dashboard installation.

If your dashboard is installed locally with all the default settings, to access the example go to http://localhost:8224/pi_embed_example/.

Embedding A Panintelligence Chart

Step 1 - Ensure your dashboard is running in HTTPS

See Configuring HTTPS for more information.

Step 2 - Configuring the Dashboard

By default, embedding the dashboard in an iframe will no longer work without configuration. This is by design to provide the most secure out of the box configuration.

We have implemented click-jacking protection in the form of the recommended 'frame-ancestors'. By default, this is configured to disallow any embedding from any site. This can be changed via the Panintelligence Configuration Tool.

Using the Configuration Tool

On Windows

You can get to the Configuration Tool via the Start menu:

...

Or by navigating to the Dashboard installation folder. On Windows, the default location is C:\Program Files\Dashboard\Dashboard:

...

Info

Please ensure that you run configuration-tool-GUI.exe as an administrator.

On Linux

Double click configuration-tool-GUI.AppImage.

...

Editing the CORS / Frame Ancestors / Trusted Hosts and the Cookie settings

...

Protocol (http
Info

If you need embedding to work with Internet Explorer, you must set PI_TOMCAT_X_FRAME_OPTIONS X Frame Host option too. Keep in mind that we do not maintain support for Internet Explorer.

Note

From the Trusted Hosts dropdown you’ll see the following values:

  • none: No embedding allowed

  • self: Embedding allowed from the same host

  • custom: Embedding allowed from the hosts specified in the space separated list

Note

Protocol (http/https) is required for trusted hosts / frame ancestors when using a wildcard.

Using

...

environment variables

Settings can be applied via a configuration file to support unattended installs and GUI-less environments.

To do this, find or create a file named dashboard.json next to the configuration tool:

...

NOTE: When using the configuration tool by the command line and you’re specifying a configuration file, you must specify an absolute path to it (not a relative path).

...

✔ Absolute path: configuration-tool configure --json-file=/absolute/path/here.json

...

Then edit it using your favourite editor. You’ll need to change tomcat.cookies.secure, tomcat.cookies.sameSite and security.trustedHosts.

...

environment variables and this is true for these fields too:

Code Block
PI_TOMCAT_FRAME_ANCESTORS="http://localhost:5000 https://my.awesome.app"
PI_TOMCAT_COOKIE_SECURE=true
PI_TOMCAT_COOKIE_SAMESITE=none
Info

If you need embedding to work with Internet Explorer, you must set PI_TOMCAT_X_FRAME_OPTIONS option too. Keep in mind that we do not maintain support for Internet Explorer.

Note

Protocol (http/https) is required for trusted hosts / frame ancestors when using a wildcard.

Step 3 - Getting a token

You can run a working example by following this repository:

In our examples, we’re doing this in the frontend just so you can follow a full example.

Note

However do not do this in production, you’ll be exposing your password!

Typically your backend communicates with the dashboard in order to get the token. Once in place, your frontend then just uses it.

You can use our API to fetch a token for any user. Below we’ve got an example in javascript using jquery:

...

languagejs

...

Using the configuration file

These settings can also be applied via a configuration file to support unattended installs and GUI-less environments.

To do this, find or create a file named dashboard.json next to the configuration tool:

...

Note

NOTE: When using the configuration tool by the command line and you’re specifying a configuration file, you must specify an absolute path to it (not a relative path).

  • ✔ Absolute path: configuration-tool configure --json-file=/absolute/path/here.json

  • ✘ Relative pathconfiguration-tool configure --json-file=relative/path/here.json

Then edit it using your favourite editor. You’ll need to change tomcat.cookies.secure, tomcat.cookies.sameSite and security.trustedHosts.

...

Info

If you need embedding to work with Internet Explorer, you must set xFrameOptions option too. Keep in mind that we do not maintain support for Internet Explorer.

Note

Protocol (http/https) is required for trusted hosts / frame ancestors when using a wildcard.

Step 3 - Getting a token

You can run a working example by following this repository:

In our examples, we’re doing this in the frontend just so you can follow a full example.

Note

However do not do this in production, you’ll be exposing your password!

Typically your backend communicates with the dashboard in order to get the token. Once in place, your frontend then just uses it.

You can use our API to fetch a token for any user. Below we’ve got an example in javascript using jquery:

Code Block
var url = "https://localhost:8224/" //Change this to your url
var username = "admin" //Change this to the user you want to login as
var password = "dashboard" //Change this to user's password
$.ajax({
    // POST to the API with username and password to swap that for a session token
    type: "POST",
    url: url + apiToken,
    contentType: "application/json",
    xhrFields: {
        withCredentials: true
    },
    beforeSend: function (xhr, settings) {
        xhr.setRequestHeader("Authorization", "basic " + username + ":" + password);
    },
    success: function (data) {
        contentType: "text/HTML",login(data.token);
    }
});

function  xhrFields: login(token) {
    // Issue an ajax request to embeddedTokenLogin with withCredentials:the truetoken in the header to pick up the session },cookies
    $.ajax({
   beforeSend: function (xhr, settings) { type: "GET",
        url:  // This is the header we need to set
  url + "pi/auth/embeddedTokenLogin",
        contentType: "text/HTML",
        xhrFields: {
         xhr.setRequestHeader("Authorization", "bearer " + token);withCredentials: true
        },
        successbeforeSend: function (dataxhr, settings) {
            // OnceThis weis havethe aheader succesfulwe ajax request with authentication we can load the charts in the iframesneed to set
            xhr.setRequestHeader("Authorization", "bearer " + token);
        },
        success: function });
}

Step 4 - Embedding

Chart

To embed a chart you’ll need an iframe and the chart’s ID. You can get this by going into the dashboard, clicking chart tools at the top-right of a chart cell and selecting the i icon:

...

Then copy the code snippet:

...

Code Block
languagehtml
<iframe id="chart_iframe" src='https://your.dashboard.com/pi/chart#chart-filter/481__1' width="500" height="500"></iframe>

You should probably only update/show the iframes once the user has been logged in.

That would change the login code to be more like:

Code Block
languagejs
function login(token) {
    // Issue an ajax request to embeddedTokenLogin with the token in the header to pick up the session cookies
    $.ajax({
        type: "GET",
        url: url + "pi/auth/embeddedTokenLogin",
        contentType: "text/HTML",
        xhrFields:(data) {
            // Once we have a succesful ajax request with authentication we can load the charts in the iframes
        }
    });
}

Step 4 - Embedding

Chart

To embed a chart you’ll need an iframe and the chart’s ID. You can get this by going into the dashboard, clicking chart tools at the top-right of a chart cell and selecting the i icon:

...

Then copy the code snippet:

...

 

Code Block
<iframe id="chart_iframe" src='https://your.dashboard.com/pi/chart#chart-filter/481__1' width="500" height="500"></iframe>

You should probably only update/show the iframes once the user has been logged in.

That would change the login code to be more like:

Code Block
function login(token) {
    // Issue an ajax request to embeddedTokenLogin with withCredentials:the truetoken in the header to pick up the session },cookies
    $.ajax({
   beforeSend: function (xhr, settings) { type: "GET",
        url: url + "pi/auth/ This is the header we need to set
  embeddedTokenLogin",
        contentType: "text/HTML",
        xhrFields: {
         xhr.setRequestHeader("Authorization", "bearer " + token);withCredentials: true
        },
        successbeforeSend: function (dataxhr, settings) {
            document.querySelector("#chart_iframe").src = "https://your.dashboard.com/pi/chart#chart-filter/481__1"
        }
    });
} // This is the header we need to set
            xhr.setRequestHeader("Authorization", "bearer " + token);
        },
        success: function (data) {
            document.querySelector("#chart_iframe").src = "https://your.dashboard.com/pi/chart#chart-filter/481__1"
        }
    });
}

Limiting drill levels on embedded charts

When embedding a chart that contains multiple drill levels, it is possible to use the query parameters “drillStart” and “drillEnd” in the URL to limit the drill levels that a user can see.

When using drillStart, the URL will also need to be configured to include the chart ID and hierarchy position of each chart that is being skipped and the chart at the drillStart level. These must be separated by the !$! delimiter when adding multiple levels. When drilling to the top, the user will return the the level defined as the drillStart parameter.

It is possible to use the parameters individually or together. The parameters are 0 indexed - with the first hierarchy in the chart corresponding to drill level 0. The functionality will also work for dynamic drill conditions.

Info

The below url would allow the user to see drill levels 1, 2 and 3 (i.e the 2nd, 3rd and 4th hierarchy levels) of the chart:

http://localhost:1234/pi/chart/?drillStart=1&drillEnd=3#chart-filter/251__1/d-f-p=251__0/!$!251__1

*Location and syntax of the query parameters.

*Example of identifiers added to view level 1 (2nd hierarchy level ) of the given chart.

Category

We have embedded a chart but what if we want to embed a category? Embedding a category isn’t actually any different from embedding the whole dashboard (yes, you can do that too!).

...

This will remove the header but keep the category list.

...

 

Interacting with the left & right drawers

...

The left drawer tag will open the category list as long as the embed mode allows for the category list to be active (Options 0 and 3). To interact with it you can use something like below:

Code Block
languagejs
targetWindow.postMessage("open-drawer:left");

The right drawer tag will open the filter panel for every embed mode available. Similarly, you can open it using the same syntax as above:

Code Block
languagejs
targetWindow.postMessage("open-drawer:right");

...

The dashboard supports embedding with default category filters selected.

Refer to Embedded Categories for details. If changing the filter values outside of the dashboard is needed, we will need to implement functions to be called outside of an iframe, so that filter values are supplied to the dashboard elegantly.

 

The current structure of the URL for category filters

Note

IMPORTANT: This is just for information. We don’t recommend editing the URL directly to change filter values, because it’s not a reliable approach and the implementation may break when upgrading the dashboard

 

Category-level filters are applied to all the charts in the category, it currently has such a pattern pattern:

...

Note

IMPORTANT: This is just for information. We don’t recommend editing the URL directly to change filter values, because it’s not a reliable approach and the implementation may break when upgrading the dashboard

Filter Name

Pattern

Object Types

Examples

Equals

eq__[[Object]]{{Value}}

Dimension

eq__[[Region]]{{North}}

Measure

eq__[[Count]]{{50}}

Greater than

gt__[[Object]]{{Value}}

Dimension

gt__[[Region]]{{North}}

Measure

gt__[[Count]]{{50}}

Lower than

lt__[[Object]]{{Value}}

Dimension

lt__[[Region]]{{North}}

Measure

lt__[[Count]]{{50}}

Greater or equals

ge__[[Object]]{{Value}}

Dimension

ge__[[Region]]{{North}}

Measure

ge__[[Count]]{{50}}

Lower or equals

le__[[Object]]{{Value}}

Dimension

le__[[Region]]{{North}}

Measure

le__[[Count]]{{50}}

Not equals

ne__[[Object]]{{Value}}

Dimension

ne__[[Region]]{{North}}

Measure

ne__[[Count]]{{50}}

Like

like__[[Region]]{{Value}}

Dimension

like__[[Region]]{{Nor%}}

like__[[Object]]{{'Value'}}

Measure*

like__[[Count]]{{'1%'}}

Not Like

like__[[Region]]{{Value}}

Dimension

nlike__[[Region]]{{Nor%}}

like__[[Object]]{{'Value'}}

Measure*

nlike__[[Count]]{{'1%'}}

Top

top__[[Object]]{{Value}}

Dimension

top__[[Region]]{{5}}

Measure

top__[[Count]]{{5}}

Bottom

btm__[[Object]]{{Value}}

Dimension

btm__[[Region]]{{3}}

Measure

btm__[[Count]]{{3}}

In

in__[[Object]]{{Val1::::Val2::::Val3}}

Dimension

in__[[Region]]{{North::::South::::West}}

Not In

nin__[[Object]]{{Val1::::Val2::::Val3}}

Dimension

nin__[[Region]]{{North::::South::::West}}

Between

btw__[[Object]]{{Value1::::Value2}}

Measure

btw__[[Count]]{{300::::500}}

Not Between

nbtw__[[Object]]{{Value1::::Value2}}

Measure

nbtw__[[Count]]{{300::::500}}

*May not work for some databases

...

Edit dashboard.json configuration file:

language
Code Block
json
{
        "proxy": {
            "enabled": true,
            "scheme": "https",
            "secure": true,
            "host": "proxy-host.com",
            "port": 443
        }
}

Using environment variables

Code Block
languagebash
PI_PROXY_ENABLED=true
PI_PROXY_SCHEME=https
PI_PROXY_IS_SECURE=true
PI_PROXY_HOST="proxy-host.com"
PI_PROXY_PORT=443

...

If you have subdomains, the hostname in the custom trusted hosts will need to be entered as *.hostname *.hostname 
 
 

Elementor macro
rowWidth100
titleb5agtf
content[{"id":"0fio3v","order":1662556629944,"background":{"source":"color","value":"#ffffff","id":""},"backgroundOverlay":{"isActive":false,"color":"#000000","opacity":0.5},"rows":[{"id":"9ivh3r","order":1662556629944,"type":"one","columns":[{"id":"7di8w","order":1,"alignment":{"vertical":"center","horizontal":"center"},"macro":{"id":"pagedivider","dividerColor":"#8d135bff","text":"Related Topics","fontSize":24,"textAlignment":"center","dividerWidth":100,"dividerWeight":3,"dividerType":"text-only","dividerIcon":"atlaskit/StarFilledIcon","textColor":"#8d135bff","iconColor":"#000","labelPosition":"middle","emojiEnabled":"false","emoji":{"id":"smile","name":"Smiling Face with Open Mouth and Smiling Eyes","short_names":["smile"],"colons":":smile:","emoticons":["C:","c:",":D",":-D"],"unified":"1f604","skin":null,"native":"😄"}}},{"id":"1rhy7","order":2,"alignment":{"vertical":"center","horizontal":"center"},"macro":{}},{"id":"2iu4vh","order":3,"alignment":{"vertical":"center","horizontal":"center"},"macro":{}},{"id":"709mb","order":4,"alignment":{"vertical":"center","horizontal":"center"},"macro":{}}]},{"id":"ynti68","order":1662556661832,"type":"one","columns":[{"id":"e6cnof","order":1,"alignment":{"vertical":"center","horizontal":"center"},"macro":{"id":"pages","type":"list","layout":"four","loadType":"manual","parentPage":"","manualPages":[{"id":"m1qj4o","position":0,"contentId":"1165328430"}],"labels":[],"spaces":[],"contributors":[],"numberOfItems":8,"pagination":"infinite"}},{"id":"yp822ip","order":2,"alignment":{"vertical":"center","horizontal":"center"},"macro":{}},{"id":"eevm8","order":3,"alignment":{"vertical":"center","horizontal":"center"},"macro":{}},{"id":"0asq5e","order":4,"alignment":{"vertical":"center","horizontal":"center"},"macro":{}}]}]}]

...