静的サイトでグラフ可視化する方法の考察

# やりたい事

仕事などでデータの可視化をする機会があるのですが、**静的サイトホスティングで十分ではないか**と妄想する事が何度かあった為、一回しっかり考察をしてみたいと思います。
こんな考えに至ったのも経験上、可視化案件の大半は下の条件に当てはまる為です。。。

- いわゆるSPA（Single Page Application）で十分。
- データ更新頻度が数分に1回（それより遅い）でよい。
- 可視化（ダッシュボード）だけで十分。分析はいらない。

<br>

:::note info
静的サイトに詳しくは無いため、間違い、情報が古い等あるかもしれません。
「こんな方法もあるよ」というのがあれば教えていただけると助かります。
:::



<br>


# 期待すること

- 低メンテナンス（データ）
- 多少のカスタマイズ性（GUI部分）
- 望めば データ更新頻度1分 を達成することもできる


# 可視化するデータ
Webページのディレクトリ構成は以下のように至ってシンプルです。

```
my_site/
  + data.json
  + index.html
```

<br>

以下のようなjsonファイルを可視化するものとします。

```
(data.json)
{
    "labels": ["A", "B", "C"],
    "values": [10, 20, 30]
}
```

# 静的サイトホスティング 

思いついた方法の内、資料の多さ、値段などを考慮して以下をピックアップして試しました。試してみて感じた長所、短所もあらかじめ付け加えておきます。

|静的サイトサービス|データ更新方法|長所|短所|
|----------------|------------|----|----|
|AWS S3          | バケットにアップロード| ・データUP > グラフ更新が速い（3秒くらい）<br>・他のAWSサービスとの連携できる<br>・Route53(ドメイン)の利用|・お金がかかる|
|Netlify|git push|・無料で使える<br>・ドメイン名をある程度カスタマイズできる|・git pushからグラフ更新まで2,3分必要<br>・上限超えると通知なしに課金|
|Cloudflare Pages|git push|・無料で機能豊富<br>・リクエスト数/帯域無制限|・グラフ表示(JavaScriptの起動？)がやたら遅い|

補足：
- git pushだと遅い、への対応；S3に配置したdata.jsonをJavaScriptのfetch（またはajax）で取ってくる手もある模様（後述）
- 上の方法で、S3 の代わりにCloudflare R2 を使うのも良さそう（試していない）



<br>


# データの可視化について

さて、ここからが本題。
（2023年11月現在、まだまだ考察中なので、考察の都度このポストは更新しようと思います）

可視化には Plotly.js を用います。（Plotlyの詳細は割愛）  
Plotlyにした理由は特にありません。今回はJavaScriptなら何でも良く、google Charts でもなんでも良いです。

可視化スクリプトは以下のような感じです。
一旦クラウドサービス利用料などは度外視して、1分に一回更新するものとします。

```javascript
(index.htmlの一部)
  <div id="my_chart"></div>
  <script>
    setInterval(()=>{ fetch('data.json')
      .then(response => response.json())
      .then(data => {
        var data = [{
          values: data.values,
          labels: data.labels,
          type: 'pie'
        }];    
        Plotly.newPlot('my_chart', data);
      });
    }, 60000);    // 60,000 ms => 1分でグラフ更新
  </script>
```

グラフはなんでも良いですが、とりあえずここでは円グラフとしました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092759/dff493a3-a205-04f9-9994-94c7ed46640c.png)


# 項目ごとに考察
ここでは問題点ごとに対策とうを考察します。
（やりかたや詳細は下にまとめました）

## 多少のカスタマイズ性（GUI)
先にカスタマイズ性に関してですが、

昨今JavaScriptとCSSを用いてタブ表示、スライドショーなどが簡単に達成できるのでこの点は良しとし、ここでは考察しません。

強いて言えば自分が Next.js などの仕組みをあまり知らないので、試してみてから再考察すべきなのかも...。

## 低メンテナンス（データ）
S3 を用いた方法では aws cliや boto3 を用いた方法が取れるので十分低メンテナンスと言えると思います。

Github を経由する方法は git push なので、ちょっとめんどくさいかな、と思ってしまいます。GithubにまつわるCI/CD系の情報もよく知らないので、この辺試せばこちらの方法でも幸せになれるんでしょうか。


## データ更新頻度1分
Netlify などでは git pushしてから2,3分後にグラフが更新されるので、これは少し遅い。（個人的にはこれでも十分な案件が多いと思いますが、一応、更新時間1分を達成する方法は考察したい）


対策
data.json はS3に配置。index.htmlではS3からグラフ化するデータを取得
1. S3バケットでCORSの設定をする
2. index.html で```fetch('｛S3バケットのURL｝data.json')``` とする

これに似たような方法で更新時間1分は十分達成できます。但しS3では料金が発生します。

# 他に考察すべきこと

- データのセキュリティ関係。-> CORSで良い？
- 可視化サイトの認証 -> cognito 使う？

<br>
<br>


# 詳細／やりかた　など
## S3

### 流れ
1. バケットを作成（バケット名はFQDNのドメイン名部分になる）
1. 「パブリックアクセスをすべてブロック」のチェックを外す
1. 作成したバケットを選択 > プロパティ > 
静的ウェブサイトホスティング：有効にする
1. バケットポリシーを編集（下に例を表示）
1. オブジェクト（この例ではindex.htmlとdata.json）をアップロード
1. バケットを選択 > プロパティ > 「静的ウェブサイトホスティング」に表示されているURLをコピーしてWebブラウザからアクセス
｛バケット名｝.s3-website-ap-northeast-1.amazonaws.com	という感じになる

（バケットポリシーの例）
```
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Principal": "*",
			"Effect": "Allow",
			"Action": [
				"s3:GetObject"
			],
			"Resource": [
				"arn:aws:s3:::example＊＊＊＊＊＊.com"
			]
		}
	]
}
```




## Netlify

### 流れ

1. Github でリポジトリ作成(index.htmlとdata.jsonをアップ）
2. GitHubアカウントでnetlifyにログイン
公式サイトhttps://www.netlify.com/からLogin > Log in with GitHub
1. Netlifyでサイトを作成
「Add new site」> Import an existing project > Deploy with Github 
1. （GithubへNetlify インストール）
1. 該当のGithubリポジトリ選択してサイト作成
1. Site overview にURLが表示されている



## Cloudflare Pages

Netlifyとほぼ同じ流れなので割愛。
ただし、Githubアカウントを利用したログインはできないのでCloudflareのアカウントを作成する必要がある。

# 参考にしたページ

https://qiita.com/ShotaOki/items/821ab449fbb1ceeb025a

https://yuaha.org/javascript-_fetch_gets3/

# その他

- GitHubPages は商用利用不可
- GitHub Actionsでpushすると良いらしい？ => Next.js などでビルドすると8~10分くらいかかるらしく、それを節約するために使うらしい。今回は無関係っぽい。