Google Apps Scriptでサンキーダイアグラムを作る【GAS】
工程間流量図(サンキーダイアグラム)とは、フローチャートのように流れを見ながらも、どちらかというとそのフロー間の流量に注目したグラフであり、要素と要素の間でどれだけの量が流れているのか?に着目するためのものです。通常のフローチャートでは、単純に1本の線で結ばれているだけなのですが、サンキーダイアグラムは、その流量によって、線の太さを変えて表現してくれます。莫大なデータを蓄積・集計し、要素間でどれだけの量が流れているのか?を見るのには最適なチャートです。
今回は、とある病院のから病院への転院人数を集計し、それを流量でグラフ化したものをつくったサンプルです。この他にも、拠点間の物量把握であったり、トラフィックを視覚化したり、いろいろ使い勝手がありそうです。
リンク
今回使用するスプレッドシート他
実行結果
ソースコード
GAS側コード
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
ui.createMenu('▶流量図')
.addItem('セットアップ', 'setup')
.addItem('チャート表示', 'sankyman')
.addToUi();
}
//ウェブアプリケーションでグラフを表示
function doGet() {
var html = HtmlService.createHtmlOutputFromFile('sanky')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('カレンダーチャート')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
return html;
}
//HTML側へデータを返す関数
function datamanrev(){
var Prop = PropertiesService.getScriptProperties();
var ssid = Prop.getProperty("sheetid")
var sheet = SpreadsheetApp.openById(ssid);
var ss = sheet.getSheetByName("data");
var dataman = ss.getRange("A1:C").getValues();
return JSON.stringify(dataman);
}
//スプレッドシート上のダイアログでグラフを表示
function sankyman() {
var html = HtmlService.createHtmlOutputFromFile('sanky')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setWidth(650)
.setHeight(500);
SpreadsheetApp.getUi()
.showModalDialog(html, '流量図のテスト');
}
//セットアップ
function setup(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var sheetId = sheet.getId();
var Prop = PropertiesService.getScriptProperties();
Prop.setProperty("sheetid",sheetId);
SpreadsheetApp.getUi().alert("セットアップ完了");
}
- 使用前にメニューから流量図⇒セットアップを実行して、スクリプトプロパティにシートのIDを格納しましょう。
- 今回はチャート表示を実行すると、スプレッドシート上でもチャートを表示するようにしています。
HTML側コード
<html>
<head>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<style>
svg path:hover {
fill: red;
}
rect {
fill: green;
}
</style>
<script type="text/javascript">
//Visualization APIの呼び出し
google.charts.load('current', {'packages':['sankey'], 'language': 'ja'});
google.setOnLoadCallback(test);
//自動的に呼び出されて実行する関数
function test(){
google.script.run.withSuccessHandler(onSuccess).datamanrev();
}
//データを取得してダイアグラムを生成
function onSuccess(dataman) {
var tempdata = JSON.parse(dataman);
var numRows = tempdata.length
var chart = new google.visualization.Sankey(document.getElementById('chart_div'));
//データテーブルを用意し、配列データを格納する
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'From' });
dataTable.addColumn({ type: 'string', id: 'To' });
dataTable.addColumn({ type: 'number', id: 'Weight' });
//データテーブルにデータを流し込む
var cnt = numRows -1;
for(i=1;i<cnt;i++){
var row = [];
row.push(tempdata[i][0]);
row.push(tempdata[i][1]);
row.push(tempdata[i][2]);
dataTable.addRow(row);
}
//グラフオプションの指定
var options = {
width: 600,
height: 400,
sankey: {
link: { color: { fill: '#F4FA58' } },
node: {
label: { color: '#871b47' },
nodePadding: 20,
},
}
};
//グラフの描画
chart.draw(dataTable, options);
}
</script>
</head>
<body>
<div id="chart_div"></div>
</body>
</html>
- オプション項目が少ないですが、地味に進化しています。現在では4カラム目あたりにツールチップ表示内容などをコメントで残し、それを読み込むなんてこともできるようになっています。tooltipはオプションでtooltip.isHtmlを使うことで、セル内に記述したHTMLをツールチップで表示も可能。
- 今回は、集計をせず作図しているため、ひとつの要素から複数のラインが同じ要素に流れている為、若干グラフとしては見づらいのですが、これらをきちんと集計し1本のグラフに集約することで、より見やすいグラフへと変わると思います。
- また、このグラフは、response.getDataTableで帰ってきた値をそのままチャートに流し込めないので、データテーブルを用意し、カラムを用意して流し込んでいます。カラム自体今回のグラフには出てこないのですが、一応設定しておきます。
