SVG in Power BI – Part 3 – Fill up with Colour

Last modified date

Series

This is the second post in a series of Using SVG within Power BI. The series is to support my session at Power BI Days in Mechelen, Belgium in April 2019. The complete series is listed below :

  1. Introduction to SVG
  2. KPI Shapes in Power BI
  3. Filling up with colour using SVG in Power BI
  4. Using Text in SVG
  5. Using SVG Rotate to create a dial in Power BI
  6. SVG Icons in Conditional Formatting
  7. Using a Theme to add SVG Icons
  8. Feb 2023 Update – 5 SVG Stars

In this post we will introduce using icons and filling the icon with colour to show a percentage value.

YouTube Video

If you would prefer a video of this topic:

Getting Icon Code

You can download icons from lots of web sites. Search for SVG icons or ask your marketing teams for company graphics as SVG. If you are using Office 2016 or above the icons in PowerPoint can be saved as SVG files. Icons can be found on the Insert ribbon and once inserted on a slide, right click and save as a picture.

save icon as picture

Once you have the icon take a look at the SVG code. There will be an open <SVG> tag with lots of attributes then one or more <PATH …. /> elements and then a closing tag </SVG>. You need to do a search replace the double quotes into single quotes, e.g. <path d=”…. has to become <path d=’…..
What we want is the <PATH …. /> and its long so I save it into a measure.

svg of icon

Draw 2 Elephants

We are going to draw 2 elephants, one grey and one coloured one on top. The coloured one we will clip to size to show it being filled up.

Next task is to create a measure in our report. Inside the measure we create 2 variables, one to store the svg start and one for the svg end. As a quick test we return the concatenation of the variables and the previous created measure to draw our icon.

Elephant Measure = 
// svg essentials
    var svg_start = "data:image/svg+xml;utf8,<svg 
        xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>"
    var svg_end = "</svg>"

return
    svg_start & [EleSVG] & svg_end

If you use the custom visual Image from Cloud Scope you can add the measure and the icon will be shown in Power BI.

one elephant

In order to draw a grey and red elephant we will nest the elephant in a <g> group tag and give the <g> element properties that the nested elements will inherit.

red elephant

I add 2 more variables one for the grey elephant and one for the red one. and tweak the return to use the new elephant variables. It will draw both elephants but they are exactly over each other so you only see the red one.

Elephant Measure = 
    // svg essentials
    var svg_start = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>"
    var svg_end = "</svg>"

    // Coloured Elephants
    var grey_ele = "<g style='fill:grey;'>" & [EleSVG] & "</g>"
    var red_ele = "<g style='fill:red;'>" & [EleSVG] & "</g>"

return
    svg_start & grey_ele & red_ele & svg_end

Clip the Red Elephant

We now want to only show a percentage of the red elephant based off a percentage measure, e.g. work complete. For this we need to create a clip-path. A clip-path defines which part of the shape will be visible. So in this case it will be a rectangle starting at 0,0 and will be height = 100 and width = percentage measure * 100.

So we create a variable to calculate the width and then a variable to store the defs tag that contains the clip-path. The red_ele variable is then tweaked to include a reference to the clip-path and the return is changed to include the defs variable.

Elephant Measure = 
    // svg essentials
    var svg_start = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>"
    var svg_end = "</svg>"

    // defs
    var clip_width = [Work Complete] * 100 
    var defs = "<defs><clipPath id='eleClip'>
                    <rect x='0' y='0' width='" & clip_width & "' height='100' />
                </clipPath></defs>"

    // Coloured Elephants
    var grey_ele = "<g style='fill:grey;'>" & [EleSVG] & "</g>"
    var red_ele = "<g style='fill:red; clip-path:url(#eleClip)'>" & [EleSVG] & "</g>"

return
    svg_start & defs & grey_ele & red_ele & svg_end

Now we have 2 measures, one that calculates a percentage and one that shows that percentage in colour.

showing percentage

Filling from the bottom up

The above example fills from the left. It is the easiest to calculate but if someone was asked to draw this idea they would probably fill in the colour from the bottom up.

Our icon is in a square which goes from 0,0 and is 100 wide and 100 tall. If we wanted to show 25% full the clip path would need to be 0,75 and 100 wide and 25 tall. So 2 values change the height is 25 = 100 * 25% and the starting y is 75 = 100 – height.

So to fill from the bottom I need to change the defs

Elephant Measure = 
    // svg essentials
    var svg_start = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>"
    var svg_end = "</svg>"

    // defs
    var clip_height = [Work Complete] * 100 
    var clip_y = 100 - clip_height
    var defs = "<defs><clipPath id='eleClip'>
                    <rect x='0' y='" & clip_y & "' width='100' height='" & clip_height & "' />
                </clipPath></defs>"

    // Coloured Elephants
    var grey_ele = "<g style='fill:grey;'>" & [EleSVG] & "</g>"
    var red_ele = "<g style='fill:red; clip-path:url(#eleClip)'>" & [EleSVG] & "</g>"

return
    svg_start & defs & grey_ele & red_ele & svg_end
filling from the bottom up

Conclusion

This gives us a quick visual measure to show a percentage.

Over 20 year experience at being passionate about training, solving problems and loving a new challenge especially in the Microsoft's Power Platform suite.