Fit content to angular powerBi client iframe - css

I have a couple of reports designed in power BI. The problem is as follows: The iframe I have created has a height of 80rem (that's fine). The problem is that in the event that the report is of a lower height there is a blank space that I want to remove.
I have been testing with css and if I make it smaller the height of the iframe other reports are cut, if I remove the height the report stays with a size of 300w x 150h, I have also tried reading using pages layout (I don't know how to use it because I don't know where the key is taken from), display option and visual layout. All this without success. The guide I use is the following: https://github.com/Microsoft/PowerBI-JavaScript/wiki/Custom-Layout
reading that I feel that it is solved with pages layout but I don't know how to use it. Do you have a solution? Thanks in advance.
The power bi config is this:
this.config = {
accessToken: accessToken && accessToken.currentValue ? accessToken.currentValue : this.config.accessToken,
tokenType: tokenType && tokenType.currentValue ? this.getTokenType(tokenType.currentValue) : this.config.tokenType,
embedUrl: embedUrl && embedUrl.currentValue ? embedUrl.currentValue : this.config.embedUrl,
type: type && type.currentValue ? type.currentValue : this.config.type,
id: id && id.currentValue ? id.currentValue : this.config.id,
filters: filtersExternal && filtersExternal.currentValue ? filtersExternal.currentValue : this.config.filters,
...this.fixedConfig
};
And Fixed config:
// Fixed configuration
fixedConfig: IEmbedConfiguration = {
settings: {
navContentPaneEnabled: false,
filterPaneEnabled: false,
customLayout: {
pageSize: {
type: models.PageSizeType.Custom,
height: 600,
width: 1300
}
}
}
};

This is working for me to resize the the power bi report in UI
this.reportService.getReportObject(reportName).subscribe(res => {
this.reportmodel = res;
this.config = {
type: res.reportType,
id: res.id,
accessToken: res.embedToken.token,
embedUrl: res.embedUrl,
permissions: pbi.models.Permissions.All,
tokenType: pbi.models.TokenType.Embed,
viewMode: pbi.models.ViewMode.View,
settings: {
filterPaneEnabled: false,
navContentPaneEnabled: navigation,
layoutType: pbi.models.LayoutType.Custom,
customLayout: {
displayOption: pbi.models.DisplayOption.FitToWidth
}
}
};
this.hideloader();
this.pbiContainerElement = document.getElementById('pbi-container');
this.powerBiService = new NgxPowerBiService();
this.powerBiService.reset(this.pbiContainerElement);
const reportobj = this.powerBiService.embed(this.pbiContainerElement, this.config) as pbi.Report;
reportobj.off('loaded');
reportobj.on('loaded', () => {
reportobj.setPage(this.reportmodel.pageName);
});
},
err => {
this.hideloader();
console.log(err);
this.dashboardLoadError = true;
throw new Error('Exception occured while rendering the dashboard:' + err);
});

Good Morning,
Finally I discovered that my problem was that in order to maintain the 16: 9 aspect ratio on certain screens, the height decreased a lot. To solve it was as simple as modifying the height of the container div of the iframe depending on the width of the screen:
#media only screen and (max-width: 1600px) {
// TODO: A variable
height: 60rem;
}
#media only screen and (max-width: 1300px) {
// TODO: A variable
height: 55rem;
}
#media only screen and (max-width: 800px) {
// TODO: A variable
height: 35rem;
}
that way the iframe adjusts to the content of the report.
My HTML div & iframe:
<div class="tn-powerbi__frame" [ngClass]="{ 'tn-powerbi__frame--fullscreen': fullscreen,'tn-powerbi__frame--insurtech': reportId===20 }" #powerbiFrame></div>
Iván Allué

Related

Customize Embedded Zoom Meeting SDK with Component View in 2.2.0

