japan-map-jsを使用してコロナのデータでヒートマップ作ってみた。

  • このエントリーをはてなブックマークに追加

今回はjapan-map-jsを使用してみたので、実装の仕方をメモしておきたいと思います。

他には、D3.jsを使用してカスタムな地図を描画する方法などあると思いますが、お手軽に試すのであれば、japan-map-jsが早いかもしれません。

導入の仕方

まずは導入の仕方。こちらのCDNを使用すればOKだと思います。

<script type="text/javascript" src="https://unpkg.com/japan-map-js@1.0.1/dist/jpmap.min.js"></script>

Railsで行う場合には、以下のように、application.html.erb等で読み込んでおきましょう。

<!DOCTYPE html>
<html>
  <head>
    <title>hoge</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <script type="text/javascript" src="https://unpkg.com/japan-map-js@1.0.1/dist/jpmap.min.js"></script>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

基本

基本はこちらのコードでいけると思います。

const d = new jpmap.japanMap(document.getElementById("japan-map"), {
  areas: [
    {"code" : 1, "color" : "#AA0000" }, // code: 1 => 北海道
    {"code" : 2, "color" : "#00AA00" }, // code: 2 => 青森
  ],
  height: 270,
  lineWidth: 0,
  onSelect: function(data){
    alert(data.name);
  }
})

htmlにjapan-mapというidの要素を作っておきます。

<div id="japan-map"></div>

今回のコード

// 今回ヒートマップで表現する数値データを定義している部分
// ゆくゆくはデータベースやcsvファイルから動的に取得する
function defineData(){
  const data = {
    "date" : "2020/08/27",
    "total_patient_person_number": 65769,
    "new_patient_person_number": 865,
    "prefectures" : [10,2,0,1,0,0,7,8,1,18,69,45,250,66,1,8,13,13,0,6,2,12,39,6,5,27,94,22,4,0,0,0,1,1,6,4,0,0,0,64,2,7,6,1,1,2,36]
  }
  return data
}

// 表示する色を作っている部分
function prefecturesConvertRGB(prefecture){
  function heatMapColorforValue(value){
    var h = (1.0 - value) * 240
    return "hsl(" + h + ", 100%, 50%)";
  }
  return heatMapColorforValue(prefecture)
}

// 今回の数値データを0〜1の範囲に変換している部分
function nomalizePrefectures(prefectures, new_patient_person_number){
  const max = Math.max(...prefectures)
  const prefs = prefectures.map(function(x){
    return x / max;
  })
  return prefs
}

// {"code": ... , "color": ...}のjsonオブジェクトの配列を作成している部分
function defineAreas(data){
  let areas = []
  const prefectures = nomalizePrefectures(data.prefectures, data.new_patient_person_number)
  for (let i=1;i<=47;i++) {
    areas.push(
      {
        "code": i, 
        "color": prefecturesConvertRGB(prefectures[i-1]) 
      }
    )
  }
  return areas
}

// ヒートマップを表示する部分
function main(){
  const data = defineData()
  const areas = defineAreas(data)
  
  const d = new jpmap.japanMap(document.getElementById("japan-map"), {
    areas: areas,
    height: 270,
    lineWidth: 0,
    onSelect: function(data){
      alert(data.name);
    }
  });
}

main()

今回はSIGNATEのCOVID-19チャレンジ(フェーズ1)から、当日の新規感染者のデータを拝借しました。

COVID-19チャレンジ

https://signate.jp/competitions/260

データセット

https://drive.google.com/drive/folders/1EcVW5JQKMB6zoyfHm8_zLVj—t_hccF

現状は手動で取ってきて記述しなければならないので、google drive apiなどで、動的に取ってこれるといいですね。

  • このエントリーをはてなブックマークに追加

SNSでもご購読できます。

スポンサードリンク

コメントを残す

*