Adding Highlighting To Your Power BI Custom Visual
This video explains how to add highlighting functionality to your Power BI custom visual. This is video #13 of the Power BI Custom Visual Development Fundamentals series, please check the playlist below for the set.
Video Transcript
Hello again and welcome back.
Today we’ll take a look at how to add highlighting behaviour to our little custom bar chart.
If you’ve watched the previous video about interactions, you may be wondering, wait, didn’t we do that already?
Well, not quite.
What we did do was to handle clicks on our own custom visual and handle highlighting according to that.
If I click on the bars of our custom visual on the left side, its own bars will highlight themselves, and you’ll see that the vanilla bar chart in the right side will also highlight itself accordingly.
However, the opposite is not true.
If I click on some bars in the vanilla visual, our own visual will get filtered instead of highlighted.
So why the difference in behaviour?
Well, this really depends on the type of interactions that we have configured in the report and how our custom visual supports them.
If I click on our custom visual and then click View Interactions, I can see that the custom visual is set to highlight the vanilla visual.
If I change this setting to filter and then select a couple of bars, you will see that the vanilla bar chart is filtered instead.
If I change this back to highlight, we get highlighted columns again.
All far so good.
The thing is, if I click the vanilla visual to edit its visual interactions, I can see that I have no highlight option at all against the custom visual.
All my interactions will the vanilla visual will result in filtering the custom visual, without any way to change its behaviour.
Well, that’s what we going to enable today.
So let’s get to it.
The first step is tell Power BI that our visual does indeed support highlighting behaviour.
For that, we need to go into the capabilities.json file.
If you recall from video number 6 about creating a new project, this file is where you declare to Power BI what your visual can be expected to support, such as what data roles does it accept.
"supportsHighlight": true,
To declare we support highlighting, we can add the supportsHighlight property right here in the top.
So let’s save the project and examine what this accomplished.
Interesting, we now have a highlighting option there.
But does this actually do?
Let’s select it and play around.
Well, at first glance it appears to do nothing.
But it in fact, it is doing two things under the covers.
For starters, clicking the bars on the vanilla visual does not filter the custom visual anymore.
The custom visual is receiving the entire dataset now at all times, regardless of other selections.
The second thing, the custom visual is now also receiving something else.
Let’s click on the debug toolbar to explore the data view.
If we take a close look, we’re now receiving an extra bit of information.
In addition to the values array, which we were already getting, we are now receiving a new highlights array as well.
The way this works is that this array will have the same length as the values array and it will be populated for every value item that Power BI believes should be highlighted.
So on the vanilla visual, we can see that we have the second bar selected.
Right now, this corresponds to the second filled in value in the highlights array right here.
Of course, this beautiful and very unrealistic example is only working because both visuals are essentially showing the same data in the same order, so it’s easy to see the relationship between the two.
In reality, and depending on how you build your report, this highlights array won’t necessarily map one-to-one with anything obvious anywhere else, so don’t take this for granted.
Another thing you may have noticed is that the highlight value here is not exactly the same as the corresponding value in the values array.
That’s strange but it is fine.
The way to interpret the highlights array is that, if a given position has any value whatsoever, then that position is meant to be highlighted in whatever way your particular visual does it.
Now, before we move on, something to consider, is that the highlight functionality is not guaranteed to work all the time and with all the visuals, even all the vanilla ones.
There are certain filtering methods in the API that completely bypass the highlighting mechanism and will outright filter everything in a report, regardless of your setting.
Therefore, when you are building highlight into your visual, and you are testing and scratching your head on why things don’t seem to work, well, before anything, test against a visual that does work against highlighting such as the vanilla bar chart or pie chart.
If your visual is getting highlight data from either of those two, but not another one, then most likely the problem is with that other visual and not with yours to begin with.
Okay, so with all that out-of-the-way, let’s actually do some highlighting.
You may have guessed what’s the first thing to do.
That’s right, back we are to the DataPoint interface, our favourite spot in this entire code base.
Let’s add a new property named highlighted of type boolean.
As usual, the compiler complains about the viewmodel code, but we’ll fix that in a bit.
Before that, we’re going to add a helper property to the viewmodel interface itself.
highlights: boolean
This property is just here to help simplify the rendering code later, you will see what I mean.
Now let’s go down the view model loading code and add some more bits.
let highlights = values.highlights;
First let’s get that highlights array we saw back there.
Do note that this highlights array is an optional property so it may or it may be defined.
Don’t assume it and always test for it.
highlighted: highlights ? highlights[i] ? true : false : false
Now let’s add some code to define the highlighted property on each data point.
This just checks if the highlights array is defined to begin with and then whether it has any value in the same position of the corresponding values array.
Again, we don’t care about the actual value, we just care that we have anything other than null in there.
viewModel.highlights = viewModel.dataPoints.filter(d => d.highlighted).length > 0;
Now let’s just fill in that helper property in the view model.
This will be true if any data point is highlighted to begin with.
highlights: false
Of course, we also need to add a default to the initialization code in the top here.
The final step is to make this render something.
Let’s go to the rending code, in the bit where we define CSS style rules for each bar.
"fill-opacity": d => viewModel.highlights ? d.highlighted ? 1.0 : 0.5 : 1.0
Now we just need to a fill opacity style rule that acts on the basis of highlighting.
The criteria here is very simple.
If we have any highlights at all in view model, then we leave the highlighted bars at full opacity and we dim all other bars.
If we don’t have any highlights to begin with, then we don’t anything with the bars and leave them at full opacity.
That’s it.
Let’s save the code and see how this works.
There you have it.
Fully working highlighting.
Neat, isn’t it?
That’s it for today.
Thanks for watching and let me know if you have any questions.
Also if you’re new here, be sure to subscribe and enable notifications, so you’re the first to know about new content.
In the next video in the series, we will look at how to add simple properties to the property pane of your custom visual.
Until then, take care and see you next time.