【Power Apps】Claude (3.5 Sonnet Artifacts)でコントロール、プロパティや変数の依存関係を可視化

ChatGPTで依存関係の可視化がうまくいかずに悩んでいたところ、以下のポストでClaudeを使ってMermaid図を生成するとよいことを教えてもらいました。

https://twitter.com/DemodoriGatsuo/status/1805578770818154608

こちらを参考に、何が可視化できればよいかを整理したうえで、Mermaid図を生成するためにはどのようなプロンプトが必要かを考えます。

## 依存関係の可視化は何のためにどんな要素が必要か

Power Appsの構成要素はアプリ、画面、コントロール、入出力・動作プロパティとツリー構造になっており、これに加えて変数やデータソースがあります。

https://powerplatformnikki.com/componentsproperties

### 何のために必要か

この構造によって通常のプログラミング言語よりもオブジェクトごとにコードが散らばっており、機能のロジックを人に説明したりバグを改修したりするときに大きなハードルになっています。

依存関係を可視化することで、ドキュメント作成・バグの改修・リファクタリングなどにかかる工数や対応漏れを大幅に少なくすることができると思います。

### どんな要素が必要か

依存関係を表す図に含まれるべき要素(ノード)としては、大別してオブジェクト(とそのプロパティ)、変数、データソースの三種類があります。

また依存関係を示す線(エッジ)は、オブジェクトごとのツリー構造や要素ごとの依存関係を表すものが必要です。

それぞれが線がオブジェクトにかぶったり、視覚的にわかりやすい色分けがされていることも可視化する上では重要になります。

## 実際にやってみた

何のためにどんな要素が必要かというところが整理できたので、実際にMermaid図を生成してみます。
以下のプロンプトとyamlファイルを入力します。

```
これらのyamlファイルはPower Appsで作成したテトリス風ゲームのソースコードです。
これをソースにして後続の指示に従い変数、プロパティやコントロールそれぞれの依存関係や親子関係を、
網羅的で完璧にMermaid図にしたものを時間をかけてもよいので生成してください

Power Appsには以下の大別して■の三要素があり、その中にもそれぞれ設計要素などが含まれています。
■オブジェクト
・画面
・コントロール
・入出力プロパティ

■変数
・名前付き計算式
・グローバル変数
・コンテキスト変数
・コレクション

■データソース
・データソース
・コネクタ

Mermaid図が必要な理由：
・この構造によって通常のプログラミング言語よりもオブジェクトごとにコードが散らばっており、機能のロジックを人に説明したりバグを改修したりするときに大きなハードルになっています。
・依存関係を可視化することで、ドキュメント作成・バグの改修・リファクタリングなどにかかる工数や対応漏れを大幅に少なしたいです。

Mermaid図に必要な要素と条件：
・依存関係を表す図に含まれるべき要素(ノード)としては、大別してオブジェクト(とそのプロパティ)、変数、データソースの三種類があります。
・また依存関係を示す線(エッジ)は、オブジェクトごとのツリー構造や要素ごとの依存関係を表すものが必要です。
・それぞれが線がオブジェクトにかぶったり、視覚的にわかりやすい色分けがされていることも可視化する上では重要になります。
・画面、コントロール、入出力プロパティのツリー構造が視覚的にわかる
・変数・データソースと入出力プロパティの依存関係が線でつながっている
・コントロールとその入出力プロパティの親子関係が線でつながっている
・ノードとエッジが省略されることなくすべて網羅的にMermaid図上に存在している
```

このプロンプトで以下のMermaid記法の文字列が生成されました。

