Starting December 3, join live sessions with database experts and the Microsoft product team to learn just how easy it is to get started
Learn moreGet certified in Microsoft Fabric—for free! For a limited time, get a free DP-600 exam voucher to use by the end of 2024. Register now
I'm developing a custom visual for PowerBI. I have a question . After investigating and the documentation is not very detailed I can't insert items in the dropbox of the capabilities objects, ie I want to have the columns of my table dynamically in a property object like the matrix table has.How to do this?
Solved! Go to Solution.
Are you tring to add a dynamic property for each column that has been added to a custom visual? If so, then I will describe what I am using to acheive that result where you add your property values into the objects collection for a specific column using the DataViewMetadataColumn. Here is an example of a demo custom visual named snazzyTable which produces a custom table where I have added three columns. As you can see, this custom visual gives the user the ability to configure bold formatting on each column seperately.
It took me a little time to figure out working with dynamic objects but the key is recognizing that many objects in the Power BI visuals API have their own objects collections to track custom properties. For example, the metadata for the column named Sales Revenue is persisted into the following path.
Here is how to recreate this effect. Begin in the capabilities.json file by defining a property just like you would for a single static property.
"objects": { "columnFormatting": { "displayName": "Bold Column Formatting", "properties": { "fontBold": { "displayName": "Font Bold", "type": { "bool": true } } } } }
Next, define a generic method to retreive metadata property values. Here is my generic implementation of getValue.
public getValue<T>(objects: DataViewObjects, objectName: string, propertyName: string, defaultValue: T): T { if (objects) { let object = objects[objectName]; if (object) { let property: T = <T>object[propertyName]; if (property !== undefined) { return property; } } } return defaultValue; }
Now comes the tricky part. When you implement enumerateObjectInstance, you must use a special selector for column metadata which invovles creating selector object with metadata propert to reference the specific column.
selector: { metadata: "YourColumnQueryNameHere" }
Here is the full implementation of enumerateObjectInstance. In particualr, check to see how it loops through each metadata column and adds a new property with a selector that includes the column query name.
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration { let objectName = options.objectName; let objectEnumeration: VisualObjectInstance[] = []; var metadataColumns: DataViewMetadataColumn[] = this.dataView.metadata.columns; switch (objectName) { case 'columnFormatting': for (var i = 0; i < metadataColumns.length; i++) { var currentColumn: DataViewMetadataColumn = metadataColumns[i]; objectEnumeration.push({ objectName: objectName, displayName: currentColumn.displayName, properties: { fontBold: this.getValue<boolean>(currentColumn.objects, objectName, "fontBold", false) }, selector: { metadata: currentColumn.queryName } }); }; break; } return objectEnumeration; }
That is all it takes to display the properties in the Format pane and to make these properties editable to the user designig a report. The last part is actually doing something difference once the user sets a column property value I handle this in the update method by querying the column property value and using the result to determine when to make the cell bold or not.
if (this.getValue<boolean>(columns[columnIndex].objects, "columnFormatting", "fontBold", false)) { tableCell.css({ "font-weight": "bold" }); }
Here's a link to the source code for snazzyTable in a GitHub repository.
https://github.com/CriticalPathTraining/CustomVisualsForPowerBI/tree/master/snazzyTable
Based on my research, you may use dataViews in VisualUpdateOptions to make it.
Hi @v-chuncz-msft ,
yes, i have data of columns of dataViews in VisualUpdateOptions, but how make a combo dinamic with this values?
regards
joão
Are you tring to add a dynamic property for each column that has been added to a custom visual? If so, then I will describe what I am using to acheive that result where you add your property values into the objects collection for a specific column using the DataViewMetadataColumn. Here is an example of a demo custom visual named snazzyTable which produces a custom table where I have added three columns. As you can see, this custom visual gives the user the ability to configure bold formatting on each column seperately.
It took me a little time to figure out working with dynamic objects but the key is recognizing that many objects in the Power BI visuals API have their own objects collections to track custom properties. For example, the metadata for the column named Sales Revenue is persisted into the following path.
Here is how to recreate this effect. Begin in the capabilities.json file by defining a property just like you would for a single static property.
"objects": { "columnFormatting": { "displayName": "Bold Column Formatting", "properties": { "fontBold": { "displayName": "Font Bold", "type": { "bool": true } } } } }
Next, define a generic method to retreive metadata property values. Here is my generic implementation of getValue.
public getValue<T>(objects: DataViewObjects, objectName: string, propertyName: string, defaultValue: T): T { if (objects) { let object = objects[objectName]; if (object) { let property: T = <T>object[propertyName]; if (property !== undefined) { return property; } } } return defaultValue; }
Now comes the tricky part. When you implement enumerateObjectInstance, you must use a special selector for column metadata which invovles creating selector object with metadata propert to reference the specific column.
selector: { metadata: "YourColumnQueryNameHere" }
Here is the full implementation of enumerateObjectInstance. In particualr, check to see how it loops through each metadata column and adds a new property with a selector that includes the column query name.
public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration { let objectName = options.objectName; let objectEnumeration: VisualObjectInstance[] = []; var metadataColumns: DataViewMetadataColumn[] = this.dataView.metadata.columns; switch (objectName) { case 'columnFormatting': for (var i = 0; i < metadataColumns.length; i++) { var currentColumn: DataViewMetadataColumn = metadataColumns[i]; objectEnumeration.push({ objectName: objectName, displayName: currentColumn.displayName, properties: { fontBold: this.getValue<boolean>(currentColumn.objects, objectName, "fontBold", false) }, selector: { metadata: currentColumn.queryName } }); }; break; } return objectEnumeration; }
That is all it takes to display the properties in the Format pane and to make these properties editable to the user designig a report. The last part is actually doing something difference once the user sets a column property value I handle this in the update method by querying the column property value and using the result to determine when to make the cell bold or not.
if (this.getValue<boolean>(columns[columnIndex].objects, "columnFormatting", "fontBold", false)) { tableCell.css({ "font-weight": "bold" }); }
Here's a link to the source code for snazzyTable in a GitHub repository.
https://github.com/CriticalPathTraining/CustomVisualsForPowerBI/tree/master/snazzyTable
I'd like to see this answer updated to use the new getFormattingModel API instead of enumerateObjectInstance
Your reply is a lifesaver, I was looking for this! I will write a blog article out of this as a continuation of series on how to develop custom visuals, I will make sure to give you credit!
Proud to be a Super User!
Awesome Keyboard Shortcusts in Power BI, thumbs up if you like the article
My Community Blog Articles (check them out!)
My Blog - Power M code to automatically detect column types -
How to create test data using DAX!
Hi @TedPattison,
Thank you for the long post, but it was very useful, the trick was in the
selector: { metadata: "YourColumnQueryNameHere" }
and
displayName: currentColumn.displayName,
thanks you so much
regards
João
hi @joao_pires , and how you add dynamic data to combo box?
i try all step above and my combo box still show the static data from capabily file
this is my visual.ts
and this is my browser console log
hi @Anonymous ,
when dev my custom visual this option is not possible.
I make a combobox dinamic into CV in CSS.
hope is help you.
thanks @joao_pires and @TedPattison
finally I'm create dynamic color picker as much as fields values selected, and strore in dataview using selector metadata.
Starting December 3, join live sessions with database experts and the Fabric product team to learn just how easy it is to get started.
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early Bird pricing ends December 9th.
User | Count |
---|---|
4 | |
3 | |
2 | |
2 | |
1 |