Nwht0xn1

cal-heatmapで草を生やすCreated on 2016-05-03 by r7kamura

この記事は何?

ユーザページに草が生えるようになりました - WikiHub Help で使ったcal-heatmapというライブラリについての説明。

cal-heatmap

cal-heatmapという、d3.jsを使ってGitHubのContribution Graphのような機能を実装するためのJavaScriptのライブラリがある。ソースコードはwa0x6e/cal-heatmap、ドキュメント付きの公式サイトは http://cal-heatmap.com/ にある。

必要なコードの読み込み

cal-heatmapそれ自体のJavaScriptとCSS、及びcal-heatmapの利用している外部ライブラリであるd3.jsを読み込むと利用できる。ドキュメントで、CDNを経由して読み込む場合はこういう風にしましょうと説明している項目にはこうあるので、簡単に試すにはまずこれから試すのが良い。

<script type="text/javascript" src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="//cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.min.js"></script>
<link rel="stylesheet" href="//cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.css" />

ちなみに自分の場合はRailsアプリでnpmを使っているという環境で、こういう感じにしたので参考までに。

npm install cal-heatmap --save
// app/assets/stylesheets/application.scss
@import "cal-heatmap/cal-heatmap";
// app/assets/javascripts/applicaiton.js
//= require "cal-heatmap/node_modules/d3/d3.min.js"
//= require "cal-heatmap"

グラフの描画

Basic Usageの項目を見るとこうある。

<div id="cal-heatmap"></div>
<script type="text/javascript">
    var cal = new CalHeatMap();
    cal.init({});
</script>

これで空のグラフが描画される。これグラフの一部がなんか黒いのはキャプチャ時にミスってマウスオーバーしてたからですね…

image

描画先の変更

デフォルトで #cal-heatmap というセレクタに一致する最初の要素が利用されるが、これは CalHeatMap#init に渡す引数のオブジェクトに itemSelector を指定すれば設定できる。この情報は、ドキュメントを上から読んでいけばかなり早いところで紹介されている。

cal.init({ itemSelector: ".your-favorite-selector" });

データの読み込み

さて、次はデータを読み込む必要がある。cal-heatmapでは基本的にはXHR経由でデータを読み込むことが想定されており、dataオプションにURLを指定すると、そのURLからデータを取得しようとする。しかし、dataプロパティにUnixtimeをキー、出現回数を値とするオブジェクトを渡せば、それをデータとして利用してくれるようにもなっているので、これが利用できる。

cal.init({
  data: { "1462234684": 3, "1462114800": 2, "1462028400": 4 },
  itemSelector: ".your-favorite-selector"
});

これでデータが読み込まれるようになる──

表示単位の変更

と思いきやグラフの表示が何も変わらないが、表示単位をデフォルトのものから月ごとの表示に変更すると、確かにデータが読み込まれていることが分かるようになる。

cal.init({
  data: { "1462234684": 3, "1462114800": 2, "1462028400": 4 },
  domain: 'month',
  itemSelector: ".your-favorite-selector"
});

image

仕上げ

あとはX軸のラベルを変えたり、データをdata属性経由で読み込むようにしたり、.js-contribution-graph という要素が現れるときだけ処理をするように変更したり、と細々とした処理を雑に書いた。今回はあまりコードは作り込まずにjQueryで適当に書いた。

jQuery(function ($) {
  $('.js-contribution-graph').each(function () {
    var now = new Date();
    new CalHeatMap().init({
      data: $(this).data('activities'),
      domain: 'month',
      domainLabelFormat: '%Y-%m',
      itemSelector: '.js-contribution-graph',
      start: new Date(now.getFullYear(), now.getMonth() - 9)
    });
  });
});

image

以上でひとまず完成。更に細かい調整も色々できるみたいなのでドキュメントを見てやっていきましょう。