Power BI SVGを使ってみよう

## 概要  

Power BIのメジャーからSVGを使ってみます。
SVGをドローイングソフト（今回はInkscape)で描いたあと、最適化してPower BIのメジャー式に使用し表示します。
![ezgif.com-gif-maker (14).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/15f6c702-25cd-7027-c8ca-f9c02239bc8f.gif)

## SVG（Scalable Vector Graphics)について  

https://developer.mozilla.org/ja/docs/Web/SVG  より
>旧来の JPEG や PNG のようなビットマップ画像形式と比較して、 SVG 形式のベクター画像は、品質を損なうことなく任意の大きさでレンダリングすることができ、テキストを更新することで、グラフィックエディターを使用せずに簡単にローカライズすることができます。適切なライブラリを使用すれば、 SVG ファイルをその場でローカライズすることも可能です。

メジャーにカスタマイズしたSVGを描画することで、よりビジュアライズされた表現が可能です。

## 注意  

* フリーのオープンソースソフトウェアInkscapeを使っています。
* Visual Studio Codeを使用する前提で進めていきます。
* オープンソースソフトウェア等を使用するので業務利用の場合、管理者にご相談ください。
* 2021年2月の情報です。

## 環境  

Windows 10 20H2
Power BI Desktop + Power BIビジュアル「HTML Content 1.1.0.15
Inkscape 1.0.2
Visual Studio Code + 拡張機能「Svg Preview 2.8.3」「XML tools 2.5.1」
node.js v14.15.4 ＋SVGO

## やってみよう  

インストール等の環境構築はその都度行います。

### InkscapeでSVGを書いてみよう

