React-grid-layout + Chartjsでダッシュボードを作成してみた

React-grid-layoutに関する記事は他にもありますが、Kibanaを意識したダッシュボードに特化した記事は見当たらなかったため、動的にグラフ追加・データソース指定ができるダッシュボードを作成してみました。（GrafanaとかSupersetみたいに立派なものではありませんのであしからず）


**作成後のイメージ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/ae047d8b-7969-972a-b4c3-aad12058be4a.png)

React-grid-layoutは下記ご参照ください。

https://github.com/react-grid-layout/react-grid-layout


# 前提（Docker環境）
Docker： 23.0.1, build a5ee5b1
docker-compose： 1.28.2, build 67630359
コンテナイメージ: nikolaik/python-nodejs:latest
Python: 3.12.5
pip3: 24.2
fastapi: 0.112.1
nodejs: v22.6.0
react-chartjs-2: 5.2.0
chart.js: 4.4.3
react-grid-layout: 1.4.1

※react-grid-layoutの最新版1.4.4は動作が不安定だったため、1.4.1にしています。

# 1. React/FastAPIコード
Githubにアップ済みのコードを使って進めます。

https://github.com/nw-engineer/Dashboard

# 2. ディレクトリ構成
GitHubに登録されているSourceコードは以下の通り

```bash
.
└── SecureAuthSite/
    ├── fastapi/
    │   └── main.py              # FastAPI
    └── react/
        ├── .env                 # PORT/API向けURL設定
        ├── package.json
        ├── package-lock.json
        └── src/
            ├── App.js           
            └── Dashboard.js     # ダッシュボード表示
```

# 3. デプロイ
gitからcloneしてコンテナを立ち上げるところから実施ます。

```bash
git clone https://github.com/nw-engineer/Dashboard.git
cd Dashboard/docker
```

起動前にsourceファイルをコピーしてからコンテナを起動ます。
```bash
mkdir work
cp -pr ../fastapi ../react work/
docker-compose up -d
```

docker psコマンドでコンテナ状態がUpしていることを確認します。
```bash
docker ps | grep kibana
79b14c17efaa   kibana-api:0.1  "python3" 21 seconds ago   Up 20 seconds 0.0.0.0:4003-4004->4003-4004/tcp, :::4003-4004->4003-4004/tcp kibana-api
```

コンテナにログインしてFastAPIを起動します。
```bash
docker exec -it kibana-api /bin/bash
cd /opt/fastapi
uvicorn main:app --host 0.0.0.0 --port 4004 --reload
```

続いて、別ターミナルを起動させてreactの準備をします。ディレクトリ移動後にpackageをインストールします。

```bash
docker exec -it kibana-api /bin/bash
cd /opt/react
npm install
```

起動前に.envのIP部分を変更します。
```abl:.env
PORT=4003
REACT_APP_API_URL=http://x.x.x.x:4004  # x.x.x.xを自身の環境に合わせる。
```

Reactを起動します。
```bash
npm start
```

# 4. 動作確認
それでは、ブラウザからアクセスします。URLに *http://ipaddoress:4003* を入れてください。以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/ebc6d26f-7db9-9213-885f-84758004d2b9.png)

グラフを追加ボタンをクリックすると、以下のようにポップアップが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/81515ea4-3b66-c4f9-79bb-9dba98c449d9.png)

- APIエンドポイント：ここにはFastAPIのエンドポイントURLを入れます
- グラフは3種類(折れ線グラフ/棒グラフ/円グラフ)のどれかを選択します
- タイトルはわかりやすい名前を入れます

APIエンドポイントは１つだけとなりますので、以下のように設定してください。

**http://ipaddress:4004/api/timeseries**

追加すると、以下のように表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/c21fe4d8-b9a0-676a-29e0-dabfd491d103.png)

編集ボタン（鉛筆マーク）をクリックすると一度作成グラフを変更することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/6ace951c-d269-9a96-a400-72b72eb88dd2.png)

削除ボタン（バケツマーク）をクリックするとグラフを削除できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/51ea1896-9be2-22e6-e4b6-384ae8af37c1.png)

また、好きな位置にグラフも動かせます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2335933/2eb892e9-a316-6e06-c3a9-dacb178984a0.png)


保存ボタンを押すとブラウザ再起動しても登録されたデータが表示されます。

# 5. その他
実データを返却するAPIを準備すれば、生きたグラフになると思います。Kibanaのビジュアライズのように細かい値まで設定することはできておりませんが、APIからデータを引っ張ってきてダッシュボードに表示させるぐらいであればこれでも十分かなと思いました。それとグラフ情報保存・リロード後の表示まではできていますが、位置情報まで正確に保存できていませんのでこのあたり追々という事で。