Power Appsの画像コントロールひとつで星評価！

# はじめに
Power Apps標準の星評価は整数単位になっているので、これまで小数点が必要な場所では「★1.5」のように表示していたのですが、とあるウェブ企業による添削で「Power Appsで出来るかは知らんけど、普通は星を並べるもんだよね（脳内意訳）」という指摘があったので、意地になって作ってみました（本当はこんな表現本質じゃないのにね！）
　ギャラリーを使ったり、星画像を並べたりと色々考えた結果、最終的にSVGを使った画像１枚になりましたので、自慢させてください。

# まずは情報収集
　SVGで作るといっても、私はこれまでHiroさんの記事を参考にありもののSVGを貼り付けたことしかありませんでした。
[Power Apps で SVG を使う - MoreBeerMorePower](https://mofumofupower.hatenablog.com/entry/2020/09/22/161458)
　そこで、まずは先達の知見を得るべく、検索してみたところ、そのものズバリのページを見つけました。
[SVGでスターレーティングを実装する #CSS - Qiita](https://qiita.com/boluyama1028/items/0087242488e7e4b40f1e)
　ところが、こちらを貼り付けても、うまく動作しません。試行錯誤の結果、useとurlのところで引っかかっていることがわかり、修正しました。
その際参考にさせていただいたサイトは、以下のとおりです。
[\<use> - SVG: スケーラブルベクターグラフィック](https://developer.mozilla.org/ja/docs/Web/SVG/Element/use)
[Power Apps でのSVG 表現メモ - コルネの進捗や備忘録が記されたなにか](https://koruneko.hatenablog.com/entry/2020/12/06/064548#%E3%83%9E%E3%82%B9%E3%82%AF)

先達の皆様、どうもありがとうございました！
# こんなのを作った
　出来たSVG画像を確認するために、このようなアプリを作成しました。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278581/90dad998-4502-be26-1eae-40e1ee351df4.png)
５つ星の画像と同じ幅のスライダーの値に応じて、星が塗りつぶされます。

## コントロールの追加と設定
### コントロール一覧
| コントロール名 | 種類 | 説明 |
|:------------:|:----:|:---:|
| imgStarRating | 画像 | 星を表示する画像コントロールです |
| sldRatingRatio | スライダー | 星を塗りつぶす割合を示すスライダーです |


### 画像コントロール(imgStarRating)の設定
| プロパティ名 | 設定値 | コメント |
|:------------:|:----:|:---:|
| Height | 50 | 画像の高さ。★の高さでもあります |
| Width | 250 | 画像の幅。★が5つ並ぶので、高さを5倍します |
| ImagePosition | Fit(自動調整) | SVGの設定に関わらず調整するようFitにします |
| Image |  | 後述 |
### スライダーコントロール(sldRatingRatio)の設定
| プロパティ名 | 設定値 | コメント |
|:------------:|:----:|:---:|
| Height | 50 | 画像の高さ。画像コントロールに合わせました |
| Width | 250 | 画像の幅。画像コントロールに合わせました |
| Default | 0 | スライダーの初期値。なんでも良いです |
| Max | 100 | 100％にするために、100を入れます |
| Min | 0 | 開始は0です |
| ShowValue | false | 星と重なるため非表示にします |
### imgStarRating.Imageプロパティの設定
　以下のコードをImageプロパティに貼り付けます。
 基本的に、With文内の変数に0~5の点数と好きな色を設定すれば使えると思います。
 ``` php:Image1:Image
 //With文の変数に、点数と色を設定してご利用ください
//画像の大きさは画像コントロールの値を反映しておらず、自動調整に任せています
//use要素の最初の5行で星を塗潰しか透過か判断しながら横並びに5個配置し、最後の1行で欠ける星の位置と割合を判断してマスクしています
With(
    {
        rating:sldRatingRatio.Value/20, //星評価の点数。0～5の範囲になるよう調整します
        fillcolor:"#ffb200",            //星を塗りつぶす色。文字列です
        linecolor:"blue"                //星の枠線の色。こちらも文字列です
    },
    "data:image/svg+xml," & 
    EncodeUrl(
        "
        <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 32'>
            <defs>
                <mask id='mask'>
                    <rect x='0' y='0' width='32' height='32' fill='white' />
                    <rect x='" & (rating-RoundDown(rating,0))*32 & "' y='0' width='32' height='32' />
                </mask>
                <symbol id='star'>
                    <path d='M31.547 12a.848.848 0 00-.677-.577l-9.427-1.376-4.224-8.532a.847.847 0 00-1.516 0l-4.218 8.534-9.427 1.355a.847.847 0 00-.467 1.467l6.823 6.664-1.612 9.375a.847.847 0 001.23.893l8.428-4.434 8.432 4.432a.847.847 0 001.229-.894l-1.615-9.373 6.822-6.665a.845.845 0 00.214-.869z' stroke='" & linecolor & "' />
                </symbol>
            </defs>
            <use href='#star' x='0'   fill='" & If(rating>=1,fillcolor,"transparent") & "' />
            <use href='#star' x='32'  fill='" & If(rating>=2,fillcolor,"transparent") & "' />
            <use href='#star' x='64'  fill='" & If(rating>=3,fillcolor,"transparent") & "' />
            <use href='#star' x='96'  fill='" & If(rating>=4,fillcolor,"transparent") & "' />
            <use href='#star' x='128' fill='" & If(rating>=5,fillcolor,"transparent") & "' />
            <use href='#star' x='" & RoundDown(rating,0)*32 & "' fill='" & fillcolor & "' mask='url(#mask)'/>
        </svg>
        "
    )
)
 ```
 # 動かしてみよう
 　出来たら動かしてみましょう。スライダーの動きに合わせて、塗りつぶされる範囲が変わりましたか？

# おわりに
　何か作った気になって書いてきましたが、所詮は諸先輩がたの知見のツギハギに過ぎません。
 それでも、とあるウェブ企業を（勝手に）見返せた、という満足感はハンパありません。
改めて、Hiroさん、boluyama1028さん、MDNの皆さん、コルネさん、ありがとうございました。