I'm trying to display an embedded PowerBi report from an external website (a html page served by nodejs). I can display the report with desktop layuot but not with mobile layout (the mobile layout is already created and published).
¿How can I embed a report using the mobile layout?
This is my report configuration:
let reportLoadConfig = {//type: report
type: "report",
tokenType: models.TokenType.Embed,
accessToken: embedData.accessToken,
// Use other embed report config based on the requirement. We have used the first one for demo purpose
//embedUrl: embedData.embedUrl[0].embedUrl,
embedUrl:embedData.embedUrl[0].embedUrl,
// Enable this setting to remove gray shoulders from embedded report
settings: {
//background: models.BackgroundType.Transparent,
layoutType: models.LayoutType.MobilePortrait,
filterPaneEnabled: false,
navContentPaneEnabled: false
}
};
// Embed Power BI report when Access token and Embed URL are available
let report = powerbi.embed(reportContainer, reportLoadConfig);
If you are using the Embed Power BI GitHub Examples, please verify:
1- All report pages have to have a mobile layout created.
2- Set the property layoutType to MobilePortrait in report Config var (client side JavaScript code)
3- If your code uses powerbi.bootstrap, verify this part:
//powerbi.bootstrap(reportContainer, { type: "report" }); //This was the default code example
//I changed the code to:
powerbi.bootstrap(
reportContainer,
{
type: 'report',
hostname: "https://app.powerbi.com",
settings: {
layoutType: models.LayoutType.MobileLandscape
}
}
);
4- Inside index.js (client side JavaScript) Verify the code:
let reportLoadConfig = {//type: report
type: "report",
tokenType: models.TokenType.Embed,
accessToken: embedData.accessToken,
// Use other embed report config based on the requirement. We have used the first one for demo purpose
//embedUrl: embedData.embedUrl[0].embedUrl,
embedUrl:embedData.embedUrl[0].embedUrl,
// Enable this setting to remove gray shoulders from embedded report
settings: {
//background: models.BackgroundType.Transparent,
layoutType: models.LayoutType.MobilePortrait,
filterPaneEnabled: false,
navContentPaneEnabled: false
},
};
5- Finally, you can write a custom javascript function (on client side) to verify the screen size and load landscape or portrait layout, something like this:
window.addEventListener('resize', async ()=>{
//write a function to detect the screen size
let isMobile=await isMobileScreen();
let newSettings = {
layoutType: models.LayoutType.MobileLandscape
};
if(isMobile){ //this returns true or false
newSettings = {
layoutType: models.LayoutType.MobilePortrait
};
report.updateSettings(newSettings);//update the report settings
}else{
report.updateSettings(newSettings); //update the report settings
}});
Here's our script. I'm just the middle man, so I don't fully undertand it. What I understood was that Luis' script needed to refresh the page before the new layout took effect. Our changes address that.
let isMobile = window.matchMedia("only screen and (max-width: 760px)").matches;
let newSettings = {
layoutType: models.LayoutType.MobileLandscape
};
if (isMobile) { //this returns true or false
newSettings = {
layoutType: models.LayoutType.MobilePortrait
};
}
// Initialize iframe for embedding report
//powerbi.bootstrap(reportContainer, { type: "report" });
powerbi.bootstrap(
reportContainer,
{
type: 'report',
hostname: "https://app.powerbi.com",
settings: newSettings
}
);
$.ajax({
type: "GET",
url: "/embedinfo/getebiriver",
success: function (data) {
embedData = $.parseJSON(data);
reportLoadConfig = {
type: "report",
tokenType: models.TokenType.Embed,
accessToken: embedData.EmbedToken.Token,
// You can embed different reports as per your need
embedUrl: embedData.EmbedReport[0].EmbedUrl,
// settings config
settings: newSettings
};
Feel free to copy/combine and roll the answer into your own, and then i'll delete this.
Related
We are trying to get a PowerBi report embedded in a Powerapps portal to show the mobile view of the report.
As described here, I’m testing with a report which only have mobile enabled pages.
This is the code I use to request the mobile version, as documented here.
let report = (await powerbi.get($('.portal-pbi-embedded')[0]))
let page = (await report.getPages()).find(i=>i.isActive);
console.log(await page.hasLayout(window['powerbi-client'].models.LayoutType.MobilePortrait))
// true
console.log(await report.updateSettings({layoutType: window['powerbi-client'].models.LayoutType.MobilePortrait}))
// {statusCode: 202, headers: {…}, body: undefined}
It appears that PowerBi can see that there is a mobile layout for the active page, and the updateSettings commands executes without errors, but nothing happens.
I also tried embedding the report again, where I request the mobile layout upfront, this gives the same behaviour (only showing the desktop version).
I recognized that the powerbi client version that powewrapps portals uses is a bit old (version 2.6.5). Even though that we are running the latest version of the portal that are available to us (9.3.2205.12).
Question 1: How do we show the mobile version of the report in the portal?
Question 2: Is there a way to update the powerbi client in the portal?
First Question
you should note the following (from docs):
after the report initial load, changing to report mobile layout is
supported only if mobile layout (portrait/landscape) has been set into
the initial embedding configuration object. Otherwise, you must first
call powerbi.reset(HTMLElement) to remove the iframe. Then, you have
to call powerbi.embed(...) using the same container with the mobile
layout setting defined on the embedded configuration object.
So basically, you are facing two options:
First Option - In your Configuration, use the following concept to control your visuals:
let models = window['powerbi-client'].models;
let embedConfig = {
type: 'report',
id: reportId,
embedUrl: 'https://app.powerbi.com/reportEmbed',
tokenType: models.TokenType.Embed,
accessToken: 'H4...rf',
settings: {
layoutType: models.LayoutType.Custom
customLayout: {
pageSize: {
type: models.PageSizeType.Custom,
width: 1600,
height: 1200
},
displayOption: models.DisplayOption.ActualSize,
pagesLayout: {
"ReportSection1" : {
defaultLayout: {
displayState: {
mode: models.VisualContainerDisplayMode.Hidden
}
},
visualsLayout: {
"VisualContainer1": {
x: 1,
y: 1,
z: 1,
width: 400,
height: 300,
displayState: {
mode: models.VisualContainerDisplayMode.Visible
}
},
"VisualContainer2": {
displayState: {
mode: models.VisualContainerDisplayMode.Visible
}
},
}
}
}
}
}
};
...
// Embed the report and display it within the div container.
let report = powerbi.embed(embedContainer, embedConfig);
The second option - use the reset method:
powerbi.reset(HTMLElement)
powerbi.embed(...)
Second Question
I'm not sure that I understood your question correctly, but if I did - take a look here (https://learn.microsoft.com/en-us/javascript/api/overview/powerbi/update-settings)
I'm trying to embed Power BI Reports(User Owns Data)
could you please help me how to hide tool bar for paginated report in power bi embedded
?
what is the setting to hide the tool bar
var config = {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: accessToken,
embedUrl: embedUrl ,
id: embedReportId,
permissions: models.Permissions.All,
settings: {
bars: {
actionBar: {
visible: false
}
},
filterPaneEnabled: false,
navContentPaneEnabled: false
},
};
The paginated report does not support hiding toolbar. It only supports enable/disable and expand/collapse of parameters pane.
For more details on paginated report embed capabilities please refer:
https://learn.microsoft.com/en-us/javascript/api/overview/powerbi/embed-paginated-report
I'm trying to use the PowerBIEmbed React component to create and design a new report. Everything works great when I edit an existing report, but when I'm creating a new one (using an embed token generated with TokenAccessLevel.Create), I'm getting the following error:
Report id is required, but it was not found. You must provide an id either as part of embed configuration or as attribute 'powerbi-report-id'.
The id I'm passing in via the configuration is the empty GUID ("00000000-0000-0000-0000-000000000000"). I have also tried deleting that property from the configuration.
I have the permissions set to models.Permissions.All (which includes models.Permissions.Create), so that isn't the issue.
Client code
const config = {
permissions: models.Permissions.All,
tokenType: models.TokenType.Embed,
type: 'report',
embedURL: generatedURL,
accessToken: generatedToken,
viewMode: models.ViewMode.Edit,
};
return (
<PowerBIEmbed
embedConfig={config}
getEmbeddedComponent={report => this.setState({ report })}
/>
);
Server Code
var authToken = await PowerBIAuthentication.DoAuthentication(_Config);
using var client = new PowerBIClient(new Uri(_Config.ApiUrl), authToken);
var dataSets = await client.Datasets.GetDatasetsInGroupAsync(_Config.WorkspaceId, cancellationToken);
var dataSet = dataSets.Value.First(x => x.Name == "AppProtoModel");
var embedTokenParameters = new GenerateTokenRequest(TokenAccessLevel.Create, dataSet.Id);
var embedToken = await client.Reports.GenerateTokenForCreateInGroupAsync(
_Config.WorkspaceId,
embedTokenParameters,
cancellationToken: cancellationToken);
myDoc.PowerBISettings.EmbedToken = embedToken;
myDoc.PowerBISettings.EmbedUrl = dataSet.CreateReportEmbedURL;
return myDoc;
Currently, PowerBIEmbed component from powerbi-client-react library does not support create mode embedding for Power BI Report and, it can be achieved using Power BI JS SDK.
Refer below code snippets:
const embedConfiguration: IEmbedConfiguration = {
permissions: models.Permissions.All,
tokenType: models.TokenType.Embed,
type: "report",
embedUrl: createReportEmbedURL,
accessToken: createEmbedToken,
viewMode: models.ViewMode.Edit,
datasetId: datasetId,
};
const report = powerbi.createReport(reportContainer, embedConfiguration);
createReportEmbedURL mentioned in above snippet can be generated using Datasets - Get Dataset API.
createEmbedToken mentioned in above snippet can be generated using Embed Token - Report GenerateTokenForCreateInGroup API.
Note: The datasetId passed in the configuration should be the same which is used to generate createReportEmbedURL.
Refer following docs for more information:
Create and save embedded report
I am trying to use this power bi below code where powerbi object not found error is getting in my typescript code:
// Read embed application token from textbox
var txtAccessToken = $('#txtAccessToken').val();
// Read embed URL from textbox
var txtEmbedUrl = $('#txtReportEmbed').val();
// Read report Id from textbox
var txtEmbedReportId = $('#txtEmbedReportId').val();
// Read embed type from radio
var tokenType = $('input:radio[name=tokenType]:checked').val();
// Get models. models contains enums that can be used.
var models = window['powerbi-client'].models;
// We give All permissions to demonstrate switching between View and Edit mode and saving report.
var permissions = models.Permissions.All;
// Embed configuration used to describe the what and how to embed.
// This object is used when calling powerbi.embed.
// This also includes settings and options such as filters.
// You can find more information at https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-Configuration-Details.
var config= {
type: 'report',
tokenType: tokenType == '0' ? models.TokenType.Aad : models.TokenType.Embed,
accessToken: txtAccessToken,
embedUrl: txtEmbedUrl,
id: txtEmbedReportId,
permissions: permissions,
settings: {
filterPaneEnabled: true,
navContentPaneEnabled: true
}
};
// Get a reference to the embedded report HTML element
var embedContainer = $('#embedContainer')[0];
// Embed the report and display it within the div container.
var report = powerbi.embed(embedContainer, config);
// Report.off removes a given event handler if it exists.
report.off("loaded");
// Report.on will add an event handler which prints to Log window.
report.on("loaded", function() {
Log.logText("Loaded");
});
report.on("error", function(event) {
Log.log(event.detail);
report.off("error");
});
report.off("saved");
report.on("saved", function(event) {
Log.log(event.detail);
if(event.detail.saveAs) {
Log.logText('In order to interact with the new report, create a new token and load the new report');
}
});
in the above code the powerbi object shows not found in my typescript code: powerbi.embed(embedContainer, config);
I tried to use window['powerbi'] or window.powerbi but doesn't work. What should be the solution then?
I faced a similar issue a few weeks back (probably exactly the same). For me it seems that what works is using window.powerbi.embed() for the embed action, whereas the import import * as powerbi from "powerbi-client"; is used for all other Power BI objects.
I had the same problem, found this question through a google search. I wasn't able to figure out why it wasn't on the window, but as a work around you can initialize it yourself like this:
import * as pbi from "powerbi-client";
const powerbi = new pbi.service.Service(
pbi.factories.hpmFactory,
pbi.factories.wpmpFactory,
pbi.factories.routerFactory
);
const container = document.getElementById("report-container");
powerbi.embed(container, embedConfiguration);
I have a power bi report with both desktop and mobile views. I'd like the browser to switch between these views as it resizes. The only way I can currently achieve this is to embed two instances of the report into the browser, one mobile the other desktop, and hide and show them depending on the browser size.
The problem with this is that if I set some filter values when in the desktop view then, narrow the browser so that the mobile view is shown, then the filter values are not same, this obviously being because there are in reality two separate reports.
The other downside of this approach is that I am presumably also incurring the performance cost on my database of generating two reports.
What can I do to only embed a single report that can dynamically switch between mobile and desktop views?
UPDATE Following response below, test code to toggle layout between mobile and custom layout
angular.element($window).on('resize', function () {
if (vm.report === null)
return;
var models = window['powerbi-client'].models;
var newLayout = models.LayoutType.Custom;
if (window.innerWidth < 768) {
newLayout = models.LayoutType.MobilePortrait;
}
if (vm.report.config.settings.layoutType !== newLayout) {
const newSettings = { layoutType: newLayout };
vm.report.updateSettings(newSettings);
}}
UPDATE 2, Added code to show how the report is generated
// report config
var models = window['powerbi-client'].models;
var config = {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: result.accessToken,
embedUrl: result.embedUrl,
id: result.reportId,
permissions: models.Permissions.View,
viewMode: models.ViewMode.Read,
settings: {
filterPaneEnabled: false,
navContentPaneEnabled: false,
background: models.BackgroundType.Transparent,
layoutType: models.LayoutType.Custom,
customLayout: {
displayOption: models.DisplayOption.FitToPage
}
}
};
// get elements and embed them
var desktopReportContainer = $('.reportContainer')[0];
vm.report = powerbi.embed(desktopReportContainer, config);
Instead of embedding two instances of a report you can do:
Change the layout type by updating settings like here: change-layout-example.
The downside of this approach is that your user's cross filters will not be saved when changing layout.
Before changing the layout type, save a bookmark and then after changing the layout type apply the saved bookmark:
function changeLayout(layoutType) {
report.bookmarksManager.capture()
.then(function (capturedBookmark) {
var bookmarkState = capturedBookmark.state;
var config = {
layoutType: layoutType
};
report.updateSettings(config).then(function () {
report.bookmarksManager.applyState(bookmarkState);
})
})
}
Please note that you will have to add error handling code to the sample above.
Use Custom layout instead of mobile layout like here: Dynamic report layout.
The downside of this approach is that you will have to write code that sets the layout dynamically.
Power BI embed Javascript library has direct support for your case.
First you will need to create a report with mobile layout using Power BI desktop. After you created the report you can embed it using JavaScript SDK. In order to decide in which layout to embed, use the layoutType property of settings in embed configuration.
There are two layout types dedicated to mobile devices:
MobilePortrait - Optimized for portrait view (This is the mobile
layout you created on Power BI desktop)
MobileLandscape - Optimized
for landscape view. This layout looks like the regular report layout.
Load a report in mobile layout Example:
// Get models. models contains enums that can be used.
var models = window['powerbi-client'].models;
var embedConfiguration = {
type: 'report',
id: '5dac7a4a-4452-46b3-99f6-a25915e0fe55',
embedUrl: 'https://app.powerbi.com/reportEmbed',
tokenType: models.TokenType.Embed,
accessToken: 'h4...rf',
settings: {
layoutType: models.LayoutType.MobilePortrait
}
};
Here is the detail guide: https://github.com/Microsoft/PowerBI-JavaScript/wiki/Embed-For-Mobile