cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Highlighted
dbardele Frequent Visitor
Frequent Visitor

Custom Visual cut off after resizing in Power BI Service

Hello, I'm new to developing custom visuals but I have something (sort of) working after following tutorials and watching YouTube videos. However, I cannot get mine to resize bigger than a postage stamp, nor to do so in real time as I change the viewport. This also was a problem when I was resizing the tutorial "Update Counter"...my counter didn't count up at all even though I was following the tutorial exactly. I'm wondering if it's because I'm using a different version of pbiviz (3.1.1) than the tutorial was written in.

 

Here is the code that I think defines sizing (unfortunately I cannot attach screengrabs of the visual). However, I may be missing something in one of the other files. Any advice will be greatly appreciated. Thanks!

 

Dom

 

import "./../style/visual.less";

import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;

import * as d3 from "d3";

export class Visual implements IVisual {

private svgRoot: d3.Selection<SVGElement, {}, HTMLElement, any>;
private xAxis: d3.Selection<SVGElement, {}, HTMLElement, any>;
private yAxis: d3.Selection<SVGElement, {}, HTMLElement, any>;
private line: d3.Selection<SVGElement, {}, HTMLElement, any>;
private circle: d3.Selection<SVGElement, {}, HTMLElement, any>;
private padding: number = 20;

constructor(options: VisualConstructorOptions) {
console.log('Visual constructor', options);

this.svgRoot = d3.select(options.element)
.append("svg")
.append("g");

this.xAxis = this.svgRoot
.append("g")
.attr("class", "x axis")
.style("stroke", "black")
.style("stroke-width", "1");

this.yAxis = this.svgRoot
.append("g")
.attr("class", "y axis")
.style("stroke", "black")
.style("stroke-width", "1");

/*
this.line = this.svgRoot
.append("g")
.style("stroke", "black");
*/

this.RenderVisual(options.element.clientWidth, options.element.clientHeight);

}

public update(options: VisualUpdateOptions) {

console.log('Visual update', options);

// let dataView: DataView = options.dataViews[0]

this.RenderVisual(options.viewport.width + 20, options.viewport.height + 20);

}

private RenderVisual(clientWidth: number, clientHeight: number) {

this.svgRoot
.attr("width", clientWidth)
.attr("height", clientHeight);

var plot = {
xOffset: 0, // this.padding,
yOffset: 0, // this.padding,
width: clientWidth - (this.padding * 2),
height: clientHeight - (this.padding * 2),
};
1 ACCEPTED SOLUTION

Accepted Solutions
dm-p Established Member
Established Member

Re: Custom Visual cut off after resizing in Power BI Service

Hi there,

Once thing I'd suggest is that this part of your code needs tweaking to make the visual keep track with the viewport:

this.svgRoot = d3.select(options.element)
    .append("svg")
    .append("g");

This is assigning the variable to the <g> (group) element that you append to the <svg> element, rather than the <svg> element itself.

When you call renderVisual, it's resizing the <g> element, and not the parent <svg>, e.g.:

zbcvR2bThe parent <svg> (as it has no explicit width & height attributes) will get rendered using the browser default (in my case it's 300 x 150 pixels.

Because the <g> element sits inside it, the parent will never grow to fit it.

It might be better to, set your svgRoot to the actual <svg> element, i.e.:

this.svgRoot = d3.select(options.element)
    .append("svg");

This way, renderVisual will resize the container element, e.g.:

w2sqiDb

Note that if you still want to group your axis elements, then you'll need to add in the parent <g> to group them somewehre else, as we removed it from the code, but this should allow you to size your SVG canvas with the viewport accordingly.

Good luck!

Daniel

View solution in original post

3 REPLIES 3
dm-p Established Member
Established Member

Re: Custom Visual cut off after resizing in Power BI Service

Hi there,

Once thing I'd suggest is that this part of your code needs tweaking to make the visual keep track with the viewport:

this.svgRoot = d3.select(options.element)
    .append("svg")
    .append("g");

This is assigning the variable to the <g> (group) element that you append to the <svg> element, rather than the <svg> element itself.

When you call renderVisual, it's resizing the <g> element, and not the parent <svg>, e.g.:

zbcvR2bThe parent <svg> (as it has no explicit width & height attributes) will get rendered using the browser default (in my case it's 300 x 150 pixels.

Because the <g> element sits inside it, the parent will never grow to fit it.

It might be better to, set your svgRoot to the actual <svg> element, i.e.:

this.svgRoot = d3.select(options.element)
    .append("svg");

This way, renderVisual will resize the container element, e.g.:

w2sqiDb

Note that if you still want to group your axis elements, then you'll need to add in the parent <g> to group them somewehre else, as we removed it from the code, but this should allow you to size your SVG canvas with the viewport accordingly.

Good luck!

Daniel

View solution in original post

dbardele Frequent Visitor
Frequent Visitor

Re: Custom Visual cut off after resizing in Power BI Service

Oh my goodness THANK YOU! That fixed it. It's still not resizing automatically when I drag the window size around like in the tutorial, but I can live with that. As soon as I click refresh, it resizes to the viewport window.

 

Thanks again! On to find the next thing that will confound me...

 

Dom

dm-p Established Member
Established Member

Re: Custom Visual cut off after resizing in Power BI Service

No probs! Glad you're sorted. There will be many confounding things to work on ;), but chip away at them...

FYI if you need to refresh the visual to fix your issue, that suggests something to do with code in the constructor method (which runs on instantiation) is working vs. the update method (which runs for every change afterwards).

I notice that you have a renderVisual call in both of these methods. It will be better to try and manage it in the update method rather than the constructor (use the contructor to create the element placeholders, but handle sizing and drawing that depends on changes to the visual in update).

Here's a simple custom visual I did for a presentation recently - it's a knock-off of the circle-card visual and is done on the older tooling, but if you look at the function code, the approach is similar. It might help you with obtaining some code to handle resizing and where to do it in the workflow.

 

Helpful resources

Announcements
Ask Amir Anything

Exclusive LIVE Community Event No. 2 – Ask Amir Anything

Next in our Triple A series: Ask Amir Netz questions about the latest updates, features and future.

Ask Amanda Anything Q&A

Ask Amanda Anything Q&A

Learn the answers to some of the questions asked during the Amanda Triple A event.

October 2019 Community Highlights

October 2019 Community Highlights

October was a busy month in the community. Read the recap article to learn about some of the events and content.

New Solution Badges

New Solution Badges

Two waves of brand new solution badges are coming! Read the article for more information on our new community badges.

Users Online
Currently online: 366 members 3,546 guests
Please welcome our newest community members: