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で帰ってきた値をそのままチャートに流し込めないので、データテーブルを用意し、カラムを用意して流し込んでいます。カラム自体今回のグラフには出てこないのですが、一応設定しておきます。

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)