はじめに
いま、幸せ? nikkieです1。
アイの歌声を聴かせて × エンジニアリングで楽しく手を動かしています。
今回は、『アイの歌声を聴かせて』の鑑賞ログをGitHubのContributionのように表示してみる中で知ったことを記事にします。
以下のツイートのような感じになりました。
エンジニアに馴染み深い形式で表示してみた、私の #アイの歌声を聴かせて 鑑賞ログです。
— nikkie にっきー (@ftnext) 2022年1月5日
エンジニアにはGitHubという設計図共有サイトが浸透していて、そこでの活動ログが以下のような形式になります
これをやるにあたって数えてみたら、2021年で20回観てました(「アイうた好きすぎだろ、ニッキー」 pic.twitter.com/ENMxyaNHQK
目次
- はじめに
- 目次
- 前提:GitHubのContribution
- ライブラリ選定(Cal-heatmapを選択)
- 実装:ドキュメントに沿って
- 設定ポイント
- JSONファイルにまとめたデータを渡そうとしたら・・
前提:GitHubのContribution
エンジニアが設計図やソースコードを公開・共有するのに使うGitHub。
GitHubアカウントのプロフィールには、コントリビューションカレンダーがあります。
これは日毎のコントリビューションを、数が多いほど濃い色で示すというものです。
緑色でカレンダーが塗りつぶされていくので、「草」🌱という名前でも親しまれていますね2。
このコントリビューションカレンダーと同様に、好きな映画(今回は、アイの歌声を聴かせて)の鑑賞回数を表せないかと思ったわけです。
なお、多数派ではないことは承知の上で、私は好きな映画は映画館で何回も見る勢です。
手を動かす中で知ったのですが、「カレンダーで表現したヒートマップ」とも言うようです。
ライブラリ選定(Cal-heatmapを選択)
そもそもどう実現するかというところから分からなかったので、それっぽいワードでGoogle検索するところからスタートです。
調べていくうちに、大変有用なまとめに出会いました。
Github Contributions Graphのようなheatmapを作成したいので、ライブラリを探している。
これといった定番は見つからず、メンテナンスされていないものばかりだった。
リストアップされたものは、ほとんどが「メンテされていない」のですが、私のケースは、サービスとしてリリースしたいわけでなく、一人で楽しめればいいのでメンテされていないライブラリでも試すことにしました。
VueもReactも入門レベルには達していないので、これら向けではないライブラリからCal-heatmapを選びました。
試している記事 cal-heatmapを使ってGithubの草を再現してみる - ソースコードから理解する技術-UnderSourceCode を調査の早い段階で見つけていたのも選択理由です。
※私のフロントエンドのスキルには広大な伸びしろが広がっていることは自覚しているので、お気づきの点あれば知らせてもらえるとありがたいです。
実装:ドキュメントに沿って
Cal-heatmapのドキュメントに沿って、アイの歌声を聴かせての鑑賞回数を示すカレンダーが表示できるように設定していきます。
でき上がったコードはこんな感じ(じゃーん!)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <script type="text/javascript" src="https://d3js.org/d3.v3.min.js"></script> <script type="text/javascript" src="https://cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.min.js" ></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.css" /> </head> <body> <h1>『アイの歌声を聴かせて』鑑賞履歴</h1> <div id="cal-heatmap" style="margin: auto; width: 30%;"></div> <script type="text/javascript"> const cal = new CalHeatMap(); const data = { "1635519600.0": 1, "1635865200.0": 1, }; const config = { domain: "month", subDomain: "day", range: 4, tooltip: true, start: new Date(2021, 9), // start October, 1st 2021 data: data, legend: [0.0, 0.5, 1.0, 1.5], cellSize: 15, subDomainTextFormat: "%d", }; cal.init(config); </script> </body> </html>
設定ポイント
cal.init({})
と空のオブジェクトを渡すだけで、空のカレンダーが表示されます。
カレンダーに渡すデータ(いつに何回)やカレンダーの表示形式は、init
メソッドに渡すオブジェクトで設定できます。
ポイントと思ったところを書き出します。
itemSelector
https://cal-heatmap.com/#itemSelector
デフォルトでは#cal-heatmap
(つまりid="cal-heatmap"
)のノードにカレンダーが表示されます。
<div id="cal-heatmap">
というタグを作っていますよね。
以上、魔法に見える部分の種明かしでした。
domain
> subDomain
https://cal-heatmap.com/#domain
GitHubのコントリビューションカレンダーのように表示する設定を探したところ、
- domain:
"month"
- subDomain:
"day"
に落ち着きました。
GitHubとは違って、月の間に空白がある(連続しているように見えにくい)のですが、何月何日というのが分かるのでしっくり来ています3。
ドキュメントのExampleにdomainとsubDomainの組合せが示されていて、参考にしました。
x_day
のように指定すると、左から右、上から下の順で並び、よく見るカレンダー表示になります
(コントリビューションカレンダーは上から下、左から右の順だったということですね)。
月の数の表示(range
、start
)
domainの数をrange
で指定します。
2021年10月公開で今月まで表示したいので、4ヶ月(range=4
)ですね。
https://cal-heatmap.com/#range
カレンダーの始まりをstart
で指定します。
公開月の10月始まりにするには、new Date(2021, 9)
とひと月前をstart
に指定する必要がありました4。
https://cal-heatmap.com/#start
data(データの形式)
いよいよ「いつに何回」というデータの指定です。
dataType
がデフォルトでは"json"
に指定されています。
なのでdata
にはオブジェクトを指定すれば、カレンダーにヒートマップとして反映されます。
オブジェクトの形式は以下のようになります。
{ "timestamp(秒)": 値(今回は回数), "1635519600.0": 1, }
https://cal-heatmap.com/#data-format
ここで、日付をtimestampに変換するためにPythonを使いました5。
>>> datetime.strptime("2021/10/30", "%Y/%m/%d").timestamp() 1635519600.0
日付の文字列からdatetime
オブジェクトを作り、timestamp
メソッド6を呼び出すことで、float
のタイムスタンプが手に入ります7。
legend
凡例(legend)はデフォルトで[10, 20, 30, 40]
と指定されています。
https://cal-heatmap.com/#legend
映画の鑑賞回数は1日あたり数回なので、1回観たら緑、2回観ていたら濃い緑のように、指定する配列を変えて色がつく区間を調整する必要がありました。
ここまでで以下のように表示されました。
ブラウザでHTMLを開いています(file:///
で始まるURLになっています)。
JSONファイルにまとめたデータを渡そうとしたら・・
ドキュメントのdataの項目には、オブジェクトの代わりに文字列も渡せるという記載があります。
実際ExampleでもJSONファイルの名前を渡しています。
キー:タイムスタンプ、値:鑑賞回数のJSONを作り、
$ head -n5 commits_ainouta.json { "1635519600.0": 1, "1635865200.0": 1, "1636297200.0": 1, "1636556400.0": 1,
ファイル名をdataに指定してみたところ・・・
- data: data, + data: "commits_ainouta.json",
カレンダーは色づかなくなり、開発者ツールのコンソールに「Reason: CORS request not HTTP」と表示されました。
CORSエラーと呼ばれるもののようです。
前編はここまでとし、次回はこのエラーの解決をまとめます(手元で解決しており、後編は近日公開予定です)。
-
↩macOSにはsayという文字列読み上げコマンドがありまして、
— nikkie にっきー (@ftnext) 2022年1月9日
say "いま、幸せ?"
のように読み上げてくれるんですが、
気が付いたら無心で繰り返しコマンド実行してました。
これは、わたし、重症だ😂#アイの歌声を聴かせて
ちなみに、?の有無でちゃんとイントネーションが変わります -
コントリビューションの数え方については 近況報告:100DaysOfContribution 達成しました!💚 - nikkie-ftnextの日記 をどうぞ↩
-
subDomainTextFormat
で「何日」も示すようにしました。ref: https://cal-heatmap.com/#subDomainTextFormat↩ -
2000/01/15始まりにするには
new Date(2000, 0, 15)
とひと月前の同じ日を指定するようです↩ -
書いている中で気付いたのですが、Cal-heatmapの
afterLoadData()
コールバックでJavaScript側でタイムスタンプに加工することもできそうです↩ -
https://docs.python.org/ja/3/library/datetime.html#datetime.datetime.timestamp↩
-
https://stackoverflow.com/questions/9637838/convert-string-date-to-timestamp-in-python#comment34554753_9637908 で知りました↩