【Power BI】Denebを使ったカスタムビジュアルの作成方法(実装編)

■はじめに

前回の「導入編」では、Power BI でカスタムビジュアルを作成できる Deneb の概要と導入方法を紹介しました。本記事では実装編として、実際に Deneb を使用して簡単なビジュアルを作成する手順を解説します。

■3×3ヒートマップで作成してみよう

図1:Denebで作成したカスタムビジュアルサンプル

本記事では、図1のような「最終購入日 × 購入頻度」で顧客を分類した 3×3のヒートマップ を題材に、Deneb の基本的な使い方を紹介します。

■サンプルデータ

※列名は必ずサンプルデータと同じ名前にしてください。

図2:RFM分析に使用するサンプルデータ

今回使用するデータは、顧客を以下の観点で分類し、組み合わせごとの顧客数を集計したものです。

  • 最終購入日(高・中・低)
  • 購入頻度(高・中・低)
  • 顧客数

■実装手順

※事前に「データの読み込み」と「Deneb の導入」を完了させてください。
①Denebビジュアルを配置する

図3:Denebビジュアル配置後のPower BI画面

レポート画面で Deneb ビジュアルを選択し、キャンバス上に配置します。
②データ項目を設定する

図4:Valuesへデータ配置後のPower BI画面

「Values」フィールドに以下の項目を追加します。

  • 最終購入日
  • 購入頻度
  • 顧客数

③Denebの編集画面を開く

図5:Denebビジュアルのメニュー

Deneb ビジュアル右上の「・・・」をクリックし、「編集」を選択します。

図6:初期設定画面

テンプレート選択画面で「Vega-Lite」→「Empty」を選択し、「Create」をクリックします。
④編集画面の構成を理解する

図7:Deneb編集画面

主に以下の4つのエリアで構成されています。

  1. コード記述エリア
    Vega-Lite(JSON形式)でグラフの定義を記述します。
  1. 実行ボタン
    記述したコードをプレビューに反映します。
  1. プレビュー表示エリア
    作成中のビジュアルを確認できます。
  1. データ表示エリア
    Values に設定したデータを確認できます。

⑤サンプルコードを入力する
※以下のコードをそのまま貼り付けることで、同様のビジュアルを再現できます。

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": 600,
  "height": 600,
  "padding": 20,
  "layer": [
    {
      "data": { "name": "dataset" },
      "mark": {
        "type": "rect",
        "stroke": "white",
        "strokeWidth": 3
      },
      "encoding": {
        "x": {
          "field": "購入頻度",
          "type": "nominal",
          "sort": ["高", "中", "低"],
          "axis": {
            "title": "購入頻度",
            "titleFontSize": 24,
            "labelFontSize": 20,
            "labelAngle": 0,
            "titlePadding": 20,
            "labelPadding": 10
          }
        },
        "y": {
          "field": "最終購入日",
          "type": "nominal",
          "sort": ["高", "中", "低"],
          "axis": {
            "title": "最終購入日",
            "titleFontSize": 24,
            "labelFontSize": 20,
            "titlePadding": 20,
            "labelPadding": 10
          }
        },
        "color": {
          "field": "顧客数",
          "type": "quantitative",
          "title": "顧客数",
          "legend": {
            "titleFontSize": 18,
            "labelFontSize": 18,
            "gradientLength": 180
          }
        },
        "tooltip": [
          { "field": "最終購入日", "type": "nominal", "title": "最終購入日" },
          { "field": "購入頻度", "type": "nominal", "title": "購入頻度" },
          { "field": "顧客数", "type": "quantitative", "title": "顧客数" }
        ]
      }
    },
    {
      "data": { "name": "dataset" },
      "mark": {
        "type": "text",
        "fontSize": 32,
        "fontWeight": "bold",
        "dy": -38
      },
      "encoding": {
        "x": {
          "field": "購入頻度",
          "type": "nominal",
          "sort": ["高", "中", "低"]
        },
        "y": {
          "field": "最終購入日",
          "type": "nominal",
          "sort": ["高", "中", "低"]
        },
        "text": {
          "field": "顧客数",
          "type": "quantitative"
        },
        "color": {
          "condition": {
            "test": "datum['顧客数'] >= 80",
            "value": "white"
          },
          "value": "black"
        }
      }
    },
    {
      "data": { "name": "dataset" },
      "transform": [
        {
          "calculate": "datum['最終購入日'] == '高' && datum['購入頻度'] == '高' ? '優良' : datum['最終購入日'] == '高' && datum['購入頻度'] == '中' ? '安定化' : datum['最終購入日'] == '高' && datum['購入頻度'] == '低' ? '新規候補' : datum['最終購入日'] == '中' && datum['購入頻度'] == '高' ? '継続' : datum['最終購入日'] == '中' && datum['購入頻度'] == '中' ? '一般' : datum['最終購入日'] == '中' && datum['購入頻度'] == '低' ? 'フォロー' : datum['最終購入日'] == '低' && datum['購入頻度'] == '高' ? '離反注意' : datum['最終購入日'] == '低' && datum['購入頻度'] == '中' ? '掘り起こし' : '休眠'",
          "as": "label"
        }
      ],
      "mark": {
        "type": "text",
        "fontSize": 24,
        "fontWeight": "bold",
        "dy": 26
      },
      "encoding": {
        "x": {
          "field": "購入頻度",
          "type": "nominal",
          "sort": ["高", "中", "低"]
        },
        "y": {
          "field": "最終購入日",
          "type": "nominal",
          "sort": ["高", "中", "低"]
        },
        "text": { "field": "label" },
        "color": {
          "condition": {
            "test": "datum['顧客数'] >= 80",
            "value": "white"
          },
          "value": "black"
        }
      }
    }
  ],
  "config": {
    "view": {
      "stroke": null
    }
  }
}

図8:サンプルコード

コード記述エリアにサンプルコードを貼り付け、「実行」をクリックします。

※本記事では詳細なコード解説は割愛しますが、
 「rect(ヒートマップ)」+「text(数値表示)」+「分類ラベル」
 の3層構造で構成されています。

⑥プレビューを確認する

図9:プレビュー画面

コード実行後、ヒートマップが表示されていれば成功です。問題なければ、左上の「レポートに戻る」をクリックします。

⑦ビジュアルの完成

図10:完成したビジュアル

レポート画面上に、作成したヒートマップが表示されます。

■まとめ

Deneb を活用することで、Power BI の標準ビジュアルでは難しい表現も柔軟に実現できます。一方で、コードベースでの実装となるため、最初はややハードルが高く感じるかもしれません。しかし、近年では生成AIなどを活用することで、コードの作成や調整も容易になっています。まずは本記事のサンプルをベースに、少しずつカスタマイズしながら理解を深めていくのがおすすめです。

cropped-logo-1.png_noindex

技術とノウハウでデジタルシフトをサポート
中小企業の頼れるパートナー

執筆者: 村瀬 俊昭(株式会社クロスディーズ システム技術統括エンジニア)

前職では社内システムの運用、サーバーの監視、システム運用業務の構築、システム開発業務といった業務に幅広く携わる。2021年より株式会社佐々木総研にてロボットの設計・開発、社内SEとして従事している。釣りが趣味で、大のビール好き。