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

The ultimate Microsoft Fabric, Power BI, Azure AI & SQL learning event! Join us in Las Vegas from March 26-28, 2024. Use code MSCUST for a $100 discount. Register Now

stevedep

Quickly build a Custom Power BI Visual (KPI Card) from scratch

Building a Custom Power BI Visual from scratch (KPI Card)

In this article we will build a custom Power BI visual from scratch, we will build a KPI card with selections (interactivity in the dashboard), drill-through functionality, formatting options and highlighting.

The code changes are kept to a minimum, so we hardly use typing or describe interfaces. This allows us to focus on the core mechanisms that we need to introduce in the code.

Each steps links to a GitHub commit so you can easily reproduce what happened. This article is a repost from a Medium article, I am the original author. 

Enjoy!

 

Create the Solution

First, we create a new visual using PowerShell and open Visual Studio:

pbiviz new KPICard_Tutorial
cd kPICardTutorial
start devenv .

See commit for the newly created files.

 

Create the Power BI File

We create the Power BI File with some Sample Data.

stevedep_0-1659506331148.png

 

We publish the Power BI file to the cloud and start the server (using PowerShell).

pbiviz start

We add the custom visual (‘</>’) and press the reload button (triangle).

stevedep_1-1659506340958.png

 

stevedep_2-1659506365464.png

 

Start Developing

We start to make changes in visual.ts and once we save the file, we can directly see the impact on the visual running on the web.

stevedep_3-1659506376125.png

 

First, we remove all the lines in the constructor and most of them in the update function. See results here. The code and debugger results look like this:

stevedep_4-1659506385384.png

 

We will now add a rectangle for each KPI. We will do this in a very stripped-down manner, so without any nice typed containers as described in the official documentation, to keep this as straightforward as possible.

First, we add a svg element using D3 (see commit)

stevedep_5-1659506394242.png

 

When we right-click on our visual and select ‘inspect’, we see that the SVG element has been created.

stevedep_6-1659506400883.png

 

Add rectangle per KPI

Next, we create a rect element per KPI using D3, see commit and illustration below.

stevedep_7-1659506410511.png

 

In line 58, we directly mapped our Power BI data to the data property of our rectangles by copying the path to the value from the inspector:

stevedep_8-1659506419547.png

 

Add ‘console.log(options)’ in the update function, open DevTools (or equivalent) to access the options object.

As a result, we see that the rect elements have been created:

stevedep_0-1659506478339.png

 

After updating the visual the number of rect elements stays the same, so D3 is properly mapping the elements to the provided dataset (thanks to the class attribute).


Add content and attributes to the rectangles

To set the x position dynamically, we add an index to the list of values to help determine the x position. We also add width and height and styling attributes to ensure our squares become visible.

We also need to make sure the SVG element’s width is equal to the viewport width.

The code looks like this:

stevedep_1-1659506530577.png

 

See code changes here, please note our dataset is now called ‘map2’.

The result is that the squares will now automatically evenly distribute over the width of the viewport width (with each update of the visual).

stevedep_2-1659506545913.gif

 

Add selections / Interactivity

We will now add selections interaction which looks like this:

stevedep_3-1659506558450.gif

 

So, selecting a rectangle results in interaction with other dashboard elements.

To add selections interaction, we need to retreive selectionId’s, add these to the dataset and add the function call ‘this.selectionManager.select()’ to the on click event of a square. See changes in this commit. Primarily, the changes revolve around making the host and selectionmanager available in the visual class instance. So the selectionManager.select() call can be made on a ‘click’ event.

stevedep_4-1659506589921.png

 

For more info, see this article on selections.

 

Add highlighting

To visually emphasize the square selected we use the SelectionId of the currently selected element to highlight that one, the remainder will be very light. In case of no selection, the squares will be dark. The result looks like this:

stevedep_5-1659506602790.gif

 

We only added a few lines, again in a very stripped-down manner, just to understand the core mechanisms at work. See commit here.

stevedep_6-1659506612770.png

 

‘selectionManager.select’ returns the id’s of the selected elements. recSelectionMerged contains all the KPI elements. We compare id’s, when its a match we assign a different opacity to the element.

 

Adding formatting options

We will now add color pickers to the Visualization pane, which looks like this:

stevedep_7-1659506627719.gif

 

We need to make sure powerbi-visuals-utils-dataviewutils has the latest version so we can import dataViewWildcard. For this, we might need to, update, upgrade and ‘npm’ install ‘powerbi-visuals-utils-dataviewutils’. See here for all the needed dependencies (that can be installed via NPM).

import { dataViewWildcard } from "powerbi-visuals-utils-dataviewutils";


The most important part of the code change is the modification the enumerateObjectInstances, to ensure the formatting pane is populated with our KPI’s. Therefore, we iterate this.map2

stevedep_0-1659506719075.png

 

Please note line 166, the selector, this basically holds the index position of the KPI to link this formatting option to the right KPI (it seems..). This is the content of the selector.

stevedep_1-1659506731117.png

 

Once a color is selected, it adds a property to the dataViews object. Before any color selection DataViews looks like this:

stevedep_2-1659506747153.png

 

After a color has been selected the dataViews looks like this:

stevedep_3-1659506756376.png

 

The objects property has been added and contains the selected colour.

Therefore, we add this code to check for the ‘objects’ property and then assign the color to our dataset, if present.

stevedep_4-1659506764859.png

 

This allows us to set the selected fill color here.

stevedep_5-1659506773874.png

 

Add Highlighting

Finally, we add highlighting. This allows interaction from other visuals to our visual. The result looks like this:

stevedep_6-1659506783470.gif

 

Firstly, we need to enable highlights in the capabilities file.

Secondly, we need to make sure we use measure values.

Thirdly, we need to check for the presence of the highlight property and then use it to change the y position of the element (being evaluated).

The same applies here, before any selection is made, there is no highlight property, after a selection, its added to the measure values property:

Before selectionBefore selection

 

 



After selectionAfter selection

 

 

Conclusion

Hopefully, this article helped you get an understanding of the core mechanics that are used in Custom Visuals in a focused manner. This article is a repost from a Medium article, I am the original author.