LoginSignup
0

More than 5 years have passed since last update.

Power BI カスタムビジュアル開発 : DataViewUtils で DataView の各種オブジェクトをパースする

Last updated at Posted at 2018-06-05

DataViewUtils

DataViewUtils は DataView オブジェクトのパースを容易にするユーティリティです。特に DataViewObjectsParser は多くのサンプルでも使われるモジュールで、Objects (書式) の扱いが格段にやり易くなるため、必須の知識となります。

インストール

このツールは pbiviz new でプロジェクトを作成した場合は、既定で入っています。入っていない場合のみ以下手順で追加。

1. npm コマンドでインストール。

npm install powerbi-visuals-utils-dataviewutils --save

2. tsconfig.json の files に型情報を追加。

tsconfig.json
{
  "compilerOptions": {
  ...
  },
  "files": [
    "node_modules/powerbi-visuals-utils-dataviewutils/lib/index.d.ts",
    ...
  ]
}

3. pbiviz.json の externalJS に追加。

pbiviz.json
{
  ...
  "externalJS": [
    "node_modules/powerbi-visuals-utils-dataviewutils/lib/index.js",
    ...
  ],
  ...
}

機能

DataViewObjectsParser

DataViewObjectsParser はビジュアルのプロパティ管理を容易にする機能を提供。多くのサンプルでも同様の手法が利用されているため、重要な機能。

powerbi.extensibility.utils.dataview.DataViewObjectsParser モジュールで以下の機能を提供

getDefault

この静的関数は DataViewObjectsParser インスタンスの DataViewObjectsParser を返す。

static getDefault(): DataViewObjectsParser;

parse

DataViewObjectsParser のフォーマットパネルのプロパティの値をパース。

static parse<T extends DataViewObjectsParser>(dataView: DataView): T;

enumerateObjectInstances

この静的関数は DataViewObjectsParser で使えるようにプロパティの一覧を返す。

static enumerateObjectInstances(dataViewObjectParser: DataViewObjectsParser, options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration;

DataViewObjectsParser の例

以下の様に capabilities の objects 定義があるとする。

capabilities.json
{
    "dataRoles": [
        {
            "displayName": "サンプルメジャー",
            "name": "myMeasure",
            "kind": "Measure"
        }
    ],        
    "objects": {
        "myProperty": {
            "displayName": "サンプルプロパティ",
            "properties": {
                "show": {
                    "displayName": "表示する",
                    "type": {
                        "bool": true
                    }
                },
                "textColor": {
                    "displayName": "色",
                    "type": {
                        "fill": {
                            "solid": {
                                "color": true
                            }
                        }
                    }
                }           
            }
        },
        "anotherProperty": {
            "displayName": "サンプルプロパティ2",
            "properties": {
                "show": {
                    "displayName": "表示する",
                    "type": {
                        "bool": true
                    }
                },
                "textAlignment": {
                    "displayName": "テキストの配置",
                    "type": {
                        "formatting": {
                            "alignment": true
                        }
                    }
                }           
            }
        }
    }
}

この場合 visual.ts では objects を以下の様に扱える。

module powerbi.extensibility.visual {
    "use strict";

    import DataViewObjectsParser = powerbi.extensibility.utils.dataview.DataViewObjectsParser;
    import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;

    // 自分のプロパティ用のクラス
    class MyProperty {
        // 各プロパティは json と同じ名前にする
        public textColor: string = "red"; // 既定の値
        public show: boolean = true; // 既定の値
    }

    class AnotherProperty {
        // 各プロパティは json と同じ名前にする
        public textAlignment: string = "center"; // 既定の値
        public show: boolean = true; // 既定の値
    }

    class PropertiesParser extends DataViewObjectsParser {
        // オブジェクトの指定
        public myProperty: MyProperty = new MyProperty();
        public anotherProperty: AnotherProperty = new AnotherProperty();
    }


    export class Visual implements IVisual {

        private area: d3.Selection<HTMLElement>
        private host: IVisualHost;
        private settings: VisualSettings;
        private propertiesParser: PropertiesParser;

        constructor(options: VisualConstructorOptions) {
            // カスタムビジュアルを配置しているホストの情報を取得
            this.host = options.host;
            // カスタムビジュアルのエリアを取得
            this.area = d3.select(options.element);
            this.area.append("h1").attr("class","color");
            this.area.append("h1").attr("class","alignment");
        }

        public update(options: VisualUpdateOptions) {
            debugger;

            // 各オブジェクトのプロパティ取得
            this.propertiesParser = PropertiesParser.parse<PropertiesParser>(options.dataViews[0]);
            let currentColor = this.propertiesParser.myProperty.textColor;
            let currentTextAlginment = this.propertiesParser.anotherProperty.textAlignment;

            this.area.select(".color").text(currentColor);
            this.area.select(".alignment").text(currentTextAlginment);
        }

        private static parseSettings(dataView: DataView): VisualSettings {
            return VisualSettings.parse(dataView) as VisualSettings;
        }

        public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
            return PropertiesParser.enumerateObjectInstances(this.propertiesParser, options);
        }

    }
}