```
flowchart TD
    %% 色の定義
    classDef screen fill:#e6f3ff,stroke:#0066cc
    classDef control fill:#fff2cc,stroke:#d6b656
    classDef property fill:#d5e8d4,stroke:#82b366
    classDef namedFormula fill:#f8cecc,stroke:#b85450
    classDef globalVar fill:#e1d5e7,stroke:#9673a6
    classDef contextVar fill:#dae8fc,stroke:#6c8ebf
    classDef collection fill:#fff2cc,stroke:#d6b656
    classDef dataSource fill:#d5e8d4,stroke:#82b366
    classDef connector fill:#ffe6cc,stroke:#d79b00

    subgraph Objects["オブジェクト"]
        subgraph Screens["画面"]
            Screen1[Screen1]:::screen
        end

        subgraph Controls["コントロール"]
            ImageBackGround[ImageBackGround]:::control
            GalleryBoard[GalleryBoard]:::control
            Timer1[Timer1]:::control
            SliderHorizontal[SliderHorizontal]:::control
            SliderVertical[SliderVertical]:::control
            ContainerRight[ContainerRight]:::control
            ButtonRight[ButtonRight]:::control
            ContainerLeft[ContainerLeft]:::control
            ButtonLeft[ButtonLeft]:::control
            ContainerStart[ContainerStart]:::control
            ButtonStart[ButtonStart]:::control
            TextInputKeyBoard[TextInputKeyBoard]:::control
            SliderHorizontalKeyBoard[SliderHorizontalKeyBoard]:::control
            ContainerScore[ContainerScore]:::control
            LabelScore[LabelScore]:::control
            AudioBGM[AudioBGM]:::control
            AudioSE[AudioSE]:::control
            LabelChain[LabelChain]:::control
            ToggleBGM[ToggleBGM]:::control
            ToggleSE[ToggleSE]:::control
            GalleryQues[GalleryQues]:::control
            ButtonGuide[ButtonGuide]:::control
            ContainerGuide[ContainerGuide]:::control
            ButtonGuideClose[ButtonGuideClose]:::control
            LabelGuide[LabelGuide]:::control
            ContainerGameOver[ContainerGameOver]:::control
            ButtonTryAgain[ButtonTryAgain]:::control
            LabelScore_1[LabelScore_1]:::control
            LabelScore_2[LabelScore_2]:::control
            ImageX[ImageX]:::control
        end

        subgraph Properties["入出力プロパティ"]
            Screen1_OnStart[OnStart]:::property
            GalleryBoard_Items[Items]:::property
            GalleryBoard_OnSelect[OnSelect]:::property
            Timer1_OnTimerEnd[OnTimerEnd]:::property
            SliderHorizontal_OnChange[OnChange]:::property
            SliderVertical_OnChange[OnChange]:::property
            ButtonRight_OnSelect[OnSelect]:::property
            ButtonLeft_OnSelect[OnSelect]:::property
            ButtonStart_OnSelect[OnSelect]:::property
            TextInputKeyBoard_Default[Default]:::property
            AudioBGM_Loop[Loop]:::property
            AudioSE_AutoStart[AutoStart]:::property
            GalleryQues_Items[Items]:::property
            ButtonGuide_OnSelect[OnSelect]:::property
            ContainerGameOver_Visible[Visible]:::property
            ButtonTryAgain_OnSelect[OnSelect]:::property
        end
    end

    subgraph Variables["変数"]
        subgraph NamedFormulas["名前付き計算式"]
            MovingMino[MovingMino]:::namedFormula
            MovingRng[MovingRng]:::namedFormula
        end

        subgraph GlobalVars["グローバル変数"]
            _Score[_Score]:::globalVar
            _chain[_

chain]:::globalVar
            _guide[_guide]:::globalVar
            _gameOver[_gameOver]:::globalVar
            _SE[_SE]:::globalVar
        end

        subgraph ContextVars["コンテキスト変数"]
            ctx_SelectedBlock[SelectedBlock]:::contextVar
        end

        subgraph Collections["コレクション"]
            ColBlocks[ColBlocks]:::collection
            ColBoard[ColBoard]:::collection
            ColQue[ColQue]:::collection
            ColScore[ColScore]:::collection
        end
    end

    subgraph DataSources["データソース"]
        LocalStorage[LocalStorage]:::dataSource
    end

    subgraph Connectors["コネクタ"]
        PowerAppsConnector[PowerAppsConnector]:::connector
    end

    %% オブジェクトの階層構造
    Screen1 --> ImageBackGround
    Screen1 --> GalleryBoard
    Screen1 --> Timer1
    Screen1 --> SliderHorizontal
    Screen1 --> SliderVertical
    Screen1 --> ContainerRight
    Screen1 --> ContainerLeft
    Screen1 --> ContainerStart
    Screen1 --> TextInputKeyBoard
    Screen1 --> SliderHorizontalKeyBoard
    Screen1 --> ContainerScore
    Screen1 --> AudioBGM
    Screen1 --> AudioSE
    Screen1 --> LabelChain
    Screen1 --> ToggleBGM
    Screen1 --> ToggleSE
    Screen1 --> GalleryQues
    Screen1 --> ButtonGuide
    Screen1 --> ContainerGuide
    Screen1 --> ContainerGameOver

    ContainerRight --> ButtonRight
    ContainerLeft --> ButtonLeft
    ContainerStart --> ButtonStart
    ContainerScore --> LabelScore
    ContainerGuide --> ButtonGuideClose
    ContainerGuide --> LabelGuide
    ContainerGameOver --> ButtonTryAgain
    ContainerGameOver --> LabelScore_1
    ContainerGameOver --> LabelScore_2
    ContainerGameOver --> ImageX

    %% プロパティとコントロールの関連
    Screen1 --> Screen1_OnStart
    GalleryBoard --> GalleryBoard_Items
    GalleryBoard --> GalleryBoard_OnSelect
    Timer1 --> Timer1_OnTimerEnd
    SliderHorizontal --> SliderHorizontal_OnChange
    SliderVertical --> SliderVertical_OnChange
    ButtonRight --> ButtonRight_OnSelect
    ButtonLeft --> ButtonLeft_OnSelect
    ButtonStart --> ButtonStart_OnSelect
    TextInputKeyBoard --> TextInputKeyBoard_Default
    AudioBGM --> AudioBGM_Loop
    AudioSE --> AudioSE_AutoStart
    GalleryQues --> GalleryQues_Items
    ButtonGuide --> ButtonGuide_OnSelect
    ContainerGameOver --> ContainerGameOver_Visible
    ButtonTryAgain --> ButtonTryAgain_OnSelect

    %% 変数とプロパティの依存関係
    MovingMino --> Timer1_OnTimerEnd
    MovingMino --> SliderHorizontal_OnChange
    MovingMino --> ButtonRight_OnSelect
    MovingMino --> ButtonLeft_OnSelect
    MovingRng --> Timer1_OnTimerEnd
    _Score --> LabelScore
    _Score --> LabelScore_1
    _chain --> LabelChain
    _guide --> ContainerGuide
    _gameOver --> ContainerGameOver_Visible
    _SE --> AudioSE_AutoStart
    ctx_SelectedBlock --> GalleryBoard_OnSelect

    ColBlocks --> Screen1_OnStart
    ColBoard --> Screen1_OnStart
    ColBoard --> GalleryBoard_Items
    ColBoard --> Timer1_OnTimerEnd
    ColQue --> Screen1_OnStart
    ColQue --> GalleryQues_Items
    ColScore --> Screen1_OnStart

    %% データソースと変数の関連
    LocalStorage --> ColScore

    %% コネクタとデータソースの関連
    PowerAppsConnector --> LocalStorage

    %% 主要なゲームロジックの流れ
    Timer1_OnTimerEnd -->|ブロック移動| ColBoard
    SliderHorizontal_OnChange -->|水平移動| ColBoard
    SliderVertical_OnChange -->|垂直移動| ColBoard
    ButtonRight_OnSelect -->|回転| ColBoard
    ButtonLeft_OnSelect -->|回転| ColBoard
    ButtonStart_OnSelect -->|ゲーム開始/リセット| ColBoard
    ButtonStart_OnSelect -->|ゲーム開始/リセット| ColQue
    ButtonStart_OnSelect -->|ゲーム開始/リセット| _Score
    ButtonTryAgain_OnSelect -->|ゲームリセット| ColBoard
    ButtonTryAgain_OnSelect -->|ゲームリセット| ColQue
    ButtonTryAgain_OnSelect -->|ゲームリセット| _Score
    ButtonTryAgain_OnSelect -->|ゲームリセット| _gameOver

    %% 注釈
    classDef note fill:#f9f,stroke:#333,stroke-width:2px;
    class Note1,Note2,Note3 note;

    Note1["ColBoardはゲームの\nメイングリッドを表す"]
    Note2["MovingMinoは現在\n移動中のブロックを追跡"]
    Note3["_Scoreはゲーム中\n常に更新される"]

    ColBoard --- Note1
    MovingMino --- Note2
    _Score --- Note3
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618051/206e69da-4fde-66ec-feb9-7aa00cc14e43.png)


複雑すぎて線が被ってしまってますが、依存関係の可視化には成功しました。

## 元記事

https://powerplatformnikki.com/claudemermaiddependencies/