今回は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などで、動的に取ってこれるといいですね。