[Inkscape](https://inkscape.org/ja/)はベクターベースのドローイングソフトです。
[Inkscape](https://inkscape.org/ja/)をダウンロードおよびインストールしてください。
Inkscapeの詳細については　https://inkscape.org/ja/about/
インストールできたら起動して適当にお絵描きしてみます。
使い方については解説しません。https://inkscape.org/ja/about/features/
![2021-02-03-12-20-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/e188f34d-5986-b060-82fd-a07f63f57018.png)


描き終わったら適当な名前を付けたフォルダーにsvgを保存します。

![2021-02-03-13-14-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/2d4707d1-92ac-b609-cd89-fe85d6ff5f44.png)

### Visual Studio CodeでSVGを表示しよう

[Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)をインストールして起動します。
拡張機能から必要に応じて日本語化してください。
Visual Studio Codeの拡張機能「Svg Preview 2.8.3」をインストールします。
いくつかSVGをプレビューする拡張機能がありますが個人的にこれが使いやすいと思いました。

![2021-02-03-01-56-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/d9793b91-7449-305c-485c-fe831c07884c.png)

ファイル＞フォルダーを開くからSVGを保存したフォルダーを指定します。
保存したSVGがあると思いますので選択すると表示することができます。

![2021-02-03-13-34-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/386c8c2a-29c3-c436-37f4-cdaa821b0579.png)

このままPower BIに使うのは余分な部分が多すぎて意味がわかりづらいので最適化します。

### Node.js+SVGOを使って最適化しよう

Node.js ＋SVGOを使うことでVisual Studio Code上から最適化できるため利便性が増します。
[Node.js](https://nodejs.org/ja/)推奨版をインストールします。
インストール完了後コマンドプロンプトからバージョン確認を行います。
```node -v```  
```npm -v```

![2021-02-03-02-16-07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/6fa76b54-5ee2-bd16-df82-f4fed42b5218.png)

問題なければSVGOをグローバルにインストールします。
```npm install -g svgo```  

SVGOの詳細ついては　https://github.com/svg/svgo  をご参照ください。
Visual Studio Codeに戻って、Ctrl＋＠または表示＞ターミナルでターミナルを開きます。
![2021-02-03-14-00-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/9fc49a01-69eb-811d-0fad-054c40f64361.png)

ターミナルに```SVGO aaa.svg -o bbb.svg```と入力します。
aaa.svgを開いて最適化、bbb.svgで保存という意味です。
-oオプションを使うことで別名保存できます。
```SVGO aaa.svg```とした場合は上書き保存となります。
![2021-02-03-14-25-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/f59cb06d-7236-1fa9-dffa-becbf8dd288f.png)

最適化されます。
1行に集約されてしまうため、xmlフォーマッターを機能拡張に導入します。
![2021-02-03-14-22-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/8cf4e302-fe37-9e5d-0f63-813b7fad0ddc.png)
インストールできたらコード上で右クリックしてドキュメントのフォーマットを実行するかShift+alt+Fを実行します。
![2021-02-03-14-32-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/3824b7c6-f33d-eaa7-9d06-df1b8ec82a0d.png)

見やすくなりました。

ドキュメントサイズの指定は必要がないので削除します。

![2021-02-03-14-52-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/3078e055-49e6-b1dd-5447-c48ea61a81f8.png)

**重要ポイント**
**Power BIのメジャー内に記述する際、ダブルクォーテーションは文字の識別子として機能してしまうためこのまま使うとエラーになってしまいます。そこでダブルクオーテーションをシングルクォーテションに置換える必要があります。**

手順
1. 最初に出てくるダブルクォーテーションを選択。  ![2021-02-03-15-00-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/a22cd36e-b8a7-34a4-bf5f-bc93de0630c7.png)

2. Cntrl+F2でダブルクォーテーションが全選択できます。![2021-02-03-15-02-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/93f76910-0a84-8ab9-2b21-4097463a4c13.png)

3. シングルクォーテションに一括で書き換えます。![2021-02-03-15-04-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/2d70f81c-2099-21a7-3cd3-d69e00044447.png)

4. Escキーで選択モードを抜ければ完了です。

**SVGのパラメーターを変えながらどのような挙動をするか確認しておくと、理解が深まります。**
また[SVG要素リファレンス](https://developer.mozilla.org/ja/docs/Web/SVG/Element)を参考に要素を追加してみるのも楽しいです。
例　フィルター要素を追加してみました
![2021-02-03-17-40-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/78791e02-5253-af68-7d1e-b8c94228a196.png)

### Power BI DesktopにSVGをつかってみよう　　

前置きが長くなってしまいましたがここからが本題です。

サンプルではSVGの色をスライサーで変化させてみます。
新規レポートを作成してデータの入力から次のようなテーブルを作成します。

![2021-02-03-18-10-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/4e929dfd-6d58-92f7-33a4-b766b822ef8a.png)

新しいメジャーから次のようなメジャーを追加します。
Data URI schemeを使うことでSVGをPowerBIに読込むことができます。
```"data:image/svg+xml;utf8,<SVGコード>"```定型文の呪文です。

```dax
SVGImage = 
var c = SELECTEDVALUE(Color[ColorName])
return "data:image/svg+xml;utf8,
```

上記コードの**カンマの後に続けて作成したSVGコードを貼り付けます。**
**貼り付けたコードの最後をダブルクォーテーションで閉じます。**

``` dax
SVGImage = 
var c = SELECTEDVALUE(Color[ColorName])
return "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'>
    <ellipse cx='101.6' cy='138.339' rx='58.964' ry='49.137' fill='#ff0'/>
    <ellipse cx='84.818' cy='128.89' rx='3.78' ry='8.693'/>
    <ellipse cx='118.08' cy='128.512' rx='3.78' ry='8.693'/>
    <path d='M84.818 162.53l37.797-.756' fill='none' stroke='#000' stroke-width='.265'/>
</svg>"
```

作成したメジャーを選択した状態でデータカテゴリを画像URLに変更します。
これを忘れるとコードのまま表示されてしまいます。
![2021-02-03-18-22-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/116910e5-3ab2-a5e6-6198-d8f529ada2ea.png)

取り敢えずこのままテーブルで表示してみます。
![2021-02-03-18-36-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/0abb41af-7fff-aea6-9616-1c9b6478ed0d.png)

SVGにまだ色の変数を渡してないので描いた時の黄色で表示されています。
なので、メジャー内のSVGの塗りつぶし部分に変数を渡せるようにします。
![2021-02-03-18-41-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/dc5faa9e-18aa-a7ba-9e9d-2a2667987fbb.png)

**```#ff0```の部分を```"&c&"```に書き換えます。**

```dax
SVGImage = 
var c = SELECTEDVALUE(Color[ColorName])
return "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'>
    <ellipse cx='101.6' cy='138.339' rx='58.964' ry='49.137' fill='"&c&"'/>
    <ellipse cx='84.818' cy='128.89' rx='3.78' ry='8.693'/>
    <ellipse cx='118.08' cy='128.512' rx='3.78' ry='8.693'/>
    <path d='M84.818 162.53l37.797-.756' fill='none' stroke='#000' stroke-width='.265'/>
</svg>"
```

テーブルで確認します。
![2021-02-03-18-51-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/e22c2167-83e7-11ba-2eb1-bceb7fa3b07c.png)

スライサーを追加してみます。
![2021-02-03-18-56-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/7aa9859c-2418-87d0-eeab-b2d026c74b65.png)


背景をグレーにしてもSVGなのでコード部分だけが描画されます。

Power BIにPower BIビジュアル「HTML Content 1.1.0.15」を追加します。
無くても表示できますがあった方が応用できると思います。

![2021-02-03-01-40-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/620b7b6f-35b4-51ea-0b53-bda51826823d.png)

テーブルの代わりに使用してみます。
![2021-02-03-19-01-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/8abd57dc-01ed-7c01-ebdd-1ac822146464.png)

大きさも自由に変えられます。
書式の背景をオフにして重ねてみたりするとSVG効果がわかります。
![2021-02-03-19-26-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/c9326e29-bc37-be62-a418-71333f0ba827.png)

ボカシ効果を付けて遊んでみました。

## まとめ

* オリジナルなSVGを手軽にPower BIレポートのメジャーとして埋め込むことができます。
* アニメーション等のさまざまな効果も可能です。
* 2年半ほど前にコミュニティフォーラムやyoutubeあったようですが最近まで知らなかったので自分なりに扱いやすい方法をまとめてみました。
* Inkscape,Visual Studio CodeからSVGの扱い方はPower BI以外にも汎用性があると思います。
* 長い記事になってしまいましたが作業自体は数分です。(;´∀｀)

## 参考  

Using SVG Images in Power BI with David Eldersveld https://www.youtube.com/watch?v=YU44czu8SD8
SVG: Scalable Vector Graphics https://developer.mozilla.org/ja/docs/Web/SVG
Node.js https://nodejs.org/ja/
svg-svgo- Node.js tool for optimizing SVG files https://github.com/svg/svgo
Webサイトを遅くするダメなSVG画像をスッキリ最適化する手軽な方法 – WPJ https://www.webprofessional.jp/three-ways-decreasing-svg-file-size-svgo/