Localizing Your Power BI Custom Visual

Localizing Your Power BI Custom Visual

Learn how to add localization to your Power BI Custom Visual. This is video #18 of the Power BI Custom Visual Development Fundamentals series, please check the playlist below for the set.

Resources

Transcript

Hello again and welcome back to this series on developing Power BI Custom Visuals.

Today, you will learn how to setup localization in your custom visual.

Localization helps you display static labels, such as the ones on tooltips, in the language of the user.

And that’s precisely what you will do in this in video.

So, let’s get to it, right now.

We can start by adding a member variable to the visual.

private locale: string;

This will be a variable called locale of type string and we’ll use that to hold the current locale of the user.

this.locale = this.host.locale;

This locale is available from the host object, so we can grab it right in the constructor.

At the time of this recording, Power BI supports 42 different locales.

You can see a list of these by following the link in the description of this video.

Power BI Supported Languages

By the way, a locale does not refer to a language alone, but a combination of language and location.

For example, Portuguese as spoken in Portugal and Portuguese as spoken in Brazil are two different locales in that list, as even though they are the same language, they have significant differences in vocabulary and pronunciation between them, not to mention the currency of the countries being different.

The import thing is, when you are defining labels for a certain language, you will need to know not the language name, but the name of the locale instead.

Anyway, with this out of the way, let’s create a file to hold our translated resources.

module powerbi.extensibility.visual {
}

To keep things simple, I’m going to keep the code in the same namespace as the visual.

This way we don’t have to import anything anywhere.

"src/resources.ts",

Now I need to add this file to the typescript configuration file so the compiler will pick it up.

I also need to restart pbiviz as the tool is not smart enough to recognize new files, at least not at the time of this recording.

export class Resources {

    constructor(items: { [key: string]: LocalizedResource }) {
        this.items = items;
    }

    private items: { [key: string]: LocalizedResource }

    public getLocalString(key: string, locale: string): string {
        if (locale && key) {
            let item = this.items[key];
            if (item) {
                let translation = item.localization[locale];
                if (translation) {
                    return translation;
                }
                else {
                    return item.defaultValue;
                }
            }
        }
    }
}

export interface LocalizedResource {

    defaultValue: string;
    localization: Localization;

}

export interface Localization {
    "ar-SA"?: string;
    "bg-BG"?: string;
    "ca-ES"?: string;
    "cs-CZ"?: string;
    "da-DK"?: string;
    "de-DE"?: string;
    "el-GR"?: string;
    "en-US"?: string;
    "es-ES"?: string;
    "et-EE"?: string;
    "eU-ES"?: string;
    "fi-FI"?: string;
    "fr-FR"?: string;
    "gl-ES"?: string;
    "he-IL"?: string;
    "hi-IN"?: string;
    "hr-HR"?: string;
    "hu-HU"?: string;
    "id-ID"?: string;
    "it-IT"?: string;
    "ja-JP"?: string;
    "kk-KZ"?: string;
    "ko-KR"?: string;
    "it-LT"?: string;
    "lv-LV"?: string;
    "ms-MY"?: string;
    "nb-NO"?: string;
    "nl-NL"?: string;
    "pl-PL"?: string;
    "pt-BR"?: string;
    "pt-PT"?: string;
    "ro-RO"?: string;
    "ru-RU"?: string;
    "sk-SK"?: string;
    "sl-SI"?: string;
    "sr-Cyrl-RS"?: string;
    "sr-Latn-RS"?: string;
    "sv-SE"?: string;
    "th-TH"?: string;
    "tr-TR"?: string;
    "uk-UA"?: string;
    "vi-VN"?: string;
    "zh-CN"?: string;
    "zh-TW"?: string;
}

Okay, so now I’m going to paste a whole bunch of code here.

This can look a bit weird but basically what this does is, it creates a simple structure that can reliably store multiple translations of multiple items, while still allowing us to locate them in a very easy way.

Instead of typing this whole thing, I recommend you just copy paste this file from the GitHub repository.

You can find a link for the repository in the description of this video.

So with this in place, I can now go define a translation in the visual.

private resources = new Resources({
    "DeviationAbsolute": {
        defaultValue: "Deviation (abs)",
        localization: {
            "pt-PT": "Desvio (abs)"
        }
    },
    "DeviationPercent": {
        defaultValue: "Deviation (%)",
        localization: {
            "pt-PT": "Desvio (%)"
        }
    }
});

In this case, I’m going to define a translation for the deviation tooltip label that we created in the previous video.

This code here takes advantage of the structure we just created to allow us to define translations in this very neat way.

So now that we have this all setup, all that’s left is to apply it to the view model.

displayName: this.resources.getLocalString("DeviationAbsolute", this.locale),
displayName: this.resources.getLocalString("DeviationPercent", this.locale),

Let’s replace these magic strings with proper calls to the resource object.

Now, instead of having a hardcoded string, this code is requesting localized strings from the resource object.

The resource object will still return the default value for each one, if it can’t find a given localization, so we’re still safe.

So let’s see what this did.

Well, at least didn’t break it.

It is still showing English tooltips by default.

But what if I change the language in Power BI to portuguese, then what?

Let’s try it.

Well, that’s certainly in Portuguese.

Let’s see the report now.

And there you have it.

The tooltip now correctly says “desvio” in portuguese, as opposed to deviation in English.

That’s a fully working translation right there.

And that’s it for today.

If you have any questions, let me know and I’ll get back to you.

In next video in this series, you will learn how to package your visual for distribution and how to use it in Power BI Desktop.

Until then, take care and see you next time.

Jorge Candeias's Picture

About Jorge Candeias

Jorge helps organizations build high-performing solutions on the Microsoft tech stack.

London, United Kingdom https://jorgecandeias.github.io