Skip to content

microsoft/powerbi-visuals-utils-formattingmodel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Microsoft PowerBI Custom Visuals Formatting Model Utils

FormattingModel utils

Formatting model utils contains the classes, interfaces, and methods needed to build a formatting settings model to populate the property panes (format and analytics panes) of your Power BI custom visual.

Formatting settings service

The formatting settings service receives a formatting settings model, and turns it into a formatting model that populates the formatting pane. The formatting model service also supports string localizations.

Initializing formatting settings service:

import { FormattingSettingsService } from "powerbi-visuals-utils-formattingmodel";

export class MyVisual implements IVisual {
    // declaring formatting settings service 
    private formattingSettingsService: FormattingSettingsService;

    constructor(options: VisualConstructorOptions) {
        
        this.formattingSettingsService = new FormattingSettingsService();
        
        // ...
    }
}

Formatting settings service interface IFormattingSettingsService has two main methods:

    /**
     * Build visual formatting settings model from metadata dataView
     * 
     * @param dataViews metadata dataView object
     * @returns visual formatting settings model 
     */
    populateFormattingSettingsModel<T extends Model>(typeClass: new () => T, dataViews: powerbi.DataView): T;

    /**
     * Build formatting model by parsing formatting settings model object 
     * 
     * @returns powerbi visual formatting model
     */
    buildFormattingModel(formattingSettingsModel: Model): visuals.FormattingModel;

Formatting settings model

The settings model contains and wraps all formatting cards for the formatting pane and analytics pane.

export class Model {
    cards: Array<Cards>;
}

This example declares a new formatting settings model:

import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";

import FormattingSettingsCompositeCard = formattingSettings.CompositeCard;
import FormattingSettingsCards = formattingSettings.Cards;
import FormattingSettingsModel = formattingSettings.Model;

export class VisualSettingsModel extends FormattingSettingsModel {
    // Building my visual formatting settings card
    myVisualCard: FormattingSettingsCompositeCard = new myVisualCardSettings();

    // Add formatting settings card to cards list in model
    cards: FormattingSettingsCards[] = [this.myVisualCard];
}

Formatting settings card

A formatting settings card specifies a formatting card in the formatting or analytics pane. A formatting settings card can contain multiple formatting slices, containers, groups, and properties.

Adding slices to a formatting settings card puts all of these slices into one formatting card.

Cards, Slices and Groups can be hidden dynamically by setting the visible parameter to false (true by default)

The card can populate either the formatting pane or analytics pane by setting the analyticsPane parameter to true or false.

Example declaring formatting settings card, including one formatting settings group and slice:

  • Card name should match the object name in capabilities.json
  • Slice name should match the property name in capabilities.json
import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";

import FormattingSettingsCompositeCard = formattingSettings.CompositeCard;
import FormattingSettingsGroup = formattingSettings.Group;
import FormattingSettingsSlice = formattingSettings.Slice;

// Formatting settings group
class myVisualGroupSettings extends FormattingSettingsGroup {
    // Formatting settings slice
    myAnotherNumericSlice = new formattingSettings.NumUpDown({
        name: "myAnotherNumericSlice",
        displayName: "My Formatting Numeric Slice in group",
        value: 15,
        visible: true,
    });

    name: string = "myVisualCard";
    displayName: string = "My Formatting Card";
    analyticsPane: boolean = false;
    visible: boolean = true;
    slices: Array<FormattingSettingsSlice> = [this.myNumericSlice];
}

// Formatting settings card
class myVisualCardSettings extends FormattingSettingsCompositeCard {
    // Formatting settings slice
    myNumericSlice = new formattingSettings.NumUpDown({
        name: "myNumericSlice",
        displayName: "My Formatting Numeric Slice",
        value: 50,
        visible: true,
        options: {
            minValue: {
                type: powerbi.visuals.ValidatorType.Min,
                value: 0,
            },
            maxValue: {
                type: powerbi.visuals.ValidatorType.Max,
                value: 100,
            },
        }
    });

    name: string = "myVisualCard";
    displayName: string = "My Formatting Card";
    analyticsPane: boolean = false;
    visible: boolean = true;

    groupSetting = new myVisualGroupSettings(Object())
    groups: Array<FormattingSettingsGroup> = [this.groupSetting]
    slices: Array<FormattingSettingsSlice> = [this.myNumericSlice];
}

The capabilities.json property declaration should be:

"objects": {
    "myVisualCard": {
        "properties": {
            "myNumericSlice": {
                "type": {
                    "numeric": true 
                }
            },
            "myAnotherNumericSlice": {
                "type": {
                    "numeric": true 
                }
            },
        }
    }
}

Formatting settings group

Some formatting settings cards can have groups inside. Groups consists of slices and can be expanded/collapsed.

Example declaring formatting settings group with one slice:

import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";

import FormattingSettingsGroup = formattingSettings.Group;
import FormattingSettingsSlice = formattingSettings.Slice;

class myVisualGroupSettings extends FormattingSettingsGroup {
    myAnotherNumericSlice = new formattingSettings.NumUpDown({
        name: "myAnotherNumericSlice",
        displayName: "My Formatting Numeric Slice in group",
        value: 15,
        visible: true
    });

