Skip to main content

Embed multiple dossier visualizations on a page

Available since 2021 Update 9 (May 2023)

Purpose

You can use the Native Embedding SDK to embed multiple visualizations in a client's webpage, with high performance that is similar to loading one out-of-the-box Library dashboard page.

Custom visualizations are also supported. To embed custom visualizations, you should deploy them on MicroStrategy Library first. To deploy custom visualizations on MicroStrategy Library, refer to Deploy a custom visualization.

Requirements

You must use the js bundle, native-embedding-sdk.js:

<script
type="text/javascript"
src="https://demo.microstrategy.com/MicroStrategyLibrary/javascript/native-embedding-sdk.js"
></script>

The js bundle is also in the web-dossier war, in the same directory as embeddinglib.js.

Example code

Embed visualizations from one dossier

To embed multiple visualizations from one dossier, after referring native-embedding-sdk.js, use the code shown below: (please use <meta charset="UTF-8" /> character encoding tag)

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title></title>
<script
type="text/javascript"
src="https://demo.microstrategy.com/MicroStrategyLibrary/javascript/native-embedding-sdk.js"
></script>
</head>
<body onload="nativeEmbedInDemoPage()">
<div id="container1" style="height: 500px;"></div>
<div id="container2" style="height: 500px;"></div>
<script type="text/javascript">
const nativeEmbedInDemoPage = async () => {
try {
// configuration for the target dossier
const configs = {
projectId: "EC70648611E7A2F962E90080EFD58751",
objectId: "27D332AC6D43352E0928B9A1FCAF4AB0",
};
const environment = await microstrategy.embeddingComponent.environments.create({
serverUrl: `https://demo.microstrategy.com/MicroStrategyLibrary`,
getAuthToken() {
return fetch(`https://demo.microstrategy.com/MicroStrategyLibrary/api/auth/login`, {
method: "POST",
credentials: "include", // including cookie
mode: "cors", // setting as CORS mode for cross origin
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
// here we login as guest user, you can log in as normal user with `username` and `password` as well
// username: "input your username",
// password: "input your password",
loginMode: 8, // 8 means guest login, use `1` if you log in as normal user
}),
})
.then((response) => {
if (response && response.ok) {
return response.headers.get("X-MSTR-authToken");
}
throw Error("Failed to fetch auth token.");
})
.catch((error) => {
console.log("Error:", error);
});
},
});
const mstrDossier = await environment.loadDossier({
projectId: configs.projectId,
objectId: configs.objectId,
});
// the viz keys can be obtained from dashboard definition APIs: e.g.`GET /app/v2/dossier/{dossierId}/definition`
await mstrDossier.refresh([
{
key: "W1334",
container: document.getElementById("container1"),
},
{
key: "A1F3431F2CA2481BB966EC8F35A9AC3A",
container: document.getElementById("container2"),
},
]);
} catch (e) {
console.error(e.message);
}
};
</script>
</body>
</html>

applicationType must be unset or equal to 35. Because the implementation of Native Embedding SDK is based on login as a Library user, which uses the param of applicationType:35.

Display a loading bar during the entire visualization embedding process

During the existing visualization embedding process, the Native Embedding SDK knows which container to use when you call the dossier.refresh API, and the loading bar appears at that time. If you want to see the loading bar during the entire embedding process, create an implementation like this:

<body>
<div id="container1"></div>
</body>
#container1 {
width: 200px;
height: 300px;
}

#mstrLoadingBarParent {
width: 100%;
height: 100%;
background-color: white;
position: relative;
}

#mstrLoadingBar {
width: 100%;
height: 100%;
background: transparent url(yourLoadingIconUrl) no-repeat center;
background-color: white;
position: absolute;
left: 0px;
top: 0px;
display: block;
}

You need to set the height and length with the container element. We haven't had a default height and length when we call dossier.refresh API to embed a viz. If the container element hasn't had the height and length, you can't see your embed visualization.