DataRoleHelper

DataRoleHelper は DataView 内のデータロールに関する確認機能を提供

powerbi.extensibility.utils.dataview.DataRoleHelper モジュールで以下の機能を提供

getMeasureIndexOfRole

名前でメジャーデータロールを取得し、インデックスを返す。

function getMeasureIndexOfRole(grouped: DataViewValueColumnGroup[], roleName: string): number;

getMeasureIndexOfRole 例

以下の例は myMeasure メジャーデータロールのインデックスを取得。取得出来た場合はインデックス番号、できない場合は -1 が返る。ポイントは categorical.values に対して grouped 関数を呼ぶと DataViewValueColumnGroup[] が返る点。

import DataRoleHelper = powerbi.extensibility.utils.dataview.DataRoleHelper;

public update(options: VisualUpdateOptions) {
    try
        let index = DataRoleHelper.getMeasureIndexOfRole(options.dataViews[0].categorical.values.grouped(), "myMeasure");
    }
    catch (err){

    }
...

getCategoryIndexOfRole

名前でカテゴリデータロールを取得し、インデックスを返す。

function getCategoryIndexOfRole(categories: DataViewCategoryColumn[], roleName: string): number;

getCategoryIndexOfRole 例

以下の例は myCategory カテゴリデータロールのインデックスを取得。取得出来た場合はインデックス番号、できない場合は -1 が返る。

import DataRoleHelper = powerbi.extensibility.utils.dataview.DataRoleHelper;

public update(options: VisualUpdateOptions) {
    try
        let index = DataRoleHelper.getCategoryIndexOfRole(options.dataViews[0].categorical.categories, "myCategory");
    }
    catch (err){
    }
...

hasRole

metadata に指定したロールが存在するか確認する。

function hasRole(column: DataViewMetadataColumn, name: string): boolean;

hasRole 例

以下の例では myCategory が metadata に存在するか確認。

import DataRoleHelper = powerbi.extensibility.utils.dataview.DataRoleHelper;

