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

Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!

Reply
john_m_dixon
Frequent Visitor

VisualObjectInstanceEnumerationObject formatting pane shows blank displayName

Using API v3.2.0 and have also tried v2.6.0 for this issue.

I'm attempting to use VisualObjectInstanceEnumerationObject to do categorized formatting options similar to the Table visual's Field formatting object. 

fieldFormatting.png

I am succesfully populating the VisualObjectInstanceEnumerationObject object, and am seeing results populated in the formatting pane for each of my containers, which are bound to to categories in a categorical dataview mapping. I can use the dropdown to switch between containers, and the results are bound to the dataview as expected. My issue is that the text of the dropdown for each category is blank for every option. See relevant code below (this is a contrived example but is representative of the issue):

capabilities.json

 

{
    "dataRoles": [
        {
            "displayName": "Category",
            "name": "category",
            "kind": "Grouping"
        },
        {
            "displayName": "Measure",
            "name": "measure",
            "kind": "Measure"
        }
    ],
    "objects": {
        "polygons": {
            "displayName": "Polygons",
            "properties": {
                "polyFill" :{
                    "displayName": "Polygon Color",
                    "type": {
                        "fill": {
                            "solid": {
                                "color": true
                            }
                        }
                    }
                }
            }
        }
    }
    "dataViewMappings": [
        {
            "categorical": {
                "categories": {
                    "for": {
                        "in": "category"
                    },
                },
                "values": {
                    "select": [
                        {
                            "bind": {
                                "to": "measure"
                            }
                        }
                    ]
                }
            }
        }
    ]
}

 

dataview conversion

 

    public convert(): dataPoint[]{
        const categorical = this._options.dataViews[0].categorical;

        const categories: DataViewCategoryColumn[] = categorical.categories;
        const values: DataViewValueColumns = categorical.values;

        const category = categories[dataRoleHelper.getCategoryIndexOfRole(categories, 'category')];
        const value = values.find(d => dataRoleHelper.hasRoleInValueColumn(d, 'measure'));

        const data: dataPoint[] = [];
        const scaleColor = d3.scaleOrdinal(d3.schemeSet3);
        
        for (let i = 0; i < category.values.length; i++){
            data.push({
                xValue : <number>category.values[i],
                yValue: <number>value.values[i],
                selectionId: this.host.createSelectionIdBuilder().withCategory(category, i).createSelectionId(),
                color: scaleColor(i.toString())
            });
        }

        return data;
    }

 

enumerateObjectInstances

 

    public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
        let instances: VisualObjectInstance[] | VisualObjectInstanceEnumerationObject =
            (<VisualObjectInstanceEnumerationObject>VisualSettings.enumerateObjectInstances(this.settings, options)).instances || [];

        switch (options.objectName) {
            case 'polygons': {
                if (this.visualData) {
                    instances = {
                        containers: this.visualData.map(d => { return { displayName: `${d.xValue}, ${d.yValue}` } }),
                        instances: this.visualData.map((d, i) => {
                            return {
                                containerIdx: i,
                                objectName: "polygons",
                                displayName: `${d.xValue}, ${d.yValue}`,
                                properties: {
                                    polyFill: { solid: { color: d.color } }
                                },
                                selector: d.selectionId.getSelector()
                            }
                        })
                    };
                }
                break;
            }
        }

        return instances;
    }

 

blankDisplayName.png

The type of displayName is:

 

    export type DisplayNameGetter = ((resourceProvider: IStringResourceProvider) => string) | string;

 

I've tried to set the value of displayName to a function that takes an IStringResourceProvider and return my chosen container name as a string. I have also tried to use the get(id: string) method of IStringResourceProvider, passing in the chosen string name as the id. If there is a significance of the id parameter of the get method, then I've been unable to determine it.

I debugged the execution of the Table visual and can see that it simply passes the displayName of the container as a string as I appear to be doing. Not sure what the difference is (maybe different API for first party visuals?).

tableVisualDisplayName.png

 @v-viig @v-evelk @jamesdales 

1 ACCEPTED SOLUTION
dm-p
Super User
Super User

Hi @john_m_dixon,

Your approach is correct, but unfortunately containers don't work properly for custom visuals. It's somewhat frustrating, particularly as the MS-produced ones seem to work (although they have the same issue if you build them locally). I recently asked the team on its status and it's still outstanding.

Regards,

Daniel





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

Proud to be a Super User!


My course: Introduction to Developing Power BI Visuals


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




View solution in original post

4 REPLIES 4
WouterBo
Helper II
Helper II

This approach seems to work in custom visuals now (using API 3.5.1). 

But how do I determine which value was selected in the combo box when I read the changed object? I can't seem to access the containerIdx in the metadata or elsewhere in the VisualUpdateOptions.

Hi! 
Any progress with finding containerIdx to track what is exactly changed. (... or dropdown selected value, or container instance, or anything to solve property mapping when containers and slectors used)  ?

dm-p
Super User
Super User

Hi @john_m_dixon,

Your approach is correct, but unfortunately containers don't work properly for custom visuals. It's somewhat frustrating, particularly as the MS-produced ones seem to work (although they have the same issue if you build them locally). I recently asked the team on its status and it's still outstanding.

Regards,

Daniel





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

Proud to be a Super User!


My course: Introduction to Developing Power BI Visuals


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




Thanks @dm-p, I got the same feedback from Microsoft, but hadn't been able to find the github issue you mentioned. It's a little puzzling that pbiviz scaffolds this interface into all new projects if it isn't usable by the api flagged for custom visuals and isn't ready for prime time.

Helpful resources

Announcements
April AMA free

Microsoft Fabric AMA Livestream

Join us Tuesday, April 09, 9:00 – 10:00 AM PST for a live, expert-led Q&A session on all things Microsoft Fabric!

March Fabric Community Update

Fabric Community Update - March 2024

Find out what's new and trending in the Fabric Community.

Top Solution Authors
Top Kudoed Authors