5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Microsoft Power AppsAdvent Calendar 2024

Day 20

Power Appsで縮尺可変ガントチャート

Last updated at Posted at 2024-12-19

緒言

こちらこちらの記事でタスク管理について書いてきましたが、上司やプロジェクトリーダーが見たいのはガントチャート。全体感を見たかったり、直近の細かい予定を見たかったりで縮尺可変が望ましい!ということでチャレンジしてみました。PlannerにもScheduleビューが用意されてるけど、ちょっと使いにくい。。。

完成イメージは以下

作り方

1. データ用意

バケット(Bucket)で分類された開始日(StartDate)と納期(DueDate)を持つタスクリストをデモデータPlannerPlusとする。

Title Bucket StartDate DueDate
ベンチプレス 胸トレ 2024/12/09 2024/12/13
ダンベルフライ 胸トレ 2024/12/11 2024/12/14
プッシュアップ 胸トレ 2024/12/03 2024/12/17
レッグプレス 足トレ 2024/12/16 2024/12/27
カーフレイズ 足トレ 2024/12/23 2024/12/27
スクワット 足トレ 2024/12/08 2025/01/10
デッドリフト 背中トレ 2025/01/01 2025/01/09
ラットプルダウン 背中トレ 2025/01/06 2025/01/16

このデータを使って以下のコレクションや変数を作成。

ClearCollect(ColPlannerPlus,AddColumns(PlannerPlus,RowIndex,0));
ForAll(
    Sequence(CountRows(ColPlannerPlus)) As i,
    Patch(ColPlannerPlus,Index(ColPlannerPlus,i.Value),{RowIndex:i.Value})
);
UpdateContext({_maxDate:Max(ColPlannerPlus,DueDate),_minDate:Min(ColPlannerPlus,StartDate)});
UpdateContext({_dateDuration:DateDiff(_minDate,_maxDate,TimeUnit.Days)})

ColPlannerPlusPlannerPlusに行インデックス列を追加したコレクション
_maxDate:全データ中の日付最大値
_minDate:全データ中の日付最小値
_dateDuration_maxDateminDateの差(日)

2.画面設計

image.png
コンテナ内にパーツを配置。特に重要なパーツは以下の6種類。
RadioGroupMag:倍率選択ラジオボタン
SliderZoom:Zoom操作スライダー
SliderScroll:拡大時のスクロール用スライダー
RectangleBlind:目隠し用の図形
GalleryDate:日付ラベル用のギャラリー
GalleryMain:ガントチャートのメインギャラリー

GalleryMain内部に入れ子でギャラリーを下図のように配置。
image.png
LabelID:非表示だがTextプロパティで子ギャラリーに親ギャラリーのレコード情報を渡す役割。
LabelTitle:タスクタイトル表示
LabelBucket:バケット表示
GallerySub:ガントチャート表示用ギャラリー

GallerySubの内容は今日の目印やスケジュール塗りつぶし用の図形。
image.png

3.ロジック

スライダーやラジオボタンの値に応じて幅や座標を可変にしている。

- ContainerGantt:
    Children:
    - GalleryMain:
        Properties:
          Items: =ColPlannerPlus
          Width: =Parent.Width*(1+(SliderZoom.Value-1)/10*RadioGroupMag.Selected.value)
        Children:
        - LabelID:
            Properties:
              Text: =ThisItem.ID
              
        - LabelTitle:
            Properties:
              Text: =ThisItem.Title
              
        - LabelBucket:
            Properties:
              Text: |-
                  =If(
                      And(
                          ThisItem.RowIndex>1,
                          Index(ColPlannerPlus,ThisItem.RowIndex-1).Bucket=ThisItem.Bucket
                      ),
                      "",
                      ThisItem.Bucket
                  )
                  
        - GallerySub:
            Properties:
              Items: =Sequence(_dateDuration)
              TemplateSize: =Self.Width/_dateDuration
              Width: =Parent.Width-(LabelTitle.X+LabelTitle.Width)
              X: =LabelTitle.X+LabelTitle.Width-(SliderScroll.Value-1)*(GalleryMain.Width-ContainerGantt.Width)/SliderScroll.Max
            Children:
            - RectangleSchedule:
                Properties:
                  Visible: |-
                    =With({rec:LookUp(ColPlannerPlus,ID=Value(LabelID.Text))},
                        And(
                            DateDiff(_minDate,rec.StartDate,TimeUnit.Days)<=ThisItem.Value-1,
                            DateDiff(_minDate,rec.DueDate,TimeUnit.Days)>=ThisItem.Value-1
                        )
                    )
                  Width: =Parent.TemplateWidth+1
                  Y: =Parent.TemplateHeight/2-Self.Height/2
                  
            - RectangleToday:
                Properties:
                  Visible: =DateAdd(_minDate,ThisItem.Value-1)=Today()
                  
    - GalleryDate:
        Properties:
          Items: =Sequence(_dateDuration)
          TemplateSize: =Self.Width/_dateDuration
          Width: =Parent.Width*(1+(SliderZoom.Value-1)/10*RadioGroupMag.Selected.value)-(LabelTitle.X+LabelTitle.Width)
          X: =LabelTitle.X+LabelTitle.Width-(SliderScroll.Value-1)*(GalleryMain.Width-ContainerGantt.Width)/SliderScroll.Max
        Children:
        - TextCanvasDate:
            Properties:
              Text: =Text(DateAdd(_minDate,ThisItem.Value-1),"m/d")
              Visible: =Mod(ThisItem.Value,Int(_dateDuration/10))=1

結言

そんなに苦労せず見やすいガントチャートができた!

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?