【GAS】AppSheetでグラフを描くために数値データを線形補間する

1135 語
6 分
【GAS】AppSheetでグラフを描くために数値データを線形補間する

はじまり#

リサちゃん avatar
リサちゃん
あーなんだ! このグラフはぁぁぁ
135ml avatar
135ml
おやおや、グラフに良くないことが起きたようだね
リサちゃん avatar
リサちゃん
気に入らん!
135ml avatar
135ml
気に入るようにしてみよう

AppSheetっていうアプリ作成サービスがあります#

「AppSheet」という、ノーコードでアプリを開発できるサービスがあります。

このAppSheetは、なんてったって、Googleスプレッドシートをデータベースにしてアプリを開発することが出来ます。 グラフも作れちゃいます。

グラフをAppSheetで描きたいのだが・・・#

グラフを描いてみる#

早速、AppSheetでグラフを描画してみます。 これは毎日測る、体重と血管年齢のグラフです。ちょっと血管年齢が上がっていますね・・・

次に、このようなデータからAppSheetでグラフを描画してみます。

このように描けました。 うーむ・・・

なんか気に入らない・・・

気に入らないポイント#

何が気に入らないのかと言うと、 このグラフは日々、スクワットをした回数をメモったデータなんですけど、 スクワットは毎日やるわけでは有りません。ちゃんと太ももを休ませる日も作る必要があります。 そのため、スクワットをしない日は、空欄、もしくは0と入力してました。

しかしそうすると、空欄もしくは0までグラフを描画するので、スクワットの回数の遷移を表すグラフとしては見にくいものになってしまいます。 0を描画することは納得なのですが、“空欄”まで0として描画してしまうAppSheetの仕様に、困りました。

未来日のレコード(執筆時点は2024/01/31)を見ると分かりやすいです。空欄が0として入力されていることがわかります。

描くための対策#

そこで、データが0もしくは空欄になっている部分を、線形補間して入力してあげることで、 データの遷移が見やすいグラフを作ることにしました。 そこで、GoogleスプレッドシートをGoogle Apps Scriptで読み込んで、線形補間したデータを表示する処理を作りました。

線形補間する処理#

これがデータを加工する処理のスクリプトです。

/**
* @description Get linear-interpolated values by argued values.
* @param {string[][]} values
* @return {string[][]}
*/
function getLinearInterpolateByColumns(values){
let baseIndices = [];
let nodes = [];
let numOfNodes = 0;
let difference = 0;
let remain = 0;
for(let i = 0; i < values.length; i++){
if(values[i][0] !== 0 && values[i][0] !== ""){
baseIndices.push(i);
}
}
console.log(`${baseIndices}`);
console.log(`${baseIndices.length}`);
console.log(`getLinearInterpolateByColumns: 111111111111111111111111111111111111111111111`);
if(baseIndices.length < 2){
console.log(`getLinearInterpolateByColumns: Not linear-interpolated.`);
console.log(`getLinearInterpolateByColumns: 2222222222222222222222222222222222222222222`);
return values;
}
for(let i = 0; i < baseIndices.length - 1; i++){
if(i === 0){
for(let j = 0; j < baseIndices[i]; j++){
nodes.push(0);
}
console.log(nodes);
console.log(`getLinearInterpolateByColumns: 33333333333333333333333333333333333333333333333`);
}
numOfNodes = baseIndices[i + 1] - baseIndices[i];
difference = values[baseIndices[i + 1]][0] - values[baseIndices[i]][0];
console.log(numOfNodes);
console.log(difference);
console.log(`getLinearInterpolateByColumns: 4444444444444444444444444444444444444444444444444`);
for(let j = 0; j < numOfNodes; j++){
console.log(values[baseIndices[i]][0]);
console.log(difference * j / numOfNodes);
nodes.push(values[baseIndices[i]][0] + difference * j / numOfNodes);
}
console.log(`getLinearInterpolateByColumns: 555555555555555555555555555555555555555555555555555`);
if(i === baseIndices.length - 2){
// remain = baseIndices[i + 1] - baseIndices[i];
remain = values.length - 1 - baseIndices[i + 1];
nodes.push(values[baseIndices[i + 1]][0]);
for(let j = 0; j < remain; j++){
nodes.push(0);
}
}
}
let roundedNodes = nodes.map(node => {
return Math.round(node);
})
let newValues = roundedNodes.map(node => {
return [node];
})
console.log(newValues);
console.log(`getLinearInterpolateByColumns: 999999999999999999999999999999999999999999999999999999`);
return newValues;
}
/**
* @description Get the statement line-broken to display values in the argued arrays.
* @param {string[][]} arrays
* @return {string[][]}
*/
function getStatementLineBrokenToDisplayArrays(arrays, opening){
const sepFirst = ":<br>";
const sep = "<br>";
let outNumberOfStart = arrays[0];
const startOfStatement = `${opening}${sepFirst}${outNumberOfStart}${sep}`;
let statement = arrays.reduce((prev, curr) => {
return `${prev.toString()}${sep}${curr.toString()}`;
});
statement = statement.replace(`${outNumberOfStart}${sep}`, startOfStatement);
return statement;
}
/**
* @description Output linear-interpolated values by argued values.
* @return {boolean}
*/
function outputLinearInterpolate(){
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
let values = sheet.getActiveRange().getValues();
console.log(values);
console.log(`${values}`);
console.log(`outputLinearInterpolate: 111111111111111111111111111111111111111111111`);
if(values[0].length > 1){
throw new RangeError("Length of selected column must be 1.")
}
let newValues = getLinearInterpolateByColumns(values);
console.log(`${newValues}`);
console.log(`outputLinearInterpolate: 222222222222222222222222222222222222222222222`);
let statementBeforeValues = getStatementLineBrokenToDisplayArrays(values, "Before interpolation:");
let statementAfterValues = getStatementLineBrokenToDisplayArrays(newValues, "After interpolation:");
displayHtml("index_html", "Linear-interpolation Terminated...", `<p>${statementBeforeValues}</p><p>${statementAfterValues}</p>`);
console.log(`outputLinearInterpolate: 999999999999999999999999999999999999999999999`);
return true;
}

