EDIT: You can now use the jPBI Framework to achieve this goal
https://jpbi.codeplex.com/
Hi all,
After my session with William Bordes called « Embed Power BI ». In this session we showed how to embed a Power BI tile in a web page, or a SharePoint Page, or whatever can show an iFrame and execute JavaScript.
Find here the Sway (in French) of our session
The code is available here, on MSDN
This is the result we expect :
I’d like to share with you THE CODE !
It’s extremely easy : everything is done with JavaScript.
First things first : to embed a tile from Power BI, you have to know its URL, to put in into the Iframe !
Prerequisites :
1. A Power BI report uploaded on the Power BI Portal
2. Tile(s) pined on a dashboard, on the Power BI Portal
Sound’s like this :
Let’s code !
3. Get the URL of the tile you want to embed. Please use : apiary.io
You have to authenticate with your O365 account on it, and add an Application on your Azure AD, extremly simple :
Authentication :
Allow Apiary to connect to Power BI Service
Back to Apiary, « switch to code » and then, « Call ressource »
Scroll down to the « Body », and find the JSON ! Get the ID of the dashboard you want.
List all tiles of the dashboard !
Get the embed URL of the tile you want to show in SharePoint/Website.
Let’s go to Visual Studio !
I’m going to show you a SharePoint Online integration, so you have to install Office Dev Tools with your Visual Studio.
New Project and create a Provider Hosted App
Get connect, then…
Note that I choose an MVC app because I must use MVC every time it’s possible for me (to learn it). You can use a web forms app if you want. The JS code I’ll show later won’t be change.
Now, we are really happy to have an app. But, before going further, we have to create and set an application in your Azure AD (the Azure AD used by your Office 365 Tenant).
So, go to your Azure Portal (if you didn’t dit it already, subscribe on Azure with your Office 365 Admin account, you’ll see your Azure AD after that).
Back to Visual Studio, you need to get an information there !
Back to Azure !
You’re AAD Application has been created. Now clic on « Configure »
Scroll down and and « Add an application »
Select « Power BI Service »
Give authorizations ! And Save !
Scroll up and copy the Client ID of the app. Paste it in a notepad.
Then, we have to make a few changes in the AAD Application JSON configuration. It’s needed to make it works with our Javascript authentication code. So, go back on the dashboard of your AAD Application.
Download the manifest
Open it, and set the value of the parameter « oauth2AllowImpliciteFlow » to « true ». Save the file.
Re-upload it in Azure
Nice ! Everything is ready. Now we can code !!! Go back to Visual Studio !
Let’s prepare the app.
Change your HomeController.cs, so it’ll seem like this (don’t forget to remove the [SharePointContextFilter]).
Comment the code in _ViewStart.cshtml
The code is available here, on MSDN
Now, we add the HTML code to « Index.cshtml »
In this example I will embed three tiles ; so I’ve added three iFrame elements.
And the JS code !
Line 13 to 19, you’ll see three call to « UpdateEmbedTile ». The first parameter is the ID of the iFrame you add in the HTML, the second parameter is the « embedUrl » we get with Apiary. You have to set it to your own value.
In the function requestToken(), don’t forget to change the var « clientId » with the client ID of your AAD application (you’ve just copied to the notepad) and, if needed, the redirectUrl, with the SSL Url of your application.
Do not forget to load jQuery :
/Scripts/jquery-1.10.2.min.js
//https://powerbi.microsoft.com/en-us/documentation/powerbi-developer-integrate-a-power-bi-tile-or-report/
var token = null;
$(document).ready(function () {
//Get Token
if (urlParameterExtraction.queryStringParameters['access_token'] == null) { requestToken(); }
// Extract token from urlParameterExtraction object.
token = urlParameterExtraction.queryStringParameters['access_token'];
//Like par auteurs
updateEmbedTile("iFrameEmbedTile1", "https://app.powerbi.com/embed?dashboardId=c822f941-7d5a-4769-abf3-0bfdfe7d202b&tileId=bd39ae2a-5499-44c9-81e7-212e4ddc7e9e", 300, 450);
//Nombre total de likes
updateEmbedTile("iFrameEmbedTile2", "https://app.powerbi.com/embed?dashboardId=c822f941-7d5a-4769-abf3-0bfdfe7d202b&tileId=98c7349d-0c80-4054-a9db-f556fb99acc1", 300, 250);
//Top des likeurs
updateEmbedTile("iFrameEmbedTile3", "https://app.powerbi.com/embed?dashboardId=c822f941-7d5a-4769-abf3-0bfdfe7d202b&tileId=8dc31946-6b46-4f60-9316-1a7fcd6a5ead", 250, 800);
});
//**********************//
//***TILE MANAGEMENT***//
//********************//
function updateEmbedTile(iFrameId, embedTileUrl, h, w) {
console.log("updateEmbedTile");
// check if the embed url was selected
if ("" === embedTileUrl)
return;
// to load a tile do the following:
// 1: set the url, include size.
// 2: add a onload handler to submit the auth token
iframe = document.getElementById(iFrameId);
iframe.src = embedTileUrl + "&width=" + w + "&height=" + h;
iframe.onload = function () { postActionLoadTile(iFrameId, h, w); }
}
function postActionLoadTile(iFrameId, h, w) {
console.log("postActionLoadTile");
// get the access token.
accessToken = token;
// return if no a
if ("" === accessToken)
return;
// construct the push message structure
var m = { action: "loadTile", accessToken: accessToken, height: h, width: w };
message = JSON.stringify(m);
// push the message.
iframe = document.getElementById(iFrameId);
iframe.contentWindow.postMessage(message, "*");;
}
//************************//
//********UTILS**********//
//**********************//
function requestToken() {
// Change clientId and replyUrl to reflect your app's values
// found on the Configure tab in the Azure Management Portal.
// Also change {your_subdomain} to your subdomain for both endpointUrl and resource.
var clientId = 'dd4870e9-992c-4e26-b464-28f66a738930';
var replyUrl = 'https://localhost:44300';
var resource = "https://analysis.windows.net/powerbi/api";
var authServer = 'https://login.windows.net/common/oauth2/authorize?';
var responseType = 'token';
var url = authServer +
"response_type=" + encodeURI(responseType) + "&" +
"client_id=" + encodeURI(clientId) + "&" +
"resource=" + encodeURI(resource) + "&" +
"redirect_uri=" + encodeURI(replyUrl);
window.location = url;
}
var urlParameterExtraction = new (function () {
function splitQueryString(queryStringFormattedString) {
var split = queryStringFormattedString.split('&');
// If there are no parameters in URL, do nothing.
if (split == "") {
return {};
}
var results = {};
// If there are parameters in URL, extract key/value pairs.
for (var i = 0; i < split.length; ++i) {
var p = split[i].split('=', 2);
if (p.length == 1)
results[p[0]] = "";
else
results[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return results;
}
// Split the query string (after removing preceding '#').
this.queryStringParameters = splitQueryString(window.location.hash.substr(1));
})();
On the SharePoint part of the project, we will add a Client Web Part to embed our page that contains tiles.
In the Elements.xml of your webpart, change the code with that :
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ClientWebPart Name="Embed Power BI Tiles" Title="Embed Power BI Tiles" Description="Show Embed Power BI Tiles" DefaultWidth="900" DefaultHeight="2000">
<!-- Content element identifies the location of the page that will render inside the client web part
Properties are referenced on the query string using the pattern _propertyName_
Example: Src="~appWebUrl/Pages/ClientWebPart1.aspx?Property1=_property1_" -->
<Content Type="html" Src="~remoteAppUrl" />
<!-- Define properties in the Properties element.
Remember to put Property Name on the Src attribute of the Content element above. -->
<Properties>
</Properties>
</ClientWebPart>
</Elements>
You can now press F5 and launch the debug !
Allow the app in your SharePoint.
The first thing you’ll see in your web browser will be a page with your tiles.
Now, go to your SharePoint, add a page, edit it and add a webpart. Choose the webpart we add in the Add In !
And that’s it !
Before upload it in production environment, don’t forget to change redirection address in your AAD Application AND in your JS code.
Note that I tried the API to embed some reports, but it seems to be a little bit buggy, so I’m in touch with Power BI team to see how we can fix it !
Do not hesitate to ask if you meet any issue !
And again : The code is available here, on MSDN 😉
Hi, thank you for writing this article – I am new totally new to app development and managed to follow your instructions, which means they were quite good. 🙂
When my tiles are loading, they display a « sorry we couldn’t find what you were looking for » message with an owl image for just a second, then the graphs load normally – do you know what causes this? It *does* work, but for some reason it is using this message while the tiles load.
J’aimeJ’aime
Yes I know ! Are you using Firefox ?
If yes, the cause is :
1. The page load without token
2. Iframes are loaded without the token <= IT'S WHEN YOU SEE THE MESSAGE
3. The page re-load, call Azure AD, get the token
4. Iframes re-loads, and show tiles (because you have your token)
I've experimented this experience only with Firefox. A workaround should be : hide the div that contains the iFrames since you don't have a token in the URL, with jQuery/Javascript.
J’aimeJ’aime
Yes, Firefox. Thank you! I have since managed to break the whole thing (for some reason the web part is trying to look at the localhost url now and failing to find it…) but I will poke around.
J’aimeJ’aime
Very helpful article. I have followed your instructions, after downloading and making the changes that you specified, but I’m getting the following error, which seems to be on the Power BI side
SourceMap https://app.powerbi.com/11.0.9169.161/scripts/visuals.min.js.map read failed: One or more errors occurred.SourceMap https://app.powerbi.com/11.0.9169.161/scripts/PowerBIVisualRenderer.min.js.map read failed: One or more errors occurred.The program ‘[4620] iexplore.exe’ has exited with code 0 (0x0).
Have you ever seen it? Do you know what could be causing it? Thanks,
Alex
J’aimeJ’aime
Hi !
It seems to be an error on Microsoft side (remember it’s in beta). I’ve met those kinds of errors with the API for reports, that’s why the code for reports is commented in the code. Here, we are using the API for tiles.
Maybe you should talk about that to the Power BI dev team on Twitter. They like feedbacks… Or try with another web browser !
Best regards
J’aimeJ’aime
I just saw last week that the dev team is officially working on PBI embeds in SharePoint, so one way or another it’ll probably get fixed 🙂
J’aimeJ’aime
Hi sir, i don’t know what i haven’t done wrong.
I get this report if i write done my credentials.
I’ve tried it with microsoft edge, firefox, IE and chrome.
cheers Ken
J’aimeJ’aime
Hi Ken, we can’t see your report there, could you post it on my Facebook page ? https://www.facebook.com/aurelien.prevot.10
J’aimeJ’aime
Very good solution here – I always have the problem that the reports are loading very long time and the browser not responding and the site is crashing. Do you know this issue ? The tiles are working fine.
J’aimeJ’aime
Hi, I changed the manifest as instructed but I am still getting the following error:
« response_type ‘token’ is not supported for the application »
J’aimeJ’aime
Hi ! Can you copy there your AAD application manifest please ?
J’aimeJ’aime
Is there a solution yet to embed complete reports and/or dashboards?
J’aimeJ’aime
HELLO !
You can embed a full report by using updateEmbedReport(« iFrameID », « Embed Url of the Report* », « The client ID of your Azure AD Application »); of jPBI framework I’ve bring on CodePlex. https://jpbi.codeplex.com
To embed a full dashboard, there is no other way than embed each tile separately !
J’aimeJ’aime
I noticed that Power BI dashboard interactivity is lost when embedded in SharePoint. Visuals appear static. Is there any way to keep them interactive?
J’aimeJ’aime
I followed the post. Now in the end when I deploy the application ,I get following error
Can you please help me.
Sign In
Sorry, but we’re having trouble signing you in.
We received a bad request.
Additional technical information:
Correlation ID: e52f3ccf-0f35-4291-bd48-09c0428249bc
Timestamp: 2016-08-30 11:44:43Z
AADSTS70001: Application with identifier ‘fcd56ff3-2dd5-440c-bcb7-6714950fff1a’ was not found in the directory mind123.onmicrosoft.com
J’aimeJ’aime
Hello,
Please ensure you have created an Azure AD Application with ID fcd56ff3-2dd5-440c-bcb7-6714950fff1a on the Azure Tenant mind123.onmicrosoft.com
Maybe you are not logged in on the right tenant.
Best regards,
J’aimeJ’aime
Hi,
Can you please help. I have followed all the steps mentioned in the blog. Whenm I try browsing it, I get an message saying ‘OOp’s the page you are looking for couldn’t be found’. I tried refreshing the page several times but still the error is same and the browser I am using is Chrome and Microsoft edge
Any help is really appreciated.
J’aimeJ’aime
Hello,
Please double check you’ve copy/paste the EMBED Url from Apiary.
Best regards
J’aimeJ’aime
Hi, I am using PowerBI API to get dashboards, tiles and reports. i think Power BI API is not returning responsive html data, all divs are with hard coded height and width. How i can use this in a responsive web site?
thanks
Jais
J’aimeJ’aime
Hi Jason, really I don’t know… Maybe try using the Office UI Fabric or some PnP responsive stuff for SharePoint, but I’m really not sure about the result. Another approach would be to use the Power BI app on iOS (if your devices are on it)…
J’aimeJ’aime
Fantastic blog you have here but I was curious if you knew of any forums that cover the same topics discussed in this article? I’d really like to be a part of online community where I can get comments from other experienced individuals that share the same interest. If you have any suggestions, please let me know. Bless you!|
J’aimeJ’aime
When I post – the page shows fine – but when I try to add the web part to a page – it immediately blanks out and shows nothing. I’m sure I am doing something foolish – but can you give some idea as to why this might be?
J’aimeJ’aime
It’s maybe because of the « auto load » of the credentials to Azure AD… Can you copy paste the URL you have ?
J’aimeJ’aime
Very informative post! Thank you!
I’m a little stuck in my deployment :
I’ve tried both your original and the jpbi version but when launching debug i get a message « working on it » then it redirects to a page with my iframes but none of the tiles load.
I’ve reverified my embed urls from apiary and even tried loading them directly in the browser, but I only get spinning loding symbols that way, no data.
Any ideas?
J’aimeJ’aime