When working with Embedded Zoom Component, the Zoom SDK return an element which you need to place it inside an html element
the problem is how to resize and position the returned component inside my code after rendering
const client = ZoomMtgEmbedded.createClient();
function getSignature(e) {
e.preventDefault();
// ... some code to get the signature
startMeetingZoomMtgEmbedded(response.signature);
}
function startMeetingZoomMtgEmbedded(signature) {
let meetingSDKElement = document.getElementById('meetingSDKElement');
client.init({
debug: true,
zoomAppRoot: meetingSDKElement,
language: 'en-US',
customize: {
meetingInfo: ['topic', 'host', 'mn', 'pwd', 'telPwd', 'invite', 'participant', 'dc', 'enctype'],
toolbar: {
buttons: [
{
text: 'Custom Button',
className: 'CustomButton',
onClick: () => {
console.log('custom button');
}
}
]
}
}
});
client.join({
apiKey: apiKey,
signature: signature,
meetingNumber: meetingNumber,
password: passWord,
userName: userName,
userEmail: userEmail,
tk: registrantToken,
success: (success) => {
console.log('success');
},
error: (error) => {
console.log(error);
}
});
}
return (
<div className="App">
<main>
<h1>Zoom Meeting SDK Sample React</h1>
{/* For Component View */}
<div id="meetingSDKElement"></div>
<button onClick={getSignature}>Join Meeting</button>
</main>
</div>
);
So my question is how to modify the style and the position of the component before or after the rendering of the code by the Zoom SDK.
For Resizing , You will find details in the following documentation link :
Zoom Documentation for resizing component view
For Positioning, You will find details in the following documentation link :
Zoom Documentation for positioning component view
The only way to resize camera view is editing #ZOOM_WEB_SDK_SELF_VIDEO id. So, you have to edit other classes also to make buttons, containers and etc resize like camera view does, but it is totally buggy and i don't think it is a good idea pay all this effort to a workaround, besides that, in next versions maybe they bring built in properties to do this job.
Just for example, this is the result when you change #ZOOM_WEB_SDK_SELF_VIDEO:
#ZOOM_WEB_SDK_SELF_VIDEO {
width: 720%;
height: 480%;
}
In general way, you can modify the style and position of your component by using reactive CSS styling.
In zoom way you can use (zoom web meeting SDK)
(a) "popper: {}" properties for positioning elements
(b) "viewSizes: {}" properties for default meeting canvas size
(c) for styling use "id" and "class" for reactive CSS styling
popper use:
client.init({
...
customize: {
video: {
popper: {
anchorElement: meetingSDKElement,
placement: 'top'
}
},
}
...
})
viewSizes use:
client.init({
...
customize: {
video: {
viewSizes: {
default: {
width: 1000,
height: 600,
}
}
},
}
...
})

CSS style is not correctly being applied when conditional render in React

I need to conditionally render components based on screen size.
I use nextjs and getInitialProps for data fetching, the page is server-side rendered. I want to detect device screen size on the client-side, so I implement a customized hook to do it.
useWindowSize.js
import { useEffect, useState } from 'react';
export default function useWindowSize() {
const [windowSize, setWindowSize] = useState({
width: typeof window === 'undefined' ? 1200 : window.innerWidth, // default width 1200
});
useEffect(() => {
// Handler to call on window resize
function handleResize() {
// Set window width/height to state
setWindowSize({
width: window.innerWidth,
//height: window.innerHeight,
});
}
// Add event listener
window.addEventListener('resize', handleResize);
// Call handler right away so state gets updated with initial window size
handleResize();
// Remove event listener on cleanup
return () => window.removeEventListener('resize', handleResize);
}, []); // Empty array ensures that effect is only run on mount
return windowSize.width <= 600;
}
then I use this hook to detect window size and conditional render components
export default function IndexPage() {
const isMobile = useWindowSize();
if (typeof window !== "undefined") {
// if you are running it on codesanbox, I don't know why log is not printed
console.log("client side re-render");
}
return (
<div>
{isMobile ? (
<div
style={{
color: "red",
fontSize: 40
}}
>
mobile
</div>
) : (
<div
style={{
color: "blue",
fontSize: 20
}}
>
desktop
</div>
)}
</div>
);
}
IndexPage.getInitialProps = () => {
return {
a: 1
};
};
when I load the page on mobile browser, you will see
text mobile is applied wrong CSS style. video demo: https://share.getcloudapp.com/nOuk08L0
how to reproduce:
https://codesandbox.io/s/thirsty-khayyam-npqpt
Can someone please help me out. Thank you in advance!
This is an issue that is related to how React patch up DOM from SSR. When there is a mismatch between client-side and server-side rendering, React will only patch/sync the text context for the node. The DOM attribute will not be automatically updated. In your case, the SSR result has the desktop style because there is no window object, and client side has the mobile result. After the mismatch, React update the text node from 'desktop' to mobile but not the style attributes.
In my opinion, you can use two different approaches. You can use Media Query to style your component based on the screen width instead of the hook. If you are doing SSR, not SSG, you can use user agent req.headers["user-agent"] to detect the device your device is being viewed on.
For the first approach, you might need to render more DOM node you might need to. For the second approach, you won't be able to know the actual viewport size, which can cause visual issue. You might be able to combine both approach to produce a good viewing experience for your user.
Reference
https://github.com/facebook/react/issues/11128#issuecomment-334882514
Thanks for #Andrew Zheng's detailed explanation! Today I learned.
I know that I can style the layout by using pure CSS media query, but my use case needs a variable like isMobile to
if (isMobile) {
doSomethingOnlyOnMobileWeb();
} else {
doSomethingOnlyForDesktopWeb();
}
So I combined two approaches you provided, and modify my hook this way:
export default function useWindowSize(userAgent) {
let isMobile = Boolean(
userAgent &&
userAgent.match(
/Android|BlackBerry|iPhone|iPod|Opera Mini|IEMobile|WPDesktop/i
)
);
const [windowSize, setWindowSize] = useState({
width: isServer
? isMobile
? BREAKPOINT_SMALL
: BREAKPOINT_LARGE
: window.innerWidth,
});
useEffect(() => {
// Handler to call on window resize
function handleResize() {
// Set window width/height to state
setWindowSize({
width: window.innerWidth,
//height: window.innerHeight,
});
}
// Add event listener
window.addEventListener('resize', handleResize);
// Call handler right away so state gets updated with initial window size
handleResize();
// Remove event listener on cleanup
return () => window.removeEventListener('resize', handleResize);
}, []); // Empty array ensures that effect is only run on mount
return windowSize.width <= BREAKPOINT_SMALL;
}
diff: passing user-agent string to useWindowSize for server-side detection and use window.innerWidth for client-side detection. There won't be a mismatch between server and client.

