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

Power BI Custom Visuals - Gradient Fill id not getting refreshed

Hello everyone,

I have just started learning to create Power BI custom visuals and I have created my first custom visual i.e. Circle Card by referring the Microsoft tutorial.

Now, I want to modify this little bit and want to show a percentage based on Actual Value and Target Value and fill the circle according to the percentage i.e. if the percentage is 85% then fill 85% circle with a different color. I have managed to do this using the below sort of code in the Update method of the visual lifecycle.

var gradient = this.container.append("defs").append("linearGradient").attr("id", "gradient")
            .attr("x1", "0%").attr("x2", "0%").attr("y1", "100%").attr("y2", "0%");

        gradient.append("stop").attr("offset", + fillPercent + "%").style("stop-color", "red");

        gradient.append("stop").attr("offset", fillPercent + "%").style("stop-color", "white");

        this.circle
            .style("fill", function () {
                return "url(#gradient)";
            })
            .style("fill-opacity", 1)
            .style("stroke", "black")
            .style("stroke-width", this.visualSettings.gauge.circleThickness)
            .attr("r", radius)
            .attr("cx", width / 2)
            .attr("cy", height / 2);

The problem is that the gradient fill is not getting refreshed based on the percentage I need to press the reload visual button. (See below)

captured.gifI have attached my visual.ts file for the reference. 

Please let me know what's wrong here? 

Thank you in advance.

 

Please click here to open visual.ts 

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Super User II
Super User II

Re: Power BI Custom Visuals - Gradient Fill id not getting refreshed

Hi @Harsh_Jariwala,

As we only have your visual.ts to go on, I can't reproduce fully locally to confirm, the first line in your posted snippet is the suspect:

var gradient = this.container.append("defs").append("linearGradient").attr("id", "gradient")
            .attr("x1", "0%").attr("x2", "0%").attr("y1", "100%").attr("y2", "0%");

How this is currently written, will append a defs element to your container element each time the update method runs, rather than replacing it. This is because your container property (and it's children) is persisted across the lifecycle of the visual.

So, when you start your visual and the update method runs for the first time the gradient is applied as you expect (akin to  your scenario of refreshing the visual to see it in your post). When you update your visual, the original will still be there in the g element represented by this.container.

So, here's what it might look like on the first run:

dm-p_0-1595188573671.png

Now, if I update the visual in a similar way to you, e.g. changing a slicer value, this happens to your DOM when the update method runs:

defs.gif

And if we expand this, it looks as follows:

dm-p_1-1595188940755.png

Hopefully the above should help illustrate that there are 5 defs now attached, and SVG will just be using the first one that was originally added as it's not been cleared down.

There are more elegant ways to solve this, but for minimal changes to your code, add the following line prior to the var gradient... declaration, e.g.:

...

this.container.select('defs').remove();
var gradient = this.container.append("defs").append("linearGradient").attr("id", "gradient")
            .attr("x1", "0%").attr("x2", "0%").attr("y1", "100%").attr("y2", "0%");

...

This checks for the presence of a defs element and removes it prior to adding the new one, and hopefully this is close to what you're after:

defs_remove.gif

Regards,

Daniel





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




View solution in original post

3 REPLIES 3
Highlighted
Super User II
Super User II

Re: Power BI Custom Visuals - Gradient Fill id not getting refreshed

Hi @Harsh_Jariwala,

As we only have your visual.ts to go on, I can't reproduce fully locally to confirm, the first line in your posted snippet is the suspect:

var gradient = this.container.append("defs").append("linearGradient").attr("id", "gradient")
            .attr("x1", "0%").attr("x2", "0%").attr("y1", "100%").attr("y2", "0%");

How this is currently written, will append a defs element to your container element each time the update method runs, rather than replacing it. This is because your container property (and it's children) is persisted across the lifecycle of the visual.

So, when you start your visual and the update method runs for the first time the gradient is applied as you expect (akin to  your scenario of refreshing the visual to see it in your post). When you update your visual, the original will still be there in the g element represented by this.container.

So, here's what it might look like on the first run:

dm-p_0-1595188573671.png

Now, if I update the visual in a similar way to you, e.g. changing a slicer value, this happens to your DOM when the update method runs:

defs.gif

And if we expand this, it looks as follows:

dm-p_1-1595188940755.png

Hopefully the above should help illustrate that there are 5 defs now attached, and SVG will just be using the first one that was originally added as it's not been cleared down.

There are more elegant ways to solve this, but for minimal changes to your code, add the following line prior to the var gradient... declaration, e.g.:

...

this.container.select('defs').remove();
var gradient = this.container.append("defs").append("linearGradient").attr("id", "gradient")
            .attr("x1", "0%").attr("x2", "0%").attr("y1", "100%").attr("y2", "0%");

...

This checks for the presence of a defs element and removes it prior to adding the new one, and hopefully this is close to what you're after:

defs_remove.gif

Regards,

Daniel





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




View solution in original post

Highlighted
Frequent Visitor

Re: Power BI Custom Visuals - Gradient Fill id not getting refreshed

Hello @dm-p,

Thank you so much for your detailed explanation. It resolved my issue.

Thank you once again.

Highlighted
Super User II
Super User II

Re: Power BI Custom Visuals - Gradient Fill id not getting refreshed

No worries! Glad it's working for you 🙂





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!




Helpful resources

Announcements
Upcoming Events

Upcoming Events

Wondering what events you could join or have an event to promote yourself? Check out our Upcoming Events.

Upcoming Events

Community Summit North America – Join Online!

Join this community-driven Power Platform digital event for unbiased support and problem-solving.

Experience what’s next for Power BI

Join us for an in-depth look at the new Power BI features and capabilities at the free Microsoft Business Applications Launch Event.

Community Blog

Community Blog

Visit our Community Blog for articles, guides, and information created by fellow community members.

Top Solution Authors