コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

Power Appsで進捗インジゲーターを作成する


スポンサードリンク

はじめに

作成するのはこちらの動画でも0:18~あたりから画面上部に表示されているようなカウントダウンタイマーとして利用している進捗インジゲーターです。

ちなみにここで紹介しているNumber 9の実装方法については以下イベントでお話する予定ですので、お時間の合う方は是非ご参加ください!

jppgb.connpass.com

今回はなんとつよつよな方々にご登壇いただけることになりました!
Power Platform界隈では有名なお歴々ですね。
この場を借りて改めてお礼をいわせていただきます。ご登壇いただき誠にありがとうございます!

進捗インジゲーターを作成する

コンポーネントを作成する

いちいち定義するのもめんどくさいのでコンポーネントで作成しましょう。

可変となるのは

  • インジゲーターの背景色
  • 進捗ゲージの塗りつぶし色
  • 進捗の値

ですね。
なのでこれらをカスタムプロパティとして作成します。

表示名 説明 プロパティの型 データ型 サンプル値
BGFill 背景色(16進) 入力 テキスト "#3f3f3f"
ProgressFill 進捗の塗りつぶし色(16進) 入力 テキスト "#f1f1f1"
ProgressValue 進捗の値(%) 入力 数値 30

他にも可変にしたい項目があればここでプロパティを作成しましょう。

進捗インジゲーターを描画する

進捗インジゲーターはSVGで描画しています。

よって画像コントロールを画面に追加します。

サイズはコンポーネント利用時にアプリ側で可変にできるように画面サイズと同じにしておきましょう。

画像コントロールImageには以下のようなSVGを設定します。

Image.Image

"data:image/svg+xml,"& 
EncodeUrl(
    "<svg viewBox='0 0 "& Self.Width & " " & Self.Height & "' xmlns='http://www.w3.org/2000/svg'>
        <circle 
            cx='" & Self.Width / 2 & "' 
            cy='" & Self.Height / 2 & "' 
            r='" & Self.Width / 2 & "' 
            fill='" & Parent.BGFill & "' 
        />
        <path 
            d='M" & Self.Width / 2 & "," & Self.Height / 2 & " 
            L" & Self.Width / 2 & ",0 
            A" & Self.Width / 2 & "," & Self.Height / 2 & " 
                0 " &
                If(
                    Parent.ProgressValue < 50,
                    "0,1",
                    "1,1"
                ) 
                & "
                " & Self.Width / 2 + Self.Width / 2 * Sin(Radians(Min(Parent.ProgressValue / 100, 0.999) * 360)) & "," & 
                    Self.Height / 2 - Self.Height / 2 * Cos(Radians(Min(Parent.ProgressValue / 100, 0.999) * 360)) & "z' 
            fill='" & Parent.ProgressFill & "' 
        />
    </svg>"
)

簡単に解説メモを残しておきます。

まず背景となる円は以下で描画しています。
画像コントロールの中心にコントロールの描画領域いっぱいに円を描画しています。

背景色はカスタムプロパティで指定したものですね。

        <circle 
            cx='" & Self.Width / 2 & "' 
            cy='" & Self.Height / 2 & "' 
            r='" & Self.Width / 2 & "' 
            fill='" & Parent.BGFill & "' 
        />

進捗インジゲーターは以下で描画しています。

        <path 
            d='M" & Self.Width / 2 & "," & Self.Height / 2 & " 
            L" & Self.Width / 2 & ",0 
            A" & Self.Width / 2 & "," & Self.Height / 2 & " 
                0 " &
                If(
                    Parent.ProgressValue < 50,
                    "0,1",
                    "1,1"
                ) 
                & "
                " & Self.Width / 2 + Self.Width / 2 * Sin(Radians(Min(Parent.ProgressValue / 100, 0.999) * 360)) & "," & 
                    Self.Height / 2 - Self.Height / 2 * Cos(Radians(Min(Parent.ProgressValue / 100, 0.999) * 360)) & "z' 
            fill='" & Parent.ProgressFill & "' 
        />

ここで扇形の中心座標を設定しています。
今回は円の中心(画像コントロールの中心)ですね。

 d='M" & Self.Width / 2 & "," & Self.Height / 2 & " 

ここで扇形の始点座標を設定しています。
今回は円の中心の頂点ですね。

L" & Self.Width / 2 & ",0 

ここでは扇形の半径を設定しています。
設定が必要なのは"縦"の半径と"横"の半径です。
つまり設定によっては楕円も設定できるってことですね。

 A" & Self.Width / 2 & "," & Self.Height / 2 & " 

ここではパターンを指定します。
扇形の角度が180°以下ならば"0, 1"を、180°以上ならば"1, 1"を設定します。

今回は進捗率ですので、進捗率が50%を超えているかどうかで判断しています。

If(
    Parent.ProgressValue < 50,
    "0,1",
    "1,1"
) 

ここでは扇形の終点座標を設定しています。
扇形の座標は、みんな大好き三角関数で求められますね!

Power Appsで三角関数ラジアンで計算されるのでRadians関数でDegreeをRadianに変換しています。

100%になった = 360°となってしまうので扇形が表示されなくなってしまいます。
それを防ぐためにMin( , 0.999)で360°を超えないようにしています。

" & Self.Width / 2 + Self.Width / 2 * Sin(Radians(Min(Parent.ProgressValue / 100, 0.999) * 360)) & "," & 
    Self.Height / 2 - Self.Height / 2 * Cos(Radians(Min(Parent.ProgressValue / 100, 0.999) * 360)) & "z' 

最後にここで扇形の塗りつぶし色を設定しています。

fill='" & Parent.ProgressFill & "'

おわりに

SVGを利用することでちょっとオシャレ?な進捗管理もできるようになります。

コンポーネント化することで、他のユーザーも簡単に利用できるようになるのでこういったSVGで描画するやつはコンポーネント化して展開してあげると便利かもしれませんね。


スポンサードリンク