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

How To Share Visual Selection Between Visuals: powerbi-visuals-tools@3.0, powerbi-visuals-api@2.2.2

Hello!

I'm in the process of setting up a custom slicer visual to pass a datapoint selection to several other visuals in the same report. The gist of the problem is that when select is called on the custom slicer visual, the other visuals execute their "registerOnSelectCallback" functions, but the ids parameter is always null. I doubled checked that the selection manager on the custom slicer has an id selected:

 

how-to-send-selection-to-multiple-visuals-on-single-report.gif

 

I'm using selection manager on powerbi-visuals-tools@3.0.7 (beta) and powerbi-visuals-api@2.2. Nothing related to selection is added in the capabilities.json.

 

Here's the effected portions of the custom slicer visual.ts: 

 

Constructor:

 

private target: HTMLElement;
private host: IVisualHost;
private manager: ISelectionManager;
private settings: VisualSettings;
private selectionIds: any = {};
private isEventUpdate: boolean = false;

constructor(options: VisualConstructorOptions) {
        let that = this;
       
        this.target = options.element;
        this.host = options.host;
        this.manager = this.host.createSelectionManager();
    }

 

 

Update function:

public update(options: VisualUpdateOptions) {
        if (!this.isEventUpdate) 
            this.init(options);
    }

 

Init function:

private init(options: VisualUpdateOptions) {
        let that = this;

        //clear selection ids array and element html (for select box)
        this.target.innerHTML = "";
        this.getSelectionIds(options.dataViews);

        let keys = Object.keys(this.selectionIds);

        //Create and append select list
        let select = d3.select('body')
            .append('select')
            .classed('selectbox', true)
            .on('change', function (e) {
                that.isEventUpdate = true;

                let value = select.node().value;

                // clear out any previous selection ids
                that.manager
                    .clear()
                    .then(() => {

                        // Find the selectionId and select it
                        that.manager
                            .select(that.selectionIds[value])
                            .then((ids: ISelectionId[]) => {
                                ids.forEach(function (id) {
                                    console.log(id);
                                });
                            })
                            .catch(() => {})
                            .finally(() => {
                                that.isEventUpdate = false;
                                debugger;
                            });
                    
                    });

                (<Event>d3.event).stopPropagation();
            });

        this.target.appendChild(select.node());

        keys.forEach((item: string, index: number) => {

            let option = document.createElement("option");

            option.value = item;
            option.text = item;

            select.node().appendChild(option);
        });
    }

 

Function to get SelectionId's (e.g. a table view work-around based on v-iig's answer on the thread: https://community.powerbi.com/t5/Developer/Creating-Selection-manager-for-Custom-Table-visuals/m-p/2...)

 

private getSelectionIds(dv: DataView[]): ISelectionId[] {
        let dataview = dv[0];
        let that = this; 

        return dataview.table.identity.map((identity: any) => {
            const categoryColumn: powerbi.DataViewCategoryColumn = {
                source: dataview.table.columns[0],
                values: null,
                identity: [identity]
            };

            let id = that.host
                .createSelectionIdBuilder()
                .withCategory(categoryColumn, 0)
                .createSelectionId();

            that.selectionIds[`${dataview.table.columns[0].displayName}${identity["identityIndex"]}`] = id;

            return id;
        });
    }

 

Here's the affected portion of one of the visuals that is supposed to listen for the selectionId of the above custom slicer:

 

Constructor

private target: HTMLElement;
    private settings: VisualSettings;
    private svg: any;
    private app: any;

    private host: IVisualHost;
    private manager: ISelectionManager;
    private selectionIds: any = {};

    constructor(options: VisualConstructorOptions) {
        let that = this;

        that.target = options.element;
        that.svg = d3.select(options.element)
            .append('svg')
            .classed("chart", true);

        that.host = options.host;
        that.manager = that.host.createSelectionManager();
        
        that.manager.registerOnSelectCallback((ids: ISelectionId[]) => {
            //called when a selection was set by Power BI
           //note when custom slicer select is called, this function executes
           //but the ids array is empty, we expect the id selection populated though...

            debugger;
        });
    }

 

 

Any help is appreciated!

 

All the best,

Diran O.

 

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: 384 members 3,327 guests
Please welcome our newest community members: