Customize PowerBI Custom Themes in PowerBI Desktop or with JSON

In PowerBI desktop the “switch theme” drop-down menu suggests that the application of themes will fancy-up your report with a new color scheme. This is true – but themes in PowerBI can do so much more! PowerBI report themes can control overall text settings as well as specifics for individual visualization types.

<p>
  Better still is a preview feature in <a href="https://powerbi.microsoft.com/en-us/blog/power-bi-desktop-december-2019-feature-summary/" target="_blank" rel="noreferrer noopener" aria-label="PowerBI Desktop December 2019 (opens in a new tab)">PowerBI Desktop December 2019</a> for customizing color and text settings within the application, then exporting the theme file. This post explores some of the PowerBI theme customizations that can be accomplished through the new theme customization UI and in the JSON file directly.
</p>

PowerBI Desktop – December 2019

After enabling “Customize current theme” under preview features in File>options and reopening the application, you are ready to roll. You can start with one of the build-in themes or import a current theme for customization.

For this example, I’ve imported a basic theme I’ve been using to preset our brand colors. It’s saved me a lot of time pulling these awful hex values.

<p>
  The option to import a theme JSON file is towards the bottom of the &#8220;Switch Theme&#8221; menu. If you&#8217;ve enabled &#8220;Customize current theme,&#8221; you will see it as an option directly above.
</p>
{ 
    "name": "IECIS", 
    "dataColors": ["#1A687E", "#01002C", "#99A23A", "#E47237", "#1B0037", "#F5C040","#67597A"],
    "background":"#FFFFFF",
    "foreground": "#01002C",
    "tableAccent": "#1A687E"
}
PowerBI report, tree map and table
Before Theme
PowerBI report with color theme applied, tree map and table
Colors Only

Importing the colors-only theme onto the world’s most useless PowerBI report shows the simple transformation of visualization colors. The real magic happens when we begin to customize the theme further in the PowerBI interface. Regardless if we had started from scratch, from a prebuilt theme available in PowerBI or from a theme in the online PowerBI theme gallery – we can use the handy customize theme UI in PowerBI Desktop.

We’re going to dive into the different theme customization options available in PowerBI, both in the desktop UI as well as the JSON file. When you’re done customizing your color theme – don’t leave it trapped in that report! Use the “Export current theme” option to obtain the report theme JSON file for later use in other reports and further customization.

Text and Visualization Settings in JSON and PowerBI Desktop

Data Colors

By customizing the sentiment and divergent color settings, you are able to include in the theme how KPIs and gradient/scale colors are handled.

<p>
  In the JSON theme file, these settings correspond to top-level attributes:
</p>

<pre class="wp-block-syntaxhighlighter-code">"bad": "#A31423",

“neutral”: “#F5C040”, “good”: “#0E7428”, “minimum”: “#34D0FD”, “center”: “#F5C040”, “maximum”: “#1A687E”

customize colors - sentiment and divergent

Text Classes

The next tab, “Text”, allows for customization of some of the text classes in the theme file. In the image below, the label text class font size has been increased to 12pt.

There are 12 different text classes that can be customized directly in the JSON file. Four of those twelve are set within the “Text” settings in PowerBI desktop – these are the primary text classes.

"textClasses": {
    "label": {
        "fontSize": 12
    },
    "callout": {
        "color": "#01002C"
    },
    "title": {
        "fontSize": 16
    },
    "header": {
        "fontSize": 14
    }
}

General = label
Title = title
Cards and KPIs = callout
Tab headers = header

While you don’t have to set the secondary classes in your theme file since they inherit from the primary classes, if you don’t like the inheritance rules (for example,if you don’t want your totals to be a bolded version of the values in a table), you can explicitly format the secondary classes in the theme file, just like you can format the primary classes.

https://docs.microsoft.com/en-us/power-bi/desktop-report-themes#report-theme-json-file-format

Of the secondary text classes, lightLabel and smallLightLabel are probably the most notable to me. “lightLabel” controls a number of settings, including legend text. “smallLightLabel” controls data labels and value axis labels. Both of those items pull their primary settings from “label.”

Visualization Settings

Thematically controlling visuals is a cascading hierarchy contained within the visualStyles section of the JSON theme file. In PowerBI desktop, the wildcard (*), or settings for all visuals, can be set. This places an asterisk for the visualName and the styleName.

visualStyles: {
    visualName: {
        styleName: {
            cardName: [{
                propertyName: propertyValue
            }]
        }
    }
}

Visualization setting structures, above. JSON generated by PowerBI desktop, below.

"visualStyles": {
    "*": {
        "*": {
           // settings for all visuals 
           "border": [
                {
                    "show": true,
                    "radius": 2
                }
            ]
        }
    }
}

