緒言
以前こちらで記事化したものの改良版。
動作イメージは↓
作り方
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({
_minDate:DateAdd(Today(),-30,TimeUnit.Days),
_dateDuration:60,
_step:1
})
ColPlannerPlus
:PlannerPlus
に行インデックス列を追加したコレクション
_minDate
:Today基準の30日前。
_dateDuration
:ガントチャートの列数。
_step
:ガントチャート1列ごとの間隔(日)。初期1日とする。
2.画面設計
主なコントロールは下記の6つ
GalleryMain2
:ガントチャートのメインギャラリー
GalleryDate2
:日付ラベル用のギャラリー
RadioGroupStep
:ガントチャートの列間隔(日)の変更
IconBack
:チャートを左へ移動
IconNext
:チャートを右へ移動
ButtonReset
:チャートをリセット
3.コード
コピペ用
- ContainerGantt2:
Control: GroupContainer
Variant: manualLayoutContainer
Properties:
DropShadow: =DropShadow.Bold
Height: =461
RadiusBottomLeft: =10
RadiusBottomRight: =10
RadiusTopLeft: =10
RadiusTopRight: =10
Width: =1113
X: =150
Y: =85
Children:
- GalleryMain2:
Control: Gallery
Variant: BrowseLayout_Vertical_OneTextVariant_ver5.0
Properties:
Items: =ColPlannerPlus
DelayItemLoading: =true
Height: =Parent.Height-Self.Y
Layout: =Layout.Vertical
LoadingSpinner: =LoadingSpinner.Data
TemplatePadding: =0
TemplateSize: =60
Width: =Parent.Width
Y: =67
Children:
- RectangleGridH2:
Control: Rectangle
Properties:
OnSelect: =Select(Parent)
Height: =2
Visible: =LabelBucket2.Text<>""
Width: =Parent.Width
- LabelID2:
Control: Label
Properties:
OnSelect: =Select(Parent)
Text: =ThisItem.ID
Height: =18
PaddingBottom: =0
PaddingRight: =0
PaddingTop: =0
Size: =12
Visible: =false
Width: =86
X: =108
- LabelTitle2:
Control: Label
Properties:
OnSelect: =Select(Parent)
Text: =ThisItem.タイトル
Fill: =App.Theme.Colors.Lighter80
Height: =Parent.TemplateHeight
PaddingBottom: =0
PaddingRight: =0
PaddingTop: =0
Width: =194
X: =108
- LabelBucket2:
Control: Label
Properties:
OnSelect: =Select(Parent)
Text: =If(ThisItem.RowIndex>1&&Index(ColPlannerPlus,ThisItem.RowIndex-1).Bucket=ThisItem.Bucket,"",ThisItem.Bucket)
Color: =
Fill: =RGBA(255, 255, 255, 1)
FontWeight: =FontWeight.Bold
Height: =Parent.TemplateHeight
PaddingBottom: =0
PaddingLeft: =15
PaddingRight: =0
PaddingTop: =0
Width: =108
- GallerySub2:
Control: Gallery
Variant: BrowseLayout_Horizontal_TwoTextOneImageVariant_ver5.0
Properties:
Items: =Sequence(_dateDuration,1,_step)
DelayItemLoading: =true
Height: =60
LoadingSpinner: =LoadingSpinner.Data
ShowScrollbar: =false
TemplatePadding: =0
TemplateSize: =IfError(Self.Width/_dateDuration,1)
Width: =Parent.Width-302
X: =302
Children:
- RectangleSchedule2:
Control: Rectangle
Properties:
OnSelect: =Select(Parent)
BorderColor: =RGBA(40, 134, 222, 1)
BorderStyle: =BorderStyle.None
Fill: =RGBA(40, 134, 222, 1)
Height: =Parent.TemplateHeight*0.6
Visible: |-
=With({rec:LookUp(ColPlannerPlus,ID=Value(LabelID2.Text))},
And(
DateDiff(_minDate,rec.StartDate,TimeUnit.Days)<=ThisItem.Value-1,
DateDiff(_minDate,rec.DueDate,TimeUnit.Days)>=ThisItem.Value-1
)
)
Width: =Parent.TemplateWidth
Y: =Parent.TemplateHeight/2-Self.Height/2
- RectangleToday2:
Control: Rectangle
Properties:
OnSelect: =Select(Parent)
BorderStyle: =BorderStyle.None
Fill: =RGBA(215, 58, 60, 1)
Height: =60
Visible: =And(DateAdd(_minDate,ThisItem.Value-_step)<=Today(),DateAdd(_minDate,ThisItem.Value)>Today())
Width: =4
X: =Parent.TemplateWidth/2-Self.Width/2
- RectangleGridV2:
Control: Rectangle
Properties:
OnSelect: =Select(Parent)
BorderStyle: =BorderStyle.None
Fill: =RGBA(106, 122, 127, 1)
Height: =60
Width: =1
- GalleryDate2:
Control: Gallery
Variant: BrowseLayout_Horizontal_TwoTextOneImageVariant_ver5.0
Properties:
Items: =Sequence(_dateDuration,1,_step)
DelayItemLoading: =true
Height: =30
LoadingSpinner: =LoadingSpinner.Data
ShowScrollbar: =false
TemplatePadding: =0
TemplateSize: =IfError(Self.Width/_dateDuration,1)
Width: =Parent.Width-GallerySub2.X
X: =GallerySub2.X
Y: =35
Children:
- TextCanvasDate2:
Control: Text
Properties:
Text: =Text(DateAdd(_minDate,ThisItem.Value-1),"m/d")
Wrap: =false
Height: =Parent.Height
Visible: =IfError(Mod(ThisItem.Value,Int(_dateDuration*_step/10)),2)=1
Width: =50
- RadioGroupStep:
Control: Radio
Variant: pcfdataset
Properties:
OnChange: =UpdateContext({_step:Self.Selected.value})
DefaultSelectedItems: =[{text:"1d",value:1}]
Items: =[{text:"1d",value:1},{text:"3d",value:3},{text:"7d",value:7}]
Layout: ='RadioGroupCanvas.Layout'.Horizontal
Height: =40
Width: =200
X: =62
Children:
- TextInput1_1:
Control: PowerApps_CoreControls_RadioGroupCanvasTemplate_dataField
Variant: textualColumn
Properties:
FieldDisplayName: ="text"
FieldName: ="text"
FieldType: ="s"
Order: =1
- IconBack:
Control: Classic/Icon
Variant: BackArrow
Properties:
OnSelect: =UpdateContext({_minDate:DateAdd(_minDate,-15*_step,TimeUnit.Days)})
Height: =35
Icon: =Icon.BackArrow
PaddingBottom: =3
PaddingLeft: =3
PaddingRight: =3
PaddingTop: =3
Width: =35
X: =302
- IconNext:
Control: Classic/Icon
Variant: BackArrow
Properties:
OnSelect: =UpdateContext({_minDate:DateAdd(_minDate,15*_step,TimeUnit.Days)})
Height: =35
Icon: =Icon.NextArrow
PaddingBottom: =3
PaddingLeft: =3
PaddingRight: =3
PaddingTop: =3
Width: =35
X: =1078
- RectangleHeadBorder:
Control: Rectangle
Properties:
OnSelect: =
BorderThickness: =2
Height: =3
Visible: =LabelBucket2.Text<>""
Width: =Parent.Width
Y: =67
- ButtonReset:
Control: Button
Properties:
OnSelect: |-
=ClearCollect(ColPlannerPlus,AddColumns(PlannerPlus,RowIndex,0));
ForAll(
Sequence(CountRows(ColPlannerPlus)) As i,
Patch(ColPlannerPlus,Index(ColPlannerPlus,i.Value),{RowIndex:i.Value})
);
UpdateContext({
_minDate:DateAdd(Today(),-30,TimeUnit.Days),
_dateDuration:60,
_step:1
})
Text: ="リセット"
X: =659
Y: =6
Mod演算時にゼロ割エラーが出ることがあったのでIfErrorで回避
結言
1年くらいのタイムスパンのある100件近くのタスクでも比較的サクッと表示できて快適!