Today I stumbled upon an older, but wonderful article about how you can use SVGs (Scalable Vector Graphics) within PowerApps, and how you can modify them dynamically for custom visualizations: Advanced PowerApps visualizations with dynamic SVG’s.

This made me think about other potential use cases, and I decided to check if I can build a reusable component that displays a World Map and allows to highlight countries with different colours. To make things a bit easier, I chose to proceed with a smaller set of data, and implemented my solution for Germany’s sixteen states:

Here’s how I did it:

To get started, I created a new Canvas PowerApp, and enabled “Components” under File-> App Settings (it is still an experimental feature, after all). Once done, I went back into my App, clicked on Components, and added a new component which I aptly named ‘Germany’:

Next, I added an image to my canvas, and this is where the SVG fun begins. The image itself has an Image property, which can contain the corresponding data-uri representation of an SVG image. So all I need to get started is a SVG map of Germany with its states, and have it converted into the correct format.

I found a usable and free map on https://mapsvg.com/maps/. Check out that site for more maps (countries, US states, world map, ..) and other tools (WordPress plugin, jQuery plugin, ..). I downloaded the German map, opened the .svg file in a text editor, and copied the full code except for the first two lines

Next I pasted the copied code into the “Insert your SVG” section over at https://yoksel.github.io/url-encoder/, and copied the result from “Take encoded”:

I added the following snippet into the Image property text field in my App:
“data:image/svg+xml,
pasted my copied result from my previous step, and closed the whole string with a closing quotation mark:

If things go well, you’ll see a black map of Germany. So, next step is to update our image code to include a fill colour AND make it a dynamic colour.

First, I added a new custom property to my component called “Selection” which I defined as a Table.

I then defined the (default) value of my new “Selection” Property of my component as follows:

Table(
{State:”DE-BW”,FillColor:”#FF4400″, Name:”Baden-Wurttemberg”},
{State:”DE-BY”,FillColor:”#4499FF”, Name:”Bavaria”},
{State:”DE-BB”,FillColor:”#FFD0D0″, Name:”Brandenburg”},
{State:”DE-BE”,FillColor:”#EE4444″, Name:”Berlin”},
{State:”DE-HB”,FillColor:”#00FFFF”, Name:”Bremen”},
{State:”DE-HH”,FillColor:”#FF0000″, Name:”Hamburg”},
{State:”DE-HE”,FillColor:”#33FFFF”, Name:”Hesse”},
{State:”DE-MV”,FillColor:”#004444″, Name:”Mecklenburg-Vorpommern”},
{State:”DE-NI”,FillColor:”#333333″, Name:”Lower Saxony”},
{State:”DE-NW”,FillColor:”#FFFF00″, Name:”North Rhine-Westphalia”},
{State:”DE-RP”,FillColor:”#FF00FF”, Name:”Rhineland-Palatinate”},
{State:”DE-SL”,FillColor:”#AB2222″, Name:”Saarland”},
{State:”DE-SN”,FillColor:”#887766″, Name:”Saxony”},
{State:”DE-ST”,FillColor:”#00EA44″, Name:”Saxony-Anhalt”},
{State:”DE-SH”,FillColor:”#AABBCC”, Name:”Schleswig-Holstein”},
{State:”DE-TH”,FillColor:”#EEBB33″, Name:”Thuringia”}
)

As you can see, it’s a list of Germany’s sixteen states with their names, an ID (State), and a unique colour (FillColor). So basically, I now have a ready list of states with unique colours, which can be updated as required.

Second step is to make the image use the state colour by doing the following:
Each state is a path Element in the original SVG code. This element can use a property called fill to define the fill colour of its area. For example:

<path d=”…..”
title = “Baden-Wurttemberg”
id=”DE-BW”
fill=”black”/>

We can now modify our code to include an expression that retrieves a specific state’s colour from our ‘Selection’ custom property. Here’s how it works:

…title=’Baden-Wurttemberg’ id=’DE-BW’ fill='”&Coalesce(EncodeUrl(LookUp(Germany.Selection,State=”DE-BW”,FillColor)),”Gray”)&”‘
/%3E…

First, we do a Lookup into Germany.Selection and filter by State=”DE-BW”, and select the FillColor as return value. We wrap this inside an EncodeUrl expression, so that we can safely use the HEX colours we defined previously. And lastly, we put it into a Coalesce expression with “Gray” as its last value, so that if no entry is found gray is used as the default colour. We do the same thing for the other states as well, only replacing the filter accordingly. If it worked, our image looks as follows:

Let’s do a quick check and remove some entries from our Selection table:

By now our component is done, and we can use it in an app. Here’s what I did:

  • I added a new Gallery item and defined the Items as the Table( {State: ..}) block from above. So basically, hard coding my items in my Gallery. I also changed the layout of my Gallery to a simple Title layout (selected Field is Name), updated the Wrap count to 2, and defined the Gallery’s TemplateFill property as If(ThisItem.IsSelected,RGBA(100,200,255,1))
  • I added my Germany Map component to my screen, and updated the Selection property to Gallery.Selected. So whichever item in my gallery gets selected is shown as highlighted.

Once again, here’s how the final result looks like:

If you want to check out the component in more detail, I made it available on Github:

https://github.com/modery/PowerApps/blob/master/Components/Component-GermanyMap.msapp

4 thoughts on “Dynamic Country Maps in PowerApps”

  1. I had great results using a World map.
    Now I want to incorporate clickable countries, opening a hyperlink of choice. I cannot get that to work; would you know a way?

      1. Thanks very much for trying and replying!
        As this is quite new technology I’d imagine Microsoft would yet have to build this extra SVG functionality into Power Apps… ?

      2. It might be simply the way the SVGs are displayed within Power Apps. So it’s something that Microsoft might not be actively working on, and not sure if we will see it work at some point.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.