The asterisk on line 2 above can be replaced by a visualName, such as areaChart or treemap, to apply settings only to a specific type of visual. Here’s the full list of visuals and cards: https://docs.microsoft.com/en-us/power-bi/desktop-report-themes#json-file-element-definitions

Page Settings

Although in the JSON file the page settings are within visual styles, they are on their own tab within the PowerBI desktop theme customization interface.

<p>
  In this example, the page background setting has been set to #1C2347 with 55% transparency for all pages.
</p>
page json settings nested within the visualStyles section

Filter Pane

We might have saved the best for last – because as someone that embeds most of my PowerBI reports in the browser, the filter pane needs a little sprucing up. In the example below, the font size is enlarged and active filters are highlighted in an eye-burning green.

theme settings for filter page, background color set to green

Much like the page settings, filter settings are captured within visual styles. filterCard covers settings for the specific filters while outspacePane is settings for the whole “Filters” area.

"visualStyles": {
    "*": {
        "*": {
            "filterCard": [
                {
                    "$id": "Applied",
                    "backgroundColor": {
                        "solid": {
                            "color": "#B0FAA4"
                        }
                    },
                    "textSize": 11,
                    "transparency": 0
                }
            ],
            "outspacePane": [
                {
                    "titleSize": 14,
                    "headerSize": 12
                }
            ]
        }
    }
}

The “$id” attribute in line 6 is an example of a selective application of styles. At present this is only available in the filterCard for “Applied” and “Available”, but I hope to see more of the programmatic setting of styles in the future.

Our Results

World’s Ugliest Theme on the World’s Most Useless Report

I may have just built the world’s ugliest theme on the world’s most useless report – we now have an example of nearly all the theme settings that can be modified via the PowerBI desktop UI. If you’re comfortable with editing JSON, you can customize a theme file quite significantly. Themes are not persistent in the PowerBI desktop application, so if you create a monster it’s contained within your report and can be overridden easily.

More Resources

https://powerbi.microsoft.com/en-us/blog/power-bi-desktop-december-2019-feature-summary/
https://community.powerbi.com/t5/Themes-Gallery/bd-p/ThemesGallery

Our Monster

{
    "name": "Our Monster",
    "dataColors": [
        "#1A687E",
        "#01002C",
        "#99A23A",
        "#E47237",
        "#1B0037",
        "#F5C040",
        "#67597A",
        "#A66999",
        "#3599B8",
        "#DFBFBF",
        "#4AC5BB",
        "#5F6B6D",
        "#FB8281",
        "#F4D25A",
        "#7F898A",
        "#A4DDEE",
        "#FDAB89",
        "#B687AC",
        "#28738A",
        "#A78F8F",
        "#168980",
        "#293537",
        "#BB4A4A",
        "#B59525",
        "#475052",
        "#6A9FB0",
        "#BD7150",
        "#7B4F71",
        "#1B4D5C",
        "#706060",
        "#0F5C55",
        "#1C2325"
    ],
    "background": "#FFFFFF",
    "foreground": "#01002C",
    "tableAccent": "#1A687E",
    "bad": "#A31423",
    "neutral": "#F5C040",
    "good": "#0E7428",
    "minimum": "#34D0FD",
    "center": "#F5C040",
    "maximum": "#1A687E",
    "textClasses": {
        "label": {
            "fontSize": 12
        },
        "callout": {
            "color": "#01002C"
        },
        "title": {
            "fontSize": 16
        },
        "header": {
            "fontSize": 14
        }
    },
    "visualStyles": {
        "*": {
            "*": {
                "background": [
                    {
                        "color": {
                            "solid": {
                                "color": "#E6E6E6"
                            }
                        }
                    }
                ],
                "visualTooltip": [
                    {
                        "titleFontColor": {
                            "solid": {
                                "color": "#FFFFFF"
                            }
                        },
                        "valueFontColor": {
                            "solid": {
                                "color": "#FFFFFF"
                            }
                        }
                    }
                ],
                "border": [
                    {
                        "show": true,
                        "radius": 3
                    }
                ],
                "filterCard": [
                    {
                        "$id": "Applied",
                        "backgroundColor": {
                            "solid": {
                                "color": "#B0FAA4"
                            }
                        },
                        "textSize": 11,
                        "transparency": 0
                    }
                ],
                "outspacePane": [
                    {
                        "titleSize": 14,
                        "headerSize": 12
                    }
                ]
            }
        },
        "page": {
            "*": {
                "background": [
                    {
                        "color": {
                            "solid": {
                                "color": "#1C2347"
                            }
                        },
                        "transparency": 55
                    }
                ]
            }
        }
    }
}