見出し画像

【Click/Adalo】Quick ChartAPIでスプレッドシートからグラフを作ってみた

(なぜこれを書いたか)
ClickにはAdaloのようなグラフを作成する機能が無いので私はグラフ作成にQuickChart APIを使っています。非常に高機能で使いきれない部分も多いのですが、今回はスプレッドシートのデータからグラフを作る方法をご紹介します。(こんな便利な方法があったのかと驚き、備忘録として作成しました。自分用に書いたので分かりにくい部分があるかも知れません)

使うのはClickとGoogleスプレッドシートとスプレッドシートAPI(Stein)、QuickChartAPIの4つです。データの流れとしてはClickからデータをスプレッドシートAPIを経由してスプレッドシートに送ります。スプレッドシートのデータをもとにQuickChartAPIでグラフを作成します。

作ったグラフはURLの形で指定できるので、それをClickにWebViewを使って取り込むという流れになります。

1.こんなグラフを作ります

健康管理アプリというのを作ります。ユーザーが毎日の体重、血圧等を入力し、カスタムリストで時系列に一覧表にして、それをグラフ化します。

①データ入力画面
ホーム画面で入力をして、同じ画面の下の方に入力した数値が一覧で表示されます。ホーム画面に下の方に体重と血圧のグラフにジャンプできるアイコンを配置してあります。

②血圧のグラフ
血圧は低い値(青のグラフ)と高い値(赤のグラフ)の両方が同じグラフに示されています。グラフの横軸は日付で、左端が一番最新の日で右に行くほど過去にさかのぼるようになっています。(通常のグラフと逆のような気もしもしますが、何か月もデータをずっと入力していくので最新の入力データが左端に表示されていた方が見やすいだろうと思ってそうしています)

ホーム画面からデータを1個入力すると点が一つ増えるという動きになります。

③体重のグラフ
毎日の体重を記録するグラフで、データは1種類になります。血圧のグラフと同様に左端が最新のデータになります。

2.スプレッドシートAPIの設定

①Stein(シュタイン)というスプレッドシートAPIを使ってみる
NoCodeアプリからデータをスプレッドシートに送る際に直接やり取りが出来ないのでスプレッドシートAPIを経由してデータを送るようにします。

スプレッドシートAPIはいろいろな種類があります。私はSheetDBというAPIをよく使うのですが、無料範囲だと2個までしかAPIが作れません。今回は作成可能API無制限という太っ腹なSteinというスプレッドシートAPIを使います。(SteinのWebサイトは下記URL)

②新規のAPI-Keyを作成する
SteinのDashBoardで「New API from Sheet」というボタンを押してAPI-Keyを取得します。

~スプレッドシートのURLの入力~
スプレッドシートのURL(全部)をコピーして下記画面の部分にペーストします。

~APIのURLを取得~
下記画面のAPI URLという部分にAPIにアクセスするためのURLが表示されるのでこれをコピーしておきます。URLは以下のような構造になっています。
「https://api.steinhq.com/v1/storages/{API-Key}」

(注意点)
~URLにシート名を追加する~

Steinの場合はAPIのURLにスプレッドシートのどのシート(タブ)にアクセスするか指定する必要があります。例えば「シート1」にデータを送りたい場合は上記URLの最後にシート名を追加する必要があります。
エラーを防ぐ意味で日本語は使わず英字にした方が無難です。
「シート1」→「sheet1」

最終的なAPIのURL:(sheet1にアクセスする場合)
「https://api.steinhq.com/v1/storages/{API-Key}/sheet1

③スプレッドシートの共有設定を変更する(QuickChartAPIを使う時だけ)
Steinを使う場合は本来スプレッドシートの共有設定を変更する必要はありません。但し、今回QuickChartAPIを使ってグラフを作る場合に限り、共有設定を「リンクを知っている全員」に変更する必要があります。
(ここは忘れやすいのでご注意ください)下記画像参照

3.Clickからスプレッドシートにデータ転送

今回、データはすべてスプレッドシートに転送し、Click内部のデータベースは作りません。その代わり「外部データベースを追加」というボタンを押してスプレッドシート内のデータを読み込みます。(下記画像の「健康管理」という部分が外部データーベースです。)

①ホーム画面の作り方
今回のアプリではホーム画面にデータの入力とデータの一覧表示という2つの機能を持たせました。

データ入力にはインプットを配置し、日付の部分だけはDatePickerを使いました。
(当初、日付は入力項目とせず、自動入力にしていたのですが、入力を忘れて次の日、入れることもあるかと思い、DatePickerで手動入力にしました。)

②ボタンにカスタムClickFlowを設定
インプットとDatePickerのデータをスプレッドシートAPIに飛ばすためにカスタムClickFlowを設定します。(下記画像参照)

