Earn the coveted Fabric Analytics Engineer certification. 100% off your exam for a limited time only!
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.
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;
}
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?).
Solved! Go to Solution.
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
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)
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) ?
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
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.