目的
Javascriptで自分の体重をグラフ化する(JavascriptからGoogle SpreadSheetをGET/POSTして作成する)際の備忘録です
Google Spread Sheetのデータをget/postする
Google Spread Sheetの準備
以下を参照してGoogleスプレッドシートの内容をWebアプリケーションから取得できる状態にする。
スクリプトからget/post functionを作成
GoogleスプレッドシートのTools→ScriptEditorから、
doGet/doPostでスプレッドシートに対してget/postするコードを作成する。
作成した後はPublish→Deploy as WebAppを選択してURLを取得する。
アクセス権設定は、今回はAnyone even anonymousなどにした(適切に設定する)
const SHEET_ID = 'xxxxxxx'
const SHEET_NAME = 'yyyyyyy'
function getData(id, sheetName) {
var sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);
var rows = sheet.getDataRange().getValues();
var keys = rows.splice(0, 1)[0];
return rows.map(function(row) {
var obj = {}
row.map(function(item, index) {
obj[keys[index]] = item;
});
return obj;
});
}
function doGet(request) {
var func = 'jsondata';
var data = getData(SHEET_ID, SHEET_NAME);
return ContentService.createTextOutput(func + '(' + JSON.stringify(data, null, 2) + ')')
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
function createRow(sheet, parameter) {
var keys = sheet.getDataRange().getValues()[0];
var row = [];
keys.map(function(key) {
var value = parameter[key];
if (value) {
row.push(value);
}
});
return row;
}
function appendRow(sheet, parameter) {
var row = createRow(sheet, parameter);
sheet.appendRow(row);
}
function doPost(e) {
console.log(e);
var sheet = SpreadsheetApp.openById(SHEET_ID).getSheetByName(SHEET_NAME);
appendRow(sheet, e.parameter);
}
尚、SHEET_ID/SHEET_NAMEは以下の通り。
const SHEET_ID = 'xxxxxxx' // https://docs.google.com/spreadsheets/d/xxxxxxx/edit#gid=0 の xxxxxxx の部分
const SHEET_NAME = 'yyyyyyy' // シート名
Publish→Deploy as WebAppを選択して取得したURLはJavascriptから指定する。
(https://script.google.com/macros/s/zzzzzzzz/exec などのこと)
JavascriptからGET/POSTリクエスト
フォルダ構成
my_weight.html
my_weight.js
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>自分の体重とか</title>
</head>
<body>
<h1>自分の体重とか</h1>
<div style="width: 50%; height: 50%;">
<canvas id="my_weight" style="width: 100%; height: 100%;"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<script src="./my_weight.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<br><br>
<div style="width:300px; border: 2px solid #000000;">
<form id="my-form">
データ追加<br>
<table>
<tr>
<td>記入日</td><td>><input type="date" name="date" required /></td>
</tr>
<tr><td>体重</td><td>><input type="number" name="weight" step="0.1" required /></td>
</tr>
<tr><td><input type="submit"></td><td id="status"></td></tr>
</table>
<div>
<a href="https://docs.google.com/spreadsheets/d/xxxxxx/edit?usp=sharing">引用元データはこちら</a>
</div>
</form>
</div>
<br><br>
<script>
// ページ読み込み後の処理 -> SpreadSheetからデータを読み込み、canvasに描画
window.onload = function(){
getJsonp_GAS();
}
// 送信ボタンを押した際の挙動 -> SpreadSheetへデータを投稿
$("form").submit( function(){
var valDate = $('#my-form [name=date]').val();
var valWeight = $('#my-form [name=weight]').val();
sendData_GAS(valDate, valWeight);
$("#status").text("送信しました");
return false; // 遷移無効化
});
</script>
</body>
</html>
function drawBarChart(labels, data) {
// 4)chart.jsで描画
var ctx = document.getElementById("my_weight").getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [ {
label: "体重(kg)",
data: data,
backgroundColor: 'rgba(60, 160, 220, 0.3)',
borderColor: 'rgba(60, 160, 220, 0.8)',
fill: true
},
],
},
options: {
scales: {
yAxes: [{
type: 'linear',
ticks: {
beginAtZero: true,
max: 120.0
}
}]
},
}
});
}
// 出力用にlabelを整形
function format_label(date) {
format_str = "YY/MM/DD";
format_str = format_str.replace(/YY/g, -100 + date.getYear());
format_str = format_str.replace(/MM/g, 1 + date.getMonth());
format_str = format_str.replace(/DD/g, date.getDate());
return format_str;
}
function insertionSort(l_lab, l_wei, in_lab, in_weight){
var result = new Object();
result.lab = new Array(0);
result.wei = new Array(0);
var idx;
for (idx = 0; idx < l_lab.length; idx++) {
if(in_lab < l_lab[idx]) {
break;
} else {
result.lab.push(l_lab[idx]);
result.wei.push(l_wei[idx]);
}
}
result.lab.push(in_lab);
result.wei.push(in_weight);
for (let idx2 = idx; idx2 < l_lab.length; idx2++) {
result.lab.push(l_lab[idx2]);
result.wei.push(l_wei[idx2]);
}
return result;
}
// SpreadSheetからデータを受信
function getJsonp_GAS() {
$.ajax({
type: 'GET',
url: 'https://script.google.com/macros/s/zzzzzzzz/exec',
dataType: 'jsonp',
jsonpCallback: 'jsondata',
success: function(json){
var label = new Array(0);
var weight = new Array(0);
// jsonデータを読み込む
for(let i=0; i < json.length; i++){
result = insertionSort(label, weight, new Date(json[i].date), json[i].weight);
label = result.lab; weight = result.wei;
}
// 日付を基準にソート
for(let i=0; i < label.length; i++) {
label[i] = format_label(label[i]);
}
drawBarChart(label, weight);
}
});
}
// SpreadSheetへデータを送信
function sendData_GAS(date, weight) {
var sendData = "date=" + date + "&weight="+weight;
$.ajax({
type: "POST",
crossDomain: true,
url: 'https://script.google.com/macros/s/zzzzzzzz/exec',
data: sendData
});
}
以下を同フォルダで実行してwebサーバを起動した後、
$ python3 -m http.server 8080 --cgi
http://localhost:8080/my_weight.html にアクセスしてグラフが表示されればOK
参考
Googleスプレッドシートの内容をjsonデータとして利用する
Google Apps ScriptのdoPostでJSONなパラメータのPOSTリクエストを受ける
html form not transferring data to google spreadsheets