「新カスタムClickFlow」を選択すると画面がGeneral APIの設定に変わります。

③General APIの設定
下記の設定画面が出てくるので変数を設定し、JSON形式の転送データを作ります。(データはPOSTで送ります)

今回変数になるのは「日付」、「体重」、「血圧(低)」、「血圧(高)」、「脈拍」の5つです。

画面右下の「変数の追加」でこの5つの値を変数として登録します。その際にテストでスプレッドシートにデータを転送するので実在するテスト値を設定しておきます。

画面左中央の「設定」の部分でこれらの変数をパラメータとして保存します。

最後に画面左下の「INPUTデータ」で転送するデータをJSONの形式で入力します。スプレッドシートAPIによってこの部分は入力の仕方が異なるので説明資料をよく読んでその通りに設定して下さい。

APIのURL部分:
上記で説明したSteinのAPI URLを入力します。URLの最後には必ずアクセスするシート(タブ)の名称を追加して下さい。

「https://api.steinhq.com/v1/storages/{API-Key}/sheet1

~テストボタンで動作確認する~
設定が終わったら画面下部の「テスト」ボタンを押して動作確認します。「変数の追加」で登録した試験値が実際にスプレッドシートに送信されます。うまく行くと下記のような「応答データ」という画面が表示されます。

この後は画面下部の「データの更新」ボタンを押して設定したデータを保存します。

④ClickFlowの設定
General APIの設定が終わってホーム画面に戻り、ボタンを選択してClickFlowを見るとGeneral APIで名前を付けた「健康管理」という設定が表示されます。

日付、体重、血圧、脈拍などのデータはインプット1~4、日付入力(DatePicker)と紐づけて下さい。

⑤データの入力と転送
上記の設定が終了してホーム画面のボタンを押すと以下の画像のような形でデータがスプレッドシートに転送されます。

4.スプレッドシートのデータをClickで読み込む

上記の設定によりスプレッドシートAPI経由でClickからスプレッドシートにデータが転送されました。(スプレッドシートにデータベースが出来たという事です)今度はそのデータをClick側で読み込み、カスタムリストで表示してみます。

①外部データの読み込み
データベースを開き一番下にある「外部データベースを追加」ボタンをクリックします。するとGeneral APIの画面がまた開きます。

②General APIの設定
スプレッドシートAPI(今回はStein)のURLを入力して、画面下部の「プレビュー&エラーチェック」ボタンを押します。
うまくいくと下図のように右側画面に取得したデータが表示されます。

③外部データベースの保存
画面下部の「保存」ボタンを押して設定を保存します。するとデータベースの設定画面に先ほど保存した「健康管理」という項目が表示されます。
クリックすると中身の項目が見られます。
(注:この時点ではデータベースの中身までは見ることが出来ません。)

④カスタムリストでデータベースの内容を表示
ホーム画面にカスタムリストを配置し、このリストと先ほど保存した外部データベース「健康管理」を紐づけます。

するとスプレッドシートから読み込んだデータがカスタムリスト上で表示することが出来るようになります。(どの項目を表示するかはテキストエレメントと外部データベースの関連付けの所で設定します。)

(ここまでで何が出来るようになったか?)
ホーム画面のボタンを押すと入力したデータがカスタムClickFlowによってスプレッドシートAPIに飛んでいき、最終的に指定したスプレッドシートに書き込まれます。

スプレッドシートに転送されたデータはClickの外部データベースの読み込みによって読み込まれ、ホーム画面のカスタムリスト上に表示されます。

5.グラフの作成

Clickからスプレッドシートに送ったデータをもとにQuickChart APIでグラフを作成します。

(グラフの作り方)
QuickChartAPIにはスプレッドシートと連携してグラフを作る機能があります。具体的にはスプレッドシートのシートIDを取得し、それを所定の書式に入れ込んでやるとグラフが出来るというイメージです。(下記URL参考)

(グラフ例):体重のグラフ

QuickChartAPIは他のAPIと違って、必要なデータをURLに入れ込んでそれを作成されるグラフをブラウザーで表示するというちょっと特殊な使い方をします。
(注意点)
~スプレッドシートの共有設定変更~
QuickChartAPIをスプレッドシートと連携してグラフを作る場合は、スプレッドシートの共有設定を必ず「リンクを知っている全員」に変更して下さい。これをやらないとエラーになります。
(最初、これを知らずにやっていたので何度やってもエラーが出て、挫折しそうになった。)

(例題1)
上記の折れ線の体重グラフは以下のようなURLを作ります。イメージで言うと「https://quickchart.io/chart?&c=」にJSONで送るデータを接続したURLを作ればそれがAPIのURLだということです。