In VueJS, is there a way to make your binded styling react to the size change of the screen?

I have a div that is conditionally binded to a class in vueJS. The formula for my computed variable uses Screen.width. It seems to work correctly when first loading, but if I change the size of the screen it doesn't rebind with the new screen size, unless I refresh the page. Is there a way I can get my conditionally binding to honor the change in screen?
<div class="div_1" v-bind:class="{ horizontalScroll : showScroll }"/>
showScroll(){
return this.events.length*225>(screen.width*.84);
}
If you wanna do it this way, you will probably have to register a 'resize' listener. Your code should look something like this:
data: () => ({
windowWidth: document.documentElement.clientWidth,
windowHeight: document.documentElement.clientHeight
}),
mounted() {
window.addEventListener('resize', this.setDimensions);
},
methods: {
setDimensions() {
this.windowWidth = document.documentElement.clientWidth;
this.windowHeight = document.documentElement.clientHeight;
},
}
and don't forget to remove it:
beforeDestroy() {
window.removeEventListener('resize', this.setDimensions);
},

Best way to configure Reactstrap carousel images to be responsive

I have done a lot of looking but there is suprisingly little documentation in regard to reactstrap carousel image responsiveness.
My ReactStrap carousel resizes responsively but the images do not.
Options I have researched/tried:
CSS via className in the carousel component itself? This is the one I thought might be best, but I haven't found a combination of background-size, height, and max-width that resizes the image properly.
srcset ? I'm not sure how to implement this or any other inline attribute, given that the carousel is a component
Perhaps some place in the carousel component itself?
Or is there a better way for me to modify the images?
Or is #media the answer via css?
`
const items = [
{
src: 'img1.png',
altText: '',
caption: ''
},
{
src: 'img2.png',
altText: '',
caption: 'Freedom Isn\'t Free'
},
{
src: 'img3.png',
altText: '',
caption: ''
}
];
class HomeCarousel extends Component {
constructor(props) {
super(props);
this.state = { activeIndex: 0 };
this.next = this.next.bind(this);
this.previous = this.previous.bind(this);
this.goToIndex = this.goToIndex.bind(this);
this.onExiting = this.onExiting.bind(this);
this.onExited = this.onExited.bind(this);
}
onExiting() {
this.animating = true;
}
onExited() {
this.animating = false;
}
next() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === items.length - 1 ? 0 : this.state.activeIndex + 1;
this.setState({ activeIndex: nextIndex });
}
previous() {
if (this.animating) return;
const nextIndex = this.state.activeIndex === 0 ? items.length - 1 : this.state.activeIndex - 1;
this.setState({ activeIndex: nextIndex });
}
goToIndex(newIndex) {
if (this.animating) return;
this.setState({ activeIndex: newIndex });
}
render() {
const { activeIndex } = this.state;
const slides = items.map((item) => {
return (
<CarouselItem
className="carouselImg"
onExiting={this.onExiting}
onExited={this.onExited}
key={item.src}
>
<img src={item.src} alt={item.altText} />
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
);
});
return (
<Carousel
activeIndex={activeIndex}
next={this.next}
previous={this.previous}
>
<CarouselIndicators items={items} activeIndex={activeIndex} onClickHandler={this.goToIndex} />
{slides}
<CarouselControl direction="prev" directionText="Previous" onClickHandler={this.previous} />
<CarouselControl direction="next" directionText="Next" onClickHandler={this.next} />
</Carousel>
);
}
}
export default HomeCarousel;
`
Good day and Hello,
I already tried this reactstrap with the Carousel component in my reactjs app.
I solved this by adding bootstrap 4 classess "d-block w-100".
I created this in my reactstrap Carousel component and in this element
from this:
<img src={item.src} alt={item.altText} />
I changed to:
<img className="d-block w-100" src={item.src} alt={item.altText} />
I just copied these classes (d-block w-100) from bootstrap 4 documentation
https://getbootstrap.com/docs/4.0/components/carousel/
This is my example that I used Reactstrap Carousel with Dynamic data from my WordPress Rest API data.
https://github.com/jun20/React-JS-and-WP-Rest-API/tree/home-carousel-final
.carousel-item > img {
width: 100%;
}
... will fix your problem.
And it has nothing to do with Reactstrap. That's probably why you didn't find much. Has to do with the TwBs Carousel alone. I personally don't see any reason why that rule is not part of TwBs carousel CSS, because everyone expects that <img> to have a width of 100% of its parent.
If you want to limit it to a particular carousel, modify the selector accordingly.
Another frequently requested TwBs carousel mod is:
.carousel-control-prev,.carousel-control-next {
cursor:pointer;
}
Given bootstrap uses flexbox, you can make the reactstrap carousel images responsive by adding this to your css:
.carousel-item, .carousel-item.active {
align-items:center;
}
This seems to prevent the image height from stretching. Worked for me!
Based on the reactstrap Carousel example 1 on this page https://reactstrap.github.io/components/carousel/
Here's how I got it to be responsive in my use case:
<CarouselItem
onExiting={() => setAnimating(true)}
onExited={() => setAnimating(false)}
key={item.src}
>
<img src={item.src} alt={item.altText} style={{ width: "100%"}}/>
<CarouselCaption captionText={item.caption} captionHeader={item.caption} />
</CarouselItem>
So, passing in style={{ width: "100%"}} to the img tag, made my oversized images fit the screen perfectly and may work for others coming here.

