Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn a 50% discount on the DP-600 certification exam by completing the Fabric 30 Days to Learn It challenge.

Reply
Anonymous
Not applicable

Powerbi custom visual doesn't update when its window resizes

Hi!

 

I'm new to powerbi custom visualisation as well as d3. I'm trying to create a custom visual which display a svg I created. The custom visual is meant to change color (elements of svg) based on my input data via powerbi.

 

I got the visual function as I wanted it to be in debug environment. However, when I resize the visual window or change remove/drag data back in,the visual doesn't update the element's colors but only display the background svg. I have to reload VS code everytime to render the element's colors again. Ive been searching for the reason but failed to find one. Could anyone here can help? It would be much appreciated. Note: the svg is too long so I removed it from the attached code but it should be under "private map"

/*
*  Power BI Visual CLI
*
*  Copyright (c) Microsoft Corporation
*  All rights reserved.
*  MIT License
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy
*  of this software and associated documentation files (the ""Software""), to deal
*  in the Software without restriction, including without limitation the rights
*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*  copies of the Software, and to permit persons to whom the Software is
*  furnished to do so, subject to the following conditions:
*
*  The above copyright notice and this permission notice shall be included in
*  all copies or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*  THE SOFTWARE.
*/
"use strict";

import "core-js/stable";
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 IVisualHost = powerbi.extensibility.visual.IVisualHost;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import VisualObjectInstance = powerbi.VisualObjectInstance;
import DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import * as d3 from "d3";
import * as d3z from "d3-zoom";
import { VisualSettings } from "./settings";
import { zoom, svg, interpolateGreens } from "d3";
import { color } from "d3";
import PrimitiveValue = powerbi.PrimitiveValue;
import IColorPalette = powerbi.extensibility.IColorPalette;
import VisualObjectInstanceEnumeration = powerbi.VisualObjectInstanceEnumeration;
import Fill = powerbi.Fill;
import VisualTooltipDataItem = powerbi.extensibility.VisualTooltipDataItem;
import ISelectionManager = powerbi.extensibility.ISelectionManager;
export class Visual implements IVisual {
    private target: HTMLElement;
    private host: IVisualHost;
    private settings: VisualSettings;
    private selectionManager: ISelectionManager;
    private container: d3.Selection<SVGElement, any, any, any>;
    private map = '<svg.... </g></svg>';

    constructor(options: VisualConstructorOptions) {
        this.container = d3.select(options.element).append('svg');
        const { host } = options;
        this.selectionManager = options.host.createSelectionManager();

    }

    public update(options: VisualUpdateOptions): void {
        if (!options.dataViews || !options.dataViews[0]) {
            return;
        }
        try {
            //this.host.eventService.renderingStarted(options);
            
            var margin = { top: -5, right: -5, bottom: -5, left: -5 },
                width = options.viewport.width - margin.left - margin.right,
                height = options.viewport.height - margin.top - margin.bottom;

            var bg = document.importNode(new DOMParser().parseFromString('<svg xmlns="http://www.w3.org/2000/svg">' + this.map + '</svg>', "application/xml").documentElement.firstChild, true);
            this.container.node().appendChild(bg);
            this.container.selectAll().remove();
            //var hover = this.container.selectAll("path")
            //    .on("click", function () {
            //        d3.select(this)
            //            .transition()
            //            .duration(500)
            //            .style("stroke", "yellow")
            //    })
            //    .on("mouseout", function () {
            //        d3.select(this)
            //            .transition()
            //            .duration(500)
            //            .style("stroke", "black")
            //    });
            //var rows = options.dataViews[0].table.rows;
            //var cols = options.dataViews[0].table.columns;
            var data = options.dataViews[0].table.rows.map((r) => {
                var n: any = {};
                for (var _i = 0; _i < options.dataViews[0].table.columns.length; _i++) {
                    if (options.dataViews[0].table.columns[_i].roles.hasOwnProperty("Shape")) {
                        n.Shape = r[_i];
                    }
                    if (options.dataViews[0].table.columns[_i].roles.hasOwnProperty("StarRanking")) {
                        n.StarRanking = r[_i];
                    }
                    if (options.dataViews[0].table.columns[_i].roles.hasOwnProperty("NormalCondition")) {
                        n.NormalCondition = r[_i];
                    }
                    if (options.dataViews[0].table.columns[_i].roles.hasOwnProperty("N1")) {
                        n.N1 = r[_i];
                    }
                    if (options.dataViews[0].table.columns[_i].roles.hasOwnProperty("Color")) {
                        n.Color = r[_i];
                    }
                }
                return n;
            });

            var paths = [];
            var SRs = [];
            data.forEach(d => {
                //var stars = d.StarRanking.split(",");
                var elements = d.Shape.split(",");
                //var stars = dd.StarRanking.split(",");WW
                elements.forEach((elementItem) => {
                    var element = "#" + elementItem;
                    paths.push(element);

                    //this.container.select(element).style("stroke", "black");
                })
            })
            data.forEach(dd => {
                var stars = dd.StarRanking.split(",");
                stars.forEach((star) => {
                    SRs.push(star);
                })
            })
            data.forEach(dd => {
                var stars = dd.Color.split(",");
                stars.forEach((star) => {
                    SRs.push({
                        stroke: star
                    });
                })
            })

            for (var _m = 0; _m < paths.length; _m++) {
                if (SRs[_m] == "1 Star") {
                    var svg = this.container
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
                        .select(paths[_m]).style("stroke", "red");
                }
                if (SRs[_m] == "2 Star") {
                    var svg = this.container
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
                        .select(paths[_m]).style("stroke", "yellow");
                }
                if (SRs[_m] == "3 Star") {
                    var svg = this.container
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
                        .select(paths[_m]).style("stroke", "orange");
                }
                if (SRs[_m] == "4 Star") {
                    var svg = this.container
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
                        .select(paths[_m]).style("stroke", "blue");
                }
                if (SRs[_m] == "5 Star") {
                    var svg = this.container
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom)
                        .attr("transform", "translate(" + margin.left + "," + margin.right + ")")
                        .select(paths[_m]).style("stroke", "green");
                }
            }
        }
        catch (e) {
            this.host.eventService.renderingFailed(options, JSON.stringify(e));
        }
    }
    private static parseSettings(dataView: DataView): VisualSettings {
        return VisualSettings.parse(dataView) as VisualSettings;
    }
    public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
        return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
    }
}

1.PNG2.PNG

0 REPLIES 0

Helpful resources

Announcements
LearnSurvey

Fabric certifications survey

Certification feedback opportunity for the community.