public update(options: VisualUpdateOptions) {
    let myCategoryExists = options.dataViews[0].metadata.columns.some((column) => {
        return DataRoleHelper.hasRole(column, "myCategory");
    });
...

hasRoleInDataView

dataView に指定したロールが存在するか確認する。

function hasRoleInDataView(dataView: DataView, name: string): boolean;

hasRoleInDataView 例

以下の例では myCategory が dataView に存在するか確認。

import DataRoleHelper = powerbi.extensibility.utils.dataview.DataRoleHelper;

public update(options: VisualUpdateOptions) {
    let myCategoryExists = DataRoleHelper.hasRoleInDataView(options.dataViews[0], "myCategory");
...

hasRoleInValueColumn

DataView の結果の値に指定したロールが存在するか確認する。

function hasRoleInValueColumn(valueColumn: DataViewValueColumn, name: string): boolean;

hasRoleInValueColumn 例

以下の例では myCategory が結果の値に存在するか確認。

import DataRoleHelper = powerbi.extensibility.utils.dataview.DataRoleHelper;

public update(options: VisualUpdateOptions) {
    let myCategoryExists = options.dataViews[0].categorical.values.some((column) => { 
        return DataRoleHelper.hasRoleInValueColumn(column, "myCategory") });
...

DataViewObjects

DataViewObjects は Object の値を取得する機能を提供

powerbi.extensibility.utils.dataview.DataViewObjects モジュールで以下の機能を提供

getValue

Object の値を取得。Fill など値が型の場合は型を取得

function getValue<T>(objects: DataViewObjects, propertyId: DataViewObjectPropertyIdentifier, defaultValue?: T): T;

getValue の例

以下の例では、myProperty オブジェクトの textColor プロパティを取得。戻り値は Fill オブジェクト。結果がない場合は black を初期値として設定。

import DataViewObjects = powerbi.extensibility.utils.dataview.DataViewObjects;

public update(options: VisualUpdateOptions) {
    let myPropertyTextColor = DataViewObjects.getValue(options.dataViews[0].metadata.objects, {
        objectName: "myProperty",
        propertyName: "textColor"
    }, "black");
...

getObject

Objects から特定の Object を取得。

function getObject(objects: DataViewObjects, objectName: string, defaultValue?: IDataViewObject): IDataViewObject;

getObject の例

以下の例では myProperty オブジェクトを取得。

import DataViewObjects = powerbi.extensibility.utils.dataview.DataViewObjects;

public update(options: VisualUpdateOptions) {
    let myPropertyObj = DataViewObjects.getObject(options.dataViews[0].metadata.objects,"myProperty");
...

getFillColor

Object の solid カラープロパティを取得 (fill の場合のみ)。GetValue と異なり色の値が返る。

function getFillColor(objects: DataViewObjects, propertyId: DataViewObjectPropertyIdentifier, defaultColor?: string): string;

getFillColor の例

以下の例では、myProperty オブジェクトの textColor の色の値を取得。オブジェクトがない場合は black を初期値として設定。

import DataViewObjects = powerbi.extensibility.utils.dataview.DataViewObjects;

public update(options: VisualUpdateOptions) {
    this.myPropertyTextColor = DataViewObjects.getFillColor(options.dataViews[0].metadata.objects, {
        objectName: "myProperty",
        propertyName: "textColor"
    }, "black");
...

getCommonValue

色か他の値かに関わらず利用できる共通関数。

function getCommonValue(objects: DataViewObjects, propertyId: DataViewObjectPropertyIdentifier, defaultValue?: any): any;

getCommonValue 例

以下の例では、myProperty オブジェクトの textColor の色の値を取得。オブジェクトがない場合は black を初期値として設定。

import DataViewObjects = powerbi.extensibility.utils.dataview.DataViewObjects;

public update(options: VisualUpdateOptions) {
    this.myPropertyTextColor = DataViewObjects.getFillColor(options.dataViews[0].metadata.objects, {
        objectName: "myProperty",
        propertyName: "textColor"
    }, "black");
...

DataViewObject

DataViewObject は Object の値を取得する機能を提供

powerbi.extensibility.utils.dataview.DataViewObject モジュールで以下の機能を提供

getValue

Object のプロパティの値を名前で取得。

function getValue<T>(object: IDataViewObject, propertyName: string, defaultValue?: T): T;

getValue の例

以下の例では myProperty オブジェクトの textColor プロパティを取得。Fill 型の結果が返る。

import DataViewObject = powerbi.extensibility.utils.dataview.DataViewObject;
public update(options: VisualUpdateOptions) {
    this.myPropertyTextColor = DataViewObject.getValue(
        options.dataViews[0].metadata.objects.myProperty, "textColor");
...

getFillColorByPropertyName

Object の solid カラープロパティを取得 (fill の場合のみ)。GetValue と異なり色の値が返る。

function getFillColorByPropertyName(object: IDataViewObject, propertyName: string, defaultColor?: string): string;

getFillColorByPropertyName の例

以下の例では myProperty オブジェクトの textColor プロパティの色の値を取得。

import DataViewObject = powerbi.extensibility.utils.dataview.DataViewObject;
public update(options: VisualUpdateOptions) {
    this.myPropertyTextColor = DataViewObject.getFillColorByPropertyName(
        options.dataViews[0].metadata.objects.myProperty, "textColor");
...

converterHelper

converterHelperは DataView 内のカテゴリやシリーズ、列の確認などの機能を提供。

powerbi.extensibility.utils.dataview.converterHelper モジュールで以下の機能を提供

categoryIsAlsoSeriesRole

カテゴリに配置したフィールドがシリーズでもあるか確認。

function categoryIsAlsoSeriesRole(dataView: DataViewCategorical, seriesRoleName: string, categoryRoleName: string): boolean;

categoryIsAlsoSeriesRole の例

以下の例では、myCategory に配置されたフィールドが myGrouping にもいるか確認。

import converterHelper = powerbi.extensibility.utils.dataview.converterHelper;

public update(options: VisualUpdateOptions) {
    let categoryIsAlsoSeriesRole = converterHelper.categoryIsAlsoSeriesRole(options.dataViews[0].categorical, 
        "myGrouping","myCategory");
...

getSeriesName

metadata の列より、シリーズの名前を取得。

function getSeriesName(source: DataViewMetadataColumn): PrimitiveValue;

getSeriesName の例

以下の例では、初めの列からシリーズ名を取得。

import converterHelper = powerbi.extensibility.utils.dataview.converterHelper;

public update(options: VisualUpdateOptions) {
    let seriesName = converterHelper.getSeriesName(options.dataViews[0].metadata.columns[0]);
...

getMiscellaneousTypeDescriptor

metadata の列が MiscellaneousType の場合、MiscellaneousTypeDescriptor を取得。

function getMiscellaneousTypeDescriptor(source: DataViewMetadataColumn): MiscellaneousTypeDescriptor;

getMiscellaneousTypeDescriptorの例

以下の例では、初めの列から MiscellaneousTypeDescriptor を取得。

import converterHelper = powerbi.extensibility.utils.dataview.converterHelper;

public update(options: VisualUpdateOptions) {
    let seriesName = converterHelper.getMiscellaneousTypeDescriptor(options.dataViews[0].metadata.columns[0]);
...

isImageUrlColumn

列が image url を含むか確認。

function isImageUrlColumn(column: DataViewMetadataColumn): boolean;

isImageUrlColumn の例

以下の例では初めの列が image url を含むか確認。

import converterHelper = powerbi.extensibility.utils.dataview.converterHelper;

public update(options: VisualUpdateOptions) {
    let containsImageUrl = converterHelper.isImageUrlColumn(options.dataViews[0].metadata.columns[0]);
...

isWebUrlColumn

列が web url を含むか確認。

function isWebUrlColumn(column: DataViewMetadataColumn): boolean;

isWebUrlColumn の例

以下の例では初めの列が web url を含むか確認。

import converterHelper = powerbi.extensibility.utils.dataview.converterHelper;

public update(options: VisualUpdateOptions) {
    let containsWebUrl = converterHelper.isWebUrlColumn(options.dataViews[0].metadata.columns[0]);
...

hasImageUrlColumn

DataView に image url を含む列があるか確認。

function hasImageUrlColumn(dataView: DataView): boolean;

hasImageUrlColumn の例

以下の例では DataView に image url を含む列があるか確認。

import converterHelper = powerbi.extensibility.utils.dataview.converterHelper;

public update(options: VisualUpdateOptions) {
    let containsWebUrl = converterHelper.hasImageUrlColumn(options.dataViews[0]);
...

まとめ

値のパースは面倒な点が多いので、ユーティリティをうまく使いたいです。また多くのサンプルはユーティリティベースのため、読めるようになるためにも必要な知識です。是非自分のカスタムビジュアルでも使ってみてください。

目次に戻る

参照

Microsoft Power BI visuals DataViewUtils
How to install
Usage Guide

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0