Power BI カスタムビジュアル開発 その５: ツールティップと多言語サポート

※ 2019/07/15 ツールが 3.0 になりいくつか内容が変わったため記事を編集します。

[前回](https://qiita.com/kenakamu/items/6465e757c0d2e52183e0)まではグラフ本体の作成を行いましたが、今回はマウスをグラフに合わせた際に表示されるツールティップについて見ていきます。

# ツールティップ
Power BI はツールティップを表示するようのフレームワークを提供しているため、データ構造を作るだけで表示が可能です。

1\. データポイントに tooltips フィールドを追加。配列型であるため複数のティップを含めることが可能。import と tooltips プロパティの追加。

```typescript
import VisualTooltipDataItem = powerbi.extensibility.VisualTooltipDataItem;

interface BarChartDataPoint {
    value: number;
    category: string;
    selectionId: ISelectionId;
    highlighted: boolean;
    color: string;
    tooltips: VisualTooltipDataItem[];
};
```

2\. visualTransform 関数で tooltips を設定。まずはツールティップに使うため、現在のカテゴリおよび値フィールドのフィールド名を取得。値の確認と取得を以下のように変更。

```typescript
// 期待した値があるか確認。なければ空データを返す
if (!dataViews
    || !dataViews[0]
    || !dataViews[0].categorical
    || !dataViews[0].categorical.categories
    || !dataViews[0].categorical.categories[0].source
    || !dataViews[0].categorical.values
    || !dataViews[0].metadata)
    return viewModel;

// 値があった場合はそれぞれ変数に一旦抜き出し
let categorical = dataViews[0].categorical;
let category = categorical.categories[0];
let dataValue = categorical.values[0];
let highlights = dataValue.highlights;
// ツールティップ用にカテゴリと値の表示名を取得
let metadata = dataViews[0].metadata;
let categoryColumnName = metadata.columns.filter(c => c.roles["category"])[0].displayName;
let valueColumnName = metadata.columns.filter(c => c.roles["measure"])[0].displayName;
```

3\. ループ処理で他のフィールド同様に値を設定。

```typescript
// カテゴリと値のセットを dataPoint に入れていく
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
    barChartDataPoints.push({
        category: <string>category.values[i],
        value: <number>dataValue.values[i],
        selectionId: host.createSelectionIdBuilder()
            .withCategory(category, i)
            .createSelectionId(),
        highlighted: highlights ? highlights[i] ? true : false : false,
        color: category.objects && category.objects[i] && dataViewObjects.getFillColor(category.objects[i], {
            objectName: "dataColor",
            propertyName: "fill"
        }, null) || host.colorPalette.getColor(<string>category.values[i]).value,
        tooltips: [
            {
                displayName: categoryColumnName,
                value: <string>category.values[i]
            },
            {
                displayName: valueColumnName,
                value: (<number>dataValue.values[i]).toString()
            }
        ]
    });
}
```

4\. this.bars.enter() のチェーンとしてマウスオーバーイベントを追加。イベントの下に以下コードを挿入。

```typescript
.on("mouseover", (d) => {
    this.host.tooltipService.show({
        dataItems: d.tooltips,
        identities: [d.selectionId],
        coordinates:[d3.event.pageX,d3.event.pageY],
        isTouchEvent: false
    });
})
```

5\. 保存して、ビジュアルを更新。ツールティップが出ることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/7d7ba182-f96b-76f7-b440-5eea6dbe04b0.png)

6\. 現在は同じ棒グラフ内でマウスを動かしてもツールティップは初めに出た場所に固定されているため、マウスムーブイベントを追加。

```typescript
.on("mousemove", (d)=>{
    this.host.tooltipService.move({
        dataItems: d.tooltips,
        identities: [d.selectionId],
        coordinates:[d3.event.pageX,d3.event.pageY],
        isTouchEvent: false
    });
```

7\. 保存して、ビジュアルを更新。ツールティップがマウスを一緒に動くことを確認。

# 多言語サポート
Power BI は多言語をサポートしていおり、現在選択されているロケールを ```host.locale``` で取得することが出来ます。

この値を利用して文字列を返す関数を作ると、ツールティップでの多言語サポートが可能となります。

1\. visualTransform 関数の下に、新しい関数を追加。

```typescript
function getLabel(locale: string, labelId: string): string {
    if (locale === "ja-JP") {
        switch (labelId) {
            case "categoryName":
                return "カテゴリ";
            case "measureName":
                return "値";
        }
    }
    else {
        switch (labelId) {
            case "categoryName":
                return "Category";
            case "measureName":
                return "value";
        }
    }
}
```

2\. visualTransform 関数のツールティップ設定コードを以下のように変更。

```typescript
// カテゴリと値のセットを dataPoint に入れていく
for (let i = 0, len = Math.max(category.values.length, dataValue.values.length); i < len; i++) {
    barChartDataPoints.push({
        category: <string>category.values[i],
        value: <number>dataValue.values[i],
        selectionId: host.createSelectionIdBuilder()
            .withCategory(category, i)
            .createSelectionId(),
        highlighted: highlights ? highlights[i] ? true : false : false,
        color: category.objects && category.objects[i] && dataViewObjects.getFillColor(category.objects[i], {
            objectName: "dataColor",
            propertyName: "fill"
        }, null) || host.colorPalette.getColor(<string>category.values[i]).value,
        tooltips: [
            {
                displayName: Visual.getLabel(host.locale, "categoryName"),
                value: <string>category.values[i]
            },
            {
                displayName: Visual.getLabel(host.locale, "measureName"),
                value: (<number>dataValue.values[i]).toString()
            }
        ]
    });
}
```

3\. 保存して、ビジュアルを更新。日本語を選択している Power BI にてツールティップが日本語になることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/1125ad55-df86-d603-c21a-a3b826b13dfe.png)

次回は作成したカスタムビジュアルのデバッグとパッケージ化を見ていきます。

[次の記事へ](https://qiita.com/kenakamu/items/3284f480adc71ec80782)
[目次へ戻る](https://qiita.com/kenakamu/items/f57ab7f73d6ea10bc9d9)

# 参照

[TooltipUtils でツールチップを活用する](https://qiita.com/kenakamu/items/a5e8aa9abb2fb110824c)