GeoChart：1000人あたりPCR検査数で都道府県を塗り分ける


Google ChartsのGeoChartを利用して、1000人あたりPCR検査数に応じて地図上で都道府県の色を塗り分ける。

## ソースコード

```html
<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div>
      <select id="dividend" onchange="drawMap()">
        <option value="patients">確定患者数</option>
        <option value="tests" selected>PCR検査数</option>
        <option value="doctors">医師数</option>
        <option value="population">人口（千人）</option>
      </select>
      <select id="divisor" onchange="drawMap()">
        <option value="patients">÷確定患者数</option>
        <option value="tests">÷PCR検査数</option>
        <option value="doctors">÷医師数</option>
        <option value="population" selected>÷人口（千人）</option>
        <option value="nothing"></option>
      </select>
    </div>
    <div id="app"></div>

    <script
      type="text/javascript"
      src="https://www.gstatic.com/charts/loader.js"
    ></script>

    <script>
      const patients = {
        愛知: 932, 愛媛: 84, 茨城: 239, 岡山: 59, 沖縄: 186, 岩手: 0, 岐阜: 220, 宮崎: 36, 宮城: 140, 京都: 586, 熊本: 58, 群馬: 179, 広島: 250, 香川: 45, 高知: 78, 佐賀: 66, 埼玉: 2035, 三重: 63, 山形: 75, 山口: 47, 山梨: 85, 滋賀: 152, 鹿児島: 203, 秋田: 17, 新潟: 92, 神奈川: 2206, 青森: 31, 静岡: 119, 石川: 310, 千葉: 1453, 大阪: 2915, 大分: 60, 長崎: 47, 長野: 88, 鳥取: 6, 島根: 28, 東京: 10975, 徳島: 12, 栃木: 151, 奈良: 200, 富山: 235, 福井: 127, 福岡: 1292, 福島: 86, 兵庫: 941, 北海道: 1377, 和歌山: 116
      };

      const tests = {
        愛知: 16828, 愛媛: 2799, 茨城: 6442, 岡山: 2579, 沖縄: 6226, 岩手: 1290, 岐阜: 8608, 宮崎: 1868, 宮城: 5534, 京都: 14909, 熊本: 4607, 群馬: 7310, 広島: 10572, 香川: 4213, 高知: 2179, 佐賀: 2108, 埼玉: 56423, 三重: 3571, 山形: 2851, 山口: 3552, 山梨: 6805, 滋賀: 3848, 鹿児島: 9099, 秋田: 1054, 新潟: 5858, 神奈川: 16219, 青森: 1317, 静岡: 10472, 石川: 3112, 千葉: 25929, 大阪: 60635, 大分: 6001, 長崎: 5671, 長野: 5565, 鳥取: 2283, 島根: 2181, 東京: 156867, 徳島: 1518, 栃木: 12024, 奈良: 7978, 富山: 4874, 福井: 4539, 福岡: 21128, 福島: 9030, 兵庫: 21956, 北海道: 26689, 和歌山: 5599
      };

      const doctors = {
        愛知: 16894, 愛媛: 3773, 茨城: 5682, 岡山: 6088, 沖縄: 3589, 岩手: 2673, 岐阜: 4416, 宮崎: 2810, 宮城: 5792, 京都: 8847, 熊本: 5310, 群馬: 4654, 広島: 7609, 香川: 2852, 高知: 2308, 佐賀: 2383, 埼玉: 12928, 三重: 4159, 山形: 2614, 山口: 3675, 山梨: 2016, 滋賀: 3386, 鹿児島: 4545, 秋田: 2413, 新潟: 4727, 神奈川: 20254, 青森: 2712, 静岡: 7948, 石川: 3430, 千葉: 12586, 大阪: 25552, 大分: 3283, 長崎: 4300, 長野: 5035, 鳥取: 1828, 島根: 2050, 東京: 45392, 徳島: 2552, 栃木: 4592, 奈良: 3582, 富山: 2808, 福井: 2057, 福岡: 16310, 福島: 3993, 兵庫: 14463, 北海道: 13425, 和歌山: 2915
      };

      const population = {
        愛知: 7537, 愛媛: 1352, 茨城: 2877, 岡山: 1898, 沖縄: 1448, 岩手: 1241, 岐阜: 1997, 宮崎: 1081, 宮城: 2316, 京都: 2591, 熊本: 1757, 群馬: 1952, 広島: 2817, 香川: 962, 高知: 706, 佐賀: 819, 埼玉: 7330, 三重: 1791, 山形: 1090, 山口: 1370, 山梨: 817, 滋賀: 1412, 鹿児島: 1614, 秋田: 981, 新潟: 2246, 神奈川: 9177, 青森: 1263, 静岡: 3659, 石川: 1143, 千葉: 6255, 大阪: 8813, 大分: 1144, 長崎: 1341, 長野: 2063, 鳥取: 560, 島根: 680, 東京: 13822, 徳島: 736, 栃木: 1946, 奈良: 1339, 富山: 1050, 福井: 774, 福岡: 5107, 福島: 1864, 兵庫: 5484, 北海道: 5286, 和歌山: 935
      };

      const provinces = [
        "愛知", "愛媛", "茨城", "岡山", "沖縄", "岩手", "岐阜", "宮崎", "宮城", "京都", "熊本", "群馬", "広島", "香川", "高知", "佐賀", "埼玉", "三重", "山形", "山口", "山梨", "滋賀", "鹿児島", "秋田", "新潟", "神奈川", "青森", "静岡", "石川", "千葉", "大阪", "大分", "長崎", "長野", "鳥取", "島根", "東京", "徳島", "栃木", "奈良", "富山", "福井", "福岡", "福島", "兵庫", "北海道", "和歌山"
      ];

      const options = {
        region: "JP",
        displayMode: "regions",
        backgroundColor: "#ebf7fe",
        resolution: "provinces",
        colors: ["white", "green"]
      };

      function divideOrGetData() {
        let dt = {
          patients: patients,
          tests: tests,
          doctors: doctors,
          population: population
        };

        let dividend = document.getElementById("dividend");
        let divisor = document.getElementById("divisor");
        let data = provinces.map(province => [
          province,
          dt[dividend.value][province] /
            (divisor.value === "nothing" ? 1 : dt[divisor.value][province])
        ]);
        let dividendText = dividend.options[dividend.selectedIndex].text;
        let divisorText = divisor.options[divisor.selectedIndex].text;
        data.unshift(["都道府県", dividendText + divisorText]);

        // console.log(data);
        return data;
      }

      function drawMap() {
        let data = google.visualization.arrayToDataTable(divideOrGetData());
        let chart = new google.visualization.GeoChart(
          document.getElementById("app")
        );
        chart.draw(data, options);
      }

      google.charts.load("current", {
        packages: ["geochart"]
      });
      google.charts.setOnLoadCallback(drawMap);
    </script>
  </body>
</html>
```

## 実行結果

https://rtte4.csb.app/
<img width="774" alt="スクリーンショット 2020-07-30 17.16.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368897/321a34bc-1f58-904f-48be-6a4df9f7e32f.png">
おまけ： 1000人あたり確定患者数
<img width="774" alt="スクリーンショット 2020-07-30 17.17.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368897/c1297d1b-7026-491e-04f0-daad7358fd31.png">

## リンク

公式ドキュメント
Visualization: GeoChart  |  Charts  |  Google Developers
https://developers.google.com/chart/interactive/docs/gallery/geochart

データ
https://www.mhlw.go.jp/stf/seisakunitsuite/newpage_00016.html
https://www.e-stat.go.jp/

- 厚生労働省　地域ごとの感染状況等の公表について　（2020/07/25）
- 社会・人口統計体系　→　都道府県データ / 基礎データ　→　Ａ　人口・世帯 （2018年度）
- 医師・歯科医師・薬剤師統計　→　医師・歯科医師・薬剤師統計 / 平成30年医師・歯科- 医師・薬剤師統計/ 統計表　→　27 医師数，主たる従業地による都道府県－指定都市・特別区・中核市（再掲）、主たる業務の種別（2018年）