Adding Data Bound Properties To Your Power BI Custom Visual

Adding Data Bound Properties To Your Power BI Custom Visual

Learn how to add data properties to your Power BI Custom Visual. This is video #16 of the Power BI Custom Visual Development Fundamentals series, please check the playlist below for the set.

Resources

Transcript

Hello again and welcome back to this series on developing Power BI Custom Visuals.

Today I’ll show you how to add data bound settings to the properties pane of your visual.

These data bound properties allow the user to configure aspects of your visual that are related to a specific bit of data, for example, a specific series or a specific category.

In this video, such a property will enable users to choose a specific colour for each specific category bar.

So, let’s get to it, right now.

Just like in the last video about simple properties, we can begin by going to the capabilities.json file so we can declare another property group.

"dataColors":{
    "displayName": "Data Colors",
    "properties": {
        "fill":{
            "displayName": "Color",
            "type": {
                "fill": {
                    "solid": {
                        "color": true
                    }
                }
            }
        }
    }
}

This time, we’re adding a new property group called data colors, that contains a single property called fill and that the user will see as color.

The type of this property is a bit out of the ordinary but it basically tells Power BI to render a color picker for this property.

The value you get from that color picker is a typical hexadecimal color code, the same format that you can use in html.

Now from the point of view of the capabilities file, there is no real difference between a simple property and a data bound property.

What makes that difference is the way we handle the property in code.

In this case, instead of a single setting that we read and write, we want to get and persist a different color value per each data category that we have on-screen, regardless of how many categories there are.

To make that happen, we need to treat this property in a different way than before.

Instead of just adding a new simple setting, what we want to do is to associate a color value to each of data points.

Luckily, we have already done that.

The color property here is already what allows each bar to have its own color, so that’s one step less.

We can therefore go right ahead and populate these colors in the properties pane.

And you guess it, we do this in the unnecessarily named enumerate object instances function.

Now that’s a mouthful every single time.

 case "dataColors":

                    break;

But anyway, in here we can add another block to handle rendering of the data colors property group.

This block needs to be somewhat different though, as again, instead of rendering a single property on the pane, we need to render one unique property per category in our data.

The thing is, those categories and those colors currently live in the view model object, which is only populated at update time.

However, this function runs outside of the update cycle, so it doesn’t have access to the view model to begin with.

Well, that’s something we need to fix.

We need to make the view model available at the visual instance level.

private viewModel: ViewModel;

We can do this by adding a new instance variable here called viewmodel.

this.viewModel = this.getViewModel(options);

And then in the update function, we change the local viewmodel variable to the instance variable.

This will break things here a bit, so let’s just fix them before we move on.

And there you go, the view model is now accessible everywhere in the visual.

if (this.viewModel) {
    for (let dp of this.viewModel.dataPoints) {
        properties.push({
            objectName: propertyGroupName,
            displayName: dp.category,
            properties: {
                fill: dp.colour
            },
            selector: dp.identity.getSelector()
        })
    }
}

This mean we can go back to the enumerate something something function and add the remaining code.

So there are a couple of things different here.

First, instead of just pushing a single property to power bi, we’re instead pushing one property per each live data point that we have.

Our data points do map to categories in this visual, so this is about right.

Second, for each property that we push, we are defining a custom display name for it, using the category name.

If we didn’t do this, we would see the default display name of color in every single property and that would be quite useless.

Third, we are now providing this selector value as well.

This is where the magic happens.

The selector is a bit of information that allows Power BI to store the color value we provide here against the specific slice of data that this data point identifies.

This is how Power BI can know that a certain property value belongs to a certain category as opposed to being a simple property with a single value.

In this way, Power BI can store multiple values for this property and will be able to return them to you, associated with each category, every time you ask.

In fact, let’s see this in action.

So now we can see a list of all the categories here, and we can select a color for each.

Thing is, it’s not applying any color other than the default and that’s because we’re not yet reading the color that the user is manually selecting.

But that’s fine, before we fix this, I want to show you how Power BI provides that manual color to you.

So if you switch here to data view mode, and you expand the metadata view, you’ll see exactly nothing.

This is a consequence of using that selector when populating the properties.

When you do that, what Power BI does is, instead of showing your property in the metadata view, it attaches it directly to the appropriate place in whatever data view you are requesting.

In our case, we are requesting a categorical data view and we are saying, by using the selectorId, that each value maps to a single category.

Meaning, we are literally data binding that setting.

Based on that, Power BI has enough information to bring in the user selected color right next to the category itself.

Or well, at least, in this objects array, in the same index position of the equivalent category values array.

It’s kind of the same thing anyway.

So, this whole thing means that we can read these data bound settings at the same time as we’re reading the rest of the view model data.

let objects = categories.objects;

First we get that objects array from the category array.

Now we need to keep in mind this objects array may or may not be there to begin with.

We need to check for its existence every time we want to access it.

colour: objects && objects[i] && DataViewObjects.getFillColor(objects[i], {
                        objectName: "dataColors",
                        propertyName: "fill"
                    }, null) || this.host.colorPalette.getColor(categories.values[i]).value,

And that’s precisely what we’re going to do right now.

So we’re doing something similar here to what we did in the updatesettings function.

The only difference is that instead of grabbing properties from the metadata view, we’re now grabbing them straight from the categories view, via that object array.

Of course, we’re checking whether the objects array is there to begin with and if it isn’t, or if it is but is has no relevant data, then we just default to the palette color we had before.

So let’s see what this did.

And there you have it, you can select the colors in the chart to your heart’s content.

You can also revert the color back if you’re not happy with it and use the palette color instead.

That’s it for today.

If you have any questions, let me know and I’ll get back to you.

In the next video in this series, you will learn how to add some nice little data tooltips to this visual.

Until then, take care and see you next time.

Jorge Candeias's Picture

About Jorge Candeias

Jorge helps organizations build high-performing solutions on the Microsoft tech stack.

London, United Kingdom https://jorgecandeias.github.io