スプレッドシート上で、線形補間したいセルを選択した状態で、outputLinearInterpolate()を実行するとスプレッドシート上にHTMLが表示されるというわけです。 (HTMLを表示する処理は、displayHtml()が担当しています。)

線形補間前のデータと、

線形補間後のデータを表示します。

表示されたデータをシートに貼り付けて、再描画したグラフを確認する#

そして、表示したデータを貼り付けます。 表示されたテキストを選択して、

貼り付ける。

そして、AppSheet上のグラフを確認します。

んんっ。。

まあ、今回使ったスクワットのデータの上下差が大きすぎて少し見づらいですが、 測定を実施している期間のスクワットの回数が、0になっている日付はありません。 回数の遷移を純粋に描画したグラフとなったことでしょう!

おしまい#

リサちゃん avatar
リサちゃん
まあまあまあ、いいんじゃないでしょうか
135ml avatar
135ml
スクワットへのモチベーションの上下の様子が伝わるグラフになったな。

以上になります!

記事を共有

この記事が役に立ったなら、ぜひ他の人と共有してください!

【GAS】AppSheetでグラフを描くために数値データを線形補間する
https://endorphinbath.com/posts/gas-interpolation-for-appsheet/
著者
kinkinbeer135ml
公開日
2024-01-13
ライセンス
CC BY-NC-SA 4.0
関連記事 スマート
1
【GAS、Google Spreadsheet】Googleドキュメントで日記を付けるために毎日Docファイルを作ってくれるスクリプトです
Code GoogleDriveにあるファイルを毎日決まった時間にコピーしてくれるスクリプトを書きました。日記をつける場合に毎回ファイルをコピーしてレイアウトを変えて・・・といった作業を効率化してしまいましょう!
2
【GAS】Googleカレンダーに曜日を指定してスケジュールを登録するスプレッドシートの構築
Code Google Apps Scriptを使い、スプレッドシートからGoogleカレンダーに曜日指定でスケジュールを追加するシステムを作りました。繰り返し入力する版と個別に入力する版があります。
3
【Google Apps Script】自分がGASで使うIDとかトークンを1つのシートで管理するライブラリを作ろうとしたけど、断念した話
Code Google Apps Scriptで使うフォルダIDやスプレッドシートIDなどを一括管理するライブラリをスプレッドシート上で作ろうと思ったのですが、とある理由により頓挫しました。貴方もお気を付け下さい。
4
【GAS、Google Spreadsheet】ブログに使用した画像をGoogleドライブで管理するために書いたスクリプト
Code 僕は、既に公開した記事で使用したファイルをGoogleドライブの所定のフォルダに保存しています。その画像を完了済みのフォルダに定期的に移動してくれるスクリプトを作りました。
5
【GAS、Google Spreadsheet】TwitterのBotを作成するために認証を行う。
Code Googleスプレッドシートを利用したGASから実行するTwitterのBotを作りました。今回は、そのTwitterに投稿するための認証周りの設定に関する紹介記事になります。
ランダム記事 ランダム
Profile Image of the Author
kinkinbeer135ml
SIerをやめて、プログラミングを勉強しています。※Amazonアソシエイトに参加しています。
お知らせ
私のブログへようこそ!これはサンプルのお知らせです。
音楽
カバー

音楽

再生中なし

0:00 0:00
歌詞なし
カテゴリ
タグ
サイト統計
記事
287
カテゴリー
8
タグ
93
総文字数
486,174
運用日数
0
最終活動
0 日前

目次