https://quickchart.io/chart?w=175&h=150&c=
{
type: 'line',
data: {
datasets: [
{
label: '体重 (Kg)',
fill:false
},
]
},
options: {
plugins: {
googleSheets: {
docId: '1p0MyjSv8TgCevl0Xp8cIBg-wi526G7JVMoIJZHUtVE8',
sheet: 'sheet1',
labelColumn: 'date',
dataColumns: ['weight'],
}
},
}
}」

(説明)
①スプレッドシートとの連携

docIDの後ろの'1p0MyjSv8TgCevl0Xp8cIBg-wi526G7JVMoIJZHUtVE8'がスプレッドシートのIDになります。' 'で囲ってやります。

(例題2)
血圧のグラフ

これは同じ画面に血圧_低と血圧_高の2種類のグラフが入っています。QuickChartは複数のグラフが混在するようなグラフも作ることが出来ます。

(2種類の血圧グラフのURL)

https://quickchart.io/chart?w=250&h=250&c=
{
type: 'line',
data: {
datasets: [
{
label: '血圧(低)',
borderColor:'rgb(54,162,235)',
borderWidth:1,
order: 2,
fill:false
},
{
type: 'line',
label: '血圧(高)',
borderColor:'rgb(255,99,132)',
borderWidth:1,
order: 1,
fill: false,
}
]
},
options: {
plugins: {
googleSheets: {
docId: '1p0MyjSv8TgCevl0Xp8cIBg-wi526G7JVMoIJZHUtVE8',
sheet: 'sheet2',
labelColumn: 'date',
dataColumns: ['pressure_low', 'pressure_high'],
rows:{limit : 60},
}
},
}
}」

(説明入り)
https://quickchart.io/chart?w=250&h=250&c=・・・wとhはグラフの幅と高さ(Pix単位)
{
type: 'line',・・・・折れ線グラフがline、棒グラフならばbar
data: {
datasets: [
{
label: '血圧(低)',・・・グラフ上部に示すlabel(凡例)の表記
borderColor:'rgb(54,162,235)',・・・グラフの線色(水色)
borderWidth:1,・・・・・・・・・グラフの線の太さ(1が一番細い)
order: 2,・・・・・・・グラフ上部に表示するlabel(凡例)の位置(2が右)
fill:false・・・・・・・グラフの下の領域を色で染めるか染めない(false)か
},
{
type: 'line',
label: '血圧(高)',
borderColor:'rgb(255,99,132)',・・・グラフの線色(赤)
borderWidth:1,
order: 1,・・・・・・グラフ上部に表示するlabel(凡例)の位置(1が左)
fill: false,
}
]
},
options: {
plugins: {
googleSheets: {・・・・グーグルシートからデータを取得しているの意味
docId: '1p0MyjSv8TgCevl0Xp8cIBg-wi526G7JVMoIJZHUtVE8',・・・スプレッドシートのシートID部分
sheet: 'sheet2',・・・・データを読み込むシートを指定
labelColumn: 'date',・・・スプレッドシートのラベル列(X軸になる列)
dataColumns: ['pressure_low', 'pressure_high'],・・・データ表示列(Y軸方向の値)
rows:{limit : 60},・・・・データが多数ある場合、最初の60個を表示。最後から60個なら-60とマイナスを付ける。
}
},
}
}」

(QuickChartで作ったグラフの特徴)
Clickにグラフの画面を作り、WebViewエレメントを配置し、上記のグラフのURLを設定してやればグラフが表示されます。これは固定の静的なグラフではなく、データを追加すればそのデータもグラフに追加になる動的なグラフです。

6.このアプリ作成の注意点

今回のアプリ作成で主に以下の3点に関して悩みました。現在は解決出来ていますのでやり方を以下で説明します。

1.データを送信してもそれがリストに反映されない
2.Clickのリストのデータの並びが古い順にしか並ばない
3.グラフの範囲が巨大になり過ぎて表示できなくなる

①データを送信してもそれがリストに反映されない
~再読み込み(リロード)の設定をする~

スプレッドシートを使う場合はこれが一番問題になるのではないでしょうか?ホーム画面のボタンを押してデータをスプレッドシートに送信してもその内容がカスタムリストに反映されないのです。

いろいろいじっていたら別の画面に遷移し、またホーム画面に戻ってくるとデータの再読み込み(リロード)が行われ、送信したデータがリストに反映されることが分かりました。要は画面の遷移を1回どこかでやって再度ホーム画面に戻るようにすればいいのです。

(データを反映させる手順)
ダミー画面を1つ用意します。ホーム画面のボタンを押したらデータをスプレッドシートに飛ばし、その後にダミー画面に遷移して、また自動でホーム画面に戻るようにします。