Find the getAuthToken function in the Native Embedding SDK doc

try {
const showLoadingBar = (container) => {
// the position of the loading bar parent element should be relative
const loadingBarParentDiv = document.createElement("div");
loadingBarParentDiv.id = "mstrLoadingBarParent";
// create the div
const loadingBarDiv = document.createElement("div");
loadingBarDiv.id = "mstrLoadingBar";
loadingBarParentDiv.appendChild(loadingBarDiv);
container.appendChild(loadingBarParentDiv);
};

const hideLoadingBar = (container) => {
container.querySelector("#mstrLoadingBar").remove();
};

const container1 = document.getElementById("container1");

showLoadingBar(container1);

const environment = await microstrategy.embeddingComponent.environments.create({
serverUrl: "https://demo.microstrategy.com/MicroStrategyLibrary",
getAuthToken: () => {
// Logic similar to the existing Native Embedding SDK.
},
});
const dossier = await environment.loadDossier({
projectId: "B19DEDCC11D4E0EFC000EB9495D0F44F",
objectId: "D9AB379D11EC92C1D9DC0080EFD415BB",
});

hideLoadingBar(container1);

await dossier.refresh([
{
key: "K66",
container: container1,
},
]);
// Your own code after the visualizations are all loaded
} catch (error) {
// Your own error handling code
}

Embed visualizations from multiple dossiers

If you want to embed visualizations from multiple dossiers, you must turn on this functionality by setting the feature flag as shown below before calling the APIs:

window.microstrategy.nativeEmbedding.featureFlags.multipleDossiers = true;

Then you can embed the visualizations from multiple dossiers in parallel like this:

async function loadVisualizationsFromDossier({
mstrEnvironment,
projectId,
dossierId,
vizAndContainers,
}) {
const mstrDossier = await mstrEnvironment.loadDossier({
projectId,
objectId: dossierId,
});
// The function here would keep the old behavior, to load the visualizations page by page
await mstrDossier.refresh(vizAndContainers);
}

async function loadVisualizationsFromDossiers() {
try {
// The preparation code starts here
const mstrEnvironment = await microstrategy.embeddingComponent.environments.create({
serverUrl: "https://demo.microstrategy.com/MicroStrategyLibrary",
getAuthToken: () => {
// Logic similar to the existing Embedding SDK.
},
});
const projectId = "B19DEDCC11D4E0EFC000EB9495D0F44F";
const dossierAndVisualizations = [
{
dossierId: "DCB5909744F164E1D190B3B0137EEC5F",
vizAndContainers: [
{
key: "W70",
container: document.getElementById("containerA"),
},
{
key: "W112",
container: document.getElementById("containerB"),
},
],
},
{
dossierId: "EDBA3FAE4F6A21187BD2CD92AE954802",
vizAndContainers: [
{
key: "W115",
container: document.getElementById("containerC"),
},
{
key: "W116",
container: document.getElementById("containerD"),
},
],
},
];
// Non-blocking concurrent loadings for visualizations from different dossiers
await Promise.all(
dossierAndVisualizations.map((dossierAndVisualization) =>
loadVisualizationsFromDossier({
mstrEnvironment,
projectId,
dossierId: dossierAndVisualization.dossierId,
vizAndContainers: dossierAndVisualization.vizAndContainers,
})
)
);
} catch (err) {
// Your custom error handling logic here
}
}

More available operations

After you embed multiple visualizations on a page, you can do some deeper manipulation of them.

References

This piece of code contains a function from the following namespace and classes:

  • microstrategy.embeddingComponent.environments Namespace

    This namespace is responsible for creating and destroying MstrEnvironment objects.

  • MstrEnvironment Class

    This class is the object returned from the microstrategy.embeddingComponent.environments.create() function, which is responsible for creating and destroying MstrDossier objects.

  • MstrDossier Class

    This class is returned from the MstrEnvironment.loadDossier() function, which is responsible for showing visualizations in containers.