Google Chartsで地図データを表示する(Geo Charts)

## はじめに
Googleスプレッドシートに読み込み元のデータを用意し、それをGoogle ChartsでWeb表示してみたいと思います。
今回は、地図に描画してわかりやすい**世界の平均寿命**を表示してみたいと思います。

- 公式サイト：https://developers.google.com/chart
- GeoChart参考：https://developers.google.com/chart/interactive/docs/gallery/geochart

## 使用技術 / 前提条件
- JavaScript
- Google SpreadSheet API
- Google MAP API KEY

## データ内容
・Googleスプレッドシートに、世界の平均寿命ランキングの上位20カ国、下位20カ国を用意(2020年：WHO)
（参考サイト：https://memorva.jp/ranking/unfpa/who_whs_population.php）
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/f6c19ef0-b252-e8e4-26d9-476fb00d4805.png)

## 作成サイト
[デモサイトはこちら](https://anotherskyjp.site/devapps/otherpg/06_googleGeoChart/geochart.html)

Googleスプレッドシートに用意したデータをマップ表示し、かつ順位がわかりやすいようにテーブルにも出力します。

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/4ac245a6-cb59-ae10-6297-0f23a8c13736.png)

## コード
- Googleスプレッドシートからのデータ読み込みと地図表示部分

~~~ function.js
      google.charts.load('current', {
        'packages':['geochart'],
        'mapsApiKey': 'APIキーを設定'
      });

      google.charts.setOnLoadCallback(drawRegionsMap);

      function drawRegionsMap() {
        // Google APIにてスプレッドシートデータを取得する
        const request = new XMLHttpRequest();
        const bookid = 'bookidを設定';
        const sheetname = 'シート名を設定';
        const url = 'https://sheets.googleapis.com/v4/spreadsheets/' + bookid + '/values/' + sheetname + '?key=APIキーを設定';

        request.open('GET', url, true);
        request.responseType = 'json';

        request.onload = function () {
          // 取得できた値を格納
          const rdata = this.response;

          // MAP:データ変換
          let flg = 1;
          const mdata = parseData(rdata, flg);

          // MAP:データセット
          const data = google.visualization.arrayToDataTable(mdata);

          // MAP:オプション設定
          const options = {
            // region: '155',
            // displayMode: 'markers',
            // colorAxis: {colors: ['#e7711c', '#4374e0']}
          };

          // MAP:セットと描画
          const chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
          chart.draw(data, options);

          // Table:データ変換とテーブル描画
          flg = 2;
          const tdata = parseData(rdata, flg);
          drawTable(tdata);

        };
        request.send();
      };
~~~

- 全体のコード

<details><summary>全体のコード</summary>
<div>

~~~ GoogleGeoChart.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <title>Google GeoChart</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
  </head>

  <body>
    <div class="container">
      <br>
      <h3>世界の平均寿命(2020)</h3>
      <p><a href="https://memorva.jp/ranking/unfpa/who_whs_life_expectancy.php" target="_blank">出典：平均寿命(WHO版) </a></p>
      <br>
      <div>上位・下位を20カ国表示</div>
      <br><br>
      <div class="container">
        <div id="regions_div"></div>
      </div>
      <br><br>
      <div class="container">
        <div id="result"></div>
      </div>
    </div>

    <script src="https://www.gstatic.com/charts/loader.js"></script>
    <script src="https://code.jquery.com/jquery-2.1.1.js" integrity="sha256-FA/0OOqu3gRvHOuidXnRbcmAWVcJORhz+pv3TX2+U6w=" crossorigin="anonymous"></script>

    <script>
      google.charts.load('current', {
        'packages':['geochart'],
        'mapsApiKey': 'APIキーを設定'
      });

      google.charts.setOnLoadCallback(drawRegionsMap);

      function drawRegionsMap() {
        // Google APIにてスプレッドシートデータを取得する
        const request = new XMLHttpRequest();
        const bookid = '15RXRhrJuoXJbpoCu9K_eX67yTlaIOjOXRG-JTuvEWjM';
        const sheetname = 'data';
        const url = 'https://sheets.googleapis.com/v4/spreadsheets/' + bookid + '/values/' + sheetname + '?key=APIキーを設定';

        request.open('GET', url, true);
        request.responseType = 'json';

        request.onload = function () {
          // 取得できた値を格納
          const rdata = this.response;

          // MAP:データ変換
          let flg = 1;
          const mdata = parseData(rdata, flg);

          // MAP:データセット
          const data = google.visualization.arrayToDataTable(mdata);

          // MAP:オプション設定
          const options = {
            // region: '155',
            // displayMode: 'markers',
            // colorAxis: {colors: ['#e7711c', '#4374e0']}
          };

          // MAP:セットと描画
          const chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
          chart.draw(data, options);

          // Table:データ変換とテーブル描画
          flg = 2;
          const tdata = parseData(rdata, flg);
          drawTable(tdata);

        };
        request.send();
      };

      // Function:データ変換
      function parseData(rdata, flg) {
        const parsegraphData = [];
        let setValue;

        if (flg == 1) {

          rdata.values.forEach(function(value, i) {
            if (i == 0) {
              setValue = [rdata.values[i][2], rdata.values[i][3]];
            } else {
              setValue = [rdata.values[i][2], Number(rdata.values[i][3])];
            };
            parsegraphData.push(setValue);
          });

        } else if (flg == 2) {

          rdata.values.forEach(function(value, i) {
            if (i > 0) {
              setValue = rdata.values[i];
              parsegraphData.push(setValue);
            };
          });

        };
        return parsegraphData;
      };

      // テーブルの描画
      function drawTable(tdata) {

        let html = '<table class="table">' +
                  '<thead class="thead-light">' +
                  '<tr><th scope="col">順位</th>' +
                  '<th scope="col">国</th>' +
                  '<th scope="col">Country</th>' +
                  '<th scope="col">平均寿命</th></tr>' +
                  '</thead><tbody>'

        for(let i = 0; i < tdata.length; i++) {
          html +=
            '<tr>' +
            '<th scope="row">' + tdata[i][0] + '位</th>' +
            '<td>' + tdata[i][1] + '</td>' +
            '<td>' + tdata[i][2] + '</td>' +
            '<td>' + Number(tdata[i][3]) + '</td>' +
            '</tr>';
        };

        html += '</tbody></table>';
        const result = $("#result");

        result.empty();
        result.append(html);
      };
    </script>

  </body>
</html>
~~~

</div></details>

## まとめ
- 外部のデータ読み込んで、簡単に地図にマップすることができました。
- 今回は使っていませんが、オプションも豊富なので細かいところにも対応できるところがすごいところです。
- Google Chartは、グラフや円、バブルなどの定番のチャートから、今回使用した地図(GeoCharts)やどうやって使えばよいかわからないマニアックな種類のチャートまでたくさんありますので、WebでChart関連の表示は、第1候補ではないかなと思います。