ExtJS 4 / 5 - Set the correct CSS for a Drag and Drop that is not allowed with custom rules

I have two grids side by side.
The left grid has a list of tags the user can select, and the grid on the right is empty so the user can drag the tags he wants there.
The plugin code for both grids is:
viewConfig: {
plugins: [
Ext.create('Ext.grid.plugin.DragDrop', {
ddGroup: 'selectedTags'
})
]
}
So, as I wanted to limit the user to be able to drag only 5 tags, I've added the following code to the grid on the right:
listeners: {
beforedrop: {
fn: function() {
if (grid.getStore().data.items.length > 4) {
dropHandlers.cancelDrop();
}
},
scope: me
}
}
This is working perfectly but what I wanted is to show the NO-DROP icon when the items are dragged over the grid instead of showing the green line as if the action was allowed.
Thanks,
After looking for this solution for a while, I finally figured it out.
You must add two methods to the dropZone in the Target Grid:
notifyOver and onNodeDrop
The solution for my problem would be the code below:
Ext.create('Ext.grid.Panel', {
store: myStore,
columns: [columns],
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragText: 'Drag and drop to reorganize',
pluginId : 'dragNdrop',
dropZone:{
notifyOver:function(source, e, data){
var store = this.view.ownerCt.getStore();
return store.getCount()<5?this.dropAllowed:this.dropNotAllowed
},
onNodeDrop:function(targetNode,dragZone,e,data){
var sourceStore = dragZone.view.ownerCt.getStore(),
targetStore = this.view.ownerCt.getStore(),
isDropValid = targetStore.getCount()<5;
if(isDropValid){
sourceStore.remove(data.records[0])
targetStore.add(data.records[0]);
}
return isDropValid;
}
}
}
},
height: 200,
width: 400,
renderTo: Ext.getBody()
});
Lopes, you can use column renderer in grid where you can check the items count and display appropriate icon. Code snippet for your reference:
gridCheckboxRenderer: function(value, meta, rec, rowInd, colInd, store){
var cssPrefix = Ext.baseCSSPrefix, cls = [cssPrefix + 'grid-checkheader'];
if (condition == false) {
cls.push(cssPrefix + 'grid-checkheader-checked-disabled');
return '<div class="' + cls.join(' ') + '"> </div>';
}
return '<div class="x-grid-row-checker"> </div>';
}
Hope it helps.

Resources