下記画像のように「データ送信」ボタンに健康管理とページ移動の2つのClickFlowを設定します。

(自動でダミー画面からホーム画面に戻る設定)
ボタンを押すとホーム画面から一旦、ダミー画面に遷移します。ダミー画面からホーム画面に自動で戻るようにするには以下のようにして「ページ移動」のClickFlowを設定します。

~ダミー画面での設定~
1).ダミー画面の左上の「Dummy」という文字をクリックする
   →画面が青い枠で囲まれて選択状態になる
2).ページ移動のClickFlowを設定(ホームに移動)

(問題その2)
②Clickのリストのデータの並びが古い順にしか並ばない
Clickのカスタムリストのデータの並びがスプレッドシートと同じ並びになってしまい、上が古く、下が新しいという並びになってしまいます。これだと一番新しいデータを見るのにいつも画面をスクロールする必要があるので不便ですよね。

「そんなの簡単じゃん!ソートすればいいだろう」と思われるかも知れません。私も最初そう思いました。でも外部から持ってきたスプレッドシートのデータはソートできないんですよ。

そこで大元のデータをスプレッドシート上でソートすることにしました。現在、データはsheet1にありますが、sheet2を作り、そこに並びを逆にしたデータを入れ、これをClickで読み込むように設定しました。(下記画像)

(データの並びを逆にする手順)
やり方はいろいろあると思いますが、私は簡単にやりたかったのでsheet2のA1セルに以下のQuery関数を入れてソートしました。
=query(sheet1!A:E,"select*order by A desc",1)

説明:
order: データの並び順(order)を変える
by A: A列(日付の列)を基準に並び替える
desc: 降順(descend)の順番で並び替える

(問題その3)
③グラフの範囲が巨大になり過ぎて表示できなくなる

このアプリの難しい点は毎日入力するデータをグラフ化する点です。1週間分のデータをグラフ化するなら何も問題は無いですが、データ範囲が、1ヶ月、3ヶ月、半年、1年と、とてつもなく長くなっていくのでこれをどうやってグラフ化するのか悩みました。

ClickにQuickChartのグラフを表示する時は一応、サイズを設定することになっています。要はグラフの横幅をどうしたらいいかということなんです。
1つのサイズであらゆる期間のグラフをまかなう事は出来ません。

(自分なりの解決方法_その1)
今回作ったアプリではグラフは直近の60日分(2ヶ月)だけ表示することにしました。(表示する期間を限定するという事です)

(設定方法)
QuickChartではデータの範囲が膨大な場合、どこの範囲をグラフ化するかオプションで設定することが出来ます。rows.limitというパラメータがあってこれを使います。
(例)
データの上位60日間分をグラフ化する場合
rows:{limit : 60}・・・・正の数字を付けると最初から数えるの意味

データの下位60日間分をグラフ化する場合
rows:{limit : -60} ・・・・マイナスの数字を付けると後ろから数えるの意味

今回のアプリでは期間設定をrows:{limit : 60}としました。(データの上位60日分)スプレッドシートのデータはQuery関数で新しい順に並び替えたので直近のデータから過去に60日間遡ったデータをグラフ化しました。

(今回のオプション設定例)
options: {
plugins: {
googleSheets: {
docId: '1p0MyjSv8TgCevl0Xp8cIBg-wi526G7JVMoIJZHUtVE8',
sheet: 'sheet2',
labelColumn: 'date',
dataColumns: ['pressure_low', 'pressure_high'],
rows:{limit : 60},
}
},

(自分なりの解決方法_その2)
これはまだやってはいないんですが、アイディアとして以下のようなことも出来ると思います。
期間に応じて例えば4種類のグラフを用意しておいてユーザーが表示する期間に応じてグラフを手動で切り替えるというやり方です。

ドロップダウンで表示期間(1か月、3ヶ月、6か月、1年)等を選び、それに対応するグラフが表示されるというやり方です。株価のグラフを見ていたら同じようなやり方でグラフの表示を切り替えていたのでこれは使えると思いました。

ただ、グラフの種類が体重、血圧、脈拍と3種類あり、表示できる種類も4種類くらい用意するとなると相当面倒なことになるので自分で出来るかなという心配はあります。

グラフを使ってデータを見やすくするというのはアプリを作る上では大切な要素ですが、使いやすいアプリにするためにはなかなかハードルが高いなと痛感した次第です。

ここまで読んでくれた人がいるでしょうか?もしいたら本当に有難いことです。ClickでもAdaloでも何か不明点や書いて欲しい記事があればお気軽にお問合せ下さい。

(過去の投稿)





この記事が気に入ったらサポートをしてみませんか?