    name: string = "myVisualCard";
    displayName: string = "My Formatting Card";
    analyticsPane: boolean = false;
    visible: boolean = true;
    slices: Array<FormattingSettingsSlice> = [this.myNumericSlice];
}

Formatting settings slice

The formatting settings slice type consists of two types of slices - simple and composite.

Each slice contains formatting properties. There's a long list of available formatting properties types.

Example declaring formatting settings slice of type NumUpDown with limitations:

The slice name should match property name from capabilities.json.

    import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";

    myNumericSlice = new formattingSettings.NumUpDown({
        name: "myNumericSlice",
        displayName: "My Formatting Numeric Slice",
        value: 50,
        visible: true,
        options: {
            minValue: {
                type: powerbi.visuals.ValidatorType.Min,
                value: 0,
            },
            maxValue: {
                type: powerbi.visuals.ValidatorType.Max,
                value: 100,
            },
        }
    });

Build formatting pane model using FormattingModel Utils

  1. Open your settings.ts file.
  2. Build your own formatting settings model with all its components (cards, groups, slices, properties ...), and name it VisualFormattingSettings. Replace your settings code with the following:
import { formattingSettings } from "powerbi-visuals-utils-formattingmodel";

import FormattingSettingsCompositeCard = formattingSettings.CompositeCard;
import FormattingSettingsSlice = formattingSettings.Slice;
import FormattingSettingsModel = formattingSettings.Model;

export class VisualSettingsModel extends FormattingSettingsModel {
    // Building my visual formatting settings card
    myVisualCard: FormattingSettingsCard = new myVisualCardSettings();

    // Add formatting settings card to cards list in model
    cards: Array<FormattingSettingsCompositeCard> = [this.myVisualCard];
}

class myVisualCardSettings extends FormattingSettingsCompositeCard {
    myNumericSlice = new formattingSettings.NumUpDown({
        name: "myNumericSlice",
        displayName: "My Formatting Numeric Slice",
        value: 100,
    });

    name: string = "myVisualCard";
    displayName: string = "My Formatting Card";
    analyticsPane: boolean = false;
    slices: Array<FormattingSettingsSlice> = [this.myNumericSlice];
}
  1. In your capabilities file, add your formatting objects and properties
"objects": {
    "myVisualCard": {
        "properties": {
            "myNumericSlice": {
                "type": {
                    "numeric": true 
                }
            }
        }
    }
}
  1. In your visual class, import the following:
import { FormattingSettingsService } from "powerbi-visuals-utils-formattingmodel";
import { VisualFormattingSettingsModel } from "./settings";
  1. Declare formatting settings and formatting settings service
   private formattingSettings: VisualFormattingSettingsModel;
   private formattingSettingsService: FormattingSettingsService;
  1. Initialize the formatting settings service in constructor
constructor(options: VisualConstructorOptions) {
    this.formattingSettingsService = new FormattingSettingsService();

    // ...
}
  1. Build formatting settings in update API using formatting settings service populateFormattingSettingsModel
public update(options: VisualUpdateOptions) {
    this.formattingSettings = this.formattingSettingsService.populateFormattingSettingsModel(VisualFormattingSettingsModel, options.dataViews[0]);
    // ...
}
  1. Build formatting model and return it in getFormattingModel API
public getFormattingModel(): powerbi.visuals.FormattingModel {
    return this.formattingSettingsService.buildFormattingModel(this.formattingSettings);
}

Formatting property selector

The optional selector in the formatting properties descriptor determines where each property is bound in the dataView. There are four distinct options.

You can add selector to formatting property in its descriptor object. This example is taken from the SampleBarChart for color custom visual data points using property selectors:

new formattingSettings.ColorPicker({
    name: "fill",
    displayName: dataPoint.category,
    value: { value: dataPoint.color },
    selector: dataViewWildcard.createDataViewWildcardSelector(dataViewWildcard.DataViewWildcardMatchingOption.InstancesAndTotals),
    altConstantSelector: dataPoint.selectionId.getSelector(),
    instanceKind: powerbi.VisualEnumerationInstanceKinds.ConstantOrRule
}

Reset settings to default

Formatting model utils will enable you to reset settings to default by automatically adding all the formatting properties descriptors to the formatting card list of features to revet to default descriptors revertToDefaultDescriptors.

You can enable resetting formatting settings from:

  • The formatting card reset to default button

  • The formatting pane top bar ... -> reset all settings to default button

Localization

For more about the localization feature and to set up localization environment, see Add the local language to your Power BI visual.

Init formatting settings service with localization manager in case localization is required in your custom visual:

constructor(options: VisualConstructorOptions) {

    const localizationManager = options.host.createLocalizationManager();
    this.formattingSettingsService = new FormattingSettingsService(localizationManager);
    
    // ...
}

Add displayNameKey or descriptionKey instead of displayName and description in the appropriate formatting component whenever you want a string to be localized. Example for building a formatting slice with localized display name and description

 myFormattingSlice = new formattingSettings.NumUpDown({
        name: "myFormattingSlice",
        displayNameKey: "myFormattingSlice_Key",
        descriptionKey: "myFormattingSlice_DescriptionKey",
        value: 100
    });

displayNameKey and descriptionKey values should be added to resources.json files.