エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

ダイヤ可視化ツール技術編

エムスリーの山本です。趣味で作っていたダイヤ可視化ツールの技術的な側面の話をします。

作ったもの

ダイヤ可視化ツールです。時刻表ではありません。鉄道路線を比較するにあたって、本数の多寡や速達列車の比率とか本数の減り方とかが一発で分かるように可視化するものです。何のために必要かというと、鉄オタがダイヤ知見を深めるのに使います。つまりそういうやつです。

たとえばこれは小田急の昼頃の1時間に運行されている列車なんですが、

  • 基本は20分間隔ダイヤ
  • 主要な駅は10分間隔で有効な列車が来るように調整されている
  • 本線は3-6-6-6で優等列車の比率が高い(長距離利用客が多そう)
  • 千代田線の直通はあまりやる気がなさそう

などが分かります。実際、新宿駅の利用者数の次に多い駅は町田駅だったりして、相当に長距離の利用者が多いのが特徴の路線です。

また、鉄オタならみんな架空鉄とか想像するのに使ったりするだろうとおもって、誰でも自由にデータ作れるようにしてみました。 最終的なレンダリングはコンピュータ側で扱うのが容易なJSONからレンダリングするのでJSONを作る必要がありますが、人間がJSONを直接書くのは面倒くさいので、CSVからJSONに変換するツールを別途用意しています。JSONファイルはWebで公開されているものであれば大体そのまま表示できます。内部的にはSVGでレンダリングしているので、そのままSVGをファイルに保存することができます。

実際のサイトは以下です。

https://ponkotuy.github.io/diagram-svg/menu.html

技術的な話

全体の設計

特にSPAを目指してなくてページ毎にTypeScriptをビルドしています。ページは3つあります。

  • index.ts(レンダリング本体)
  • menu.ts(メニュー部)
  • csv2json.ts(CSVからJSONに変換する仕組み)

作ったもののコアな部分はindex.tsで、JSONを読み込んでSVGレンダリングを行っています。

csv2json.tsはそのJSONを作るのが地味に面倒くさい、GoogleSpreadsheetからJSONを作成したい、となったので作りました。昔はExcel馬鹿にしてたんですが、表計算ソフトはデータ作成のUIが非常に優れているという認識に改めました。CSVなので特にGoogle Spreadsheetに限定はしてないです。(余談なんですがGoogleSpreadsheetのCSV出力、更新が遅いのですが何とかなりませんかね?)

フレームワークとしてVue.jsを使っています。一番大きな理由は慣れていたからですが、このような小さなツールだとあまり重厚長大なフレームワークを使いたくはないという理由もあります。

言語

言語は基本的にTypeScriptです。JavaScriptあんまり好きではないんですが、型があるとだいぶん書きやすくなります。型システム的にもなかなか興味深いです。リテラル型とか。リテラル型を活用すると、以下のような1-10の値のみ許容する型、みたいなのが作れます。(Union Typeとのあわせ技です)

export type Speed = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10

https://github.com/ponkotuy/diagram-svg/blob/e68bc644bc6d9ecc2f383ffdb95e3dcc12823ae5/src/common/train.ts#L24

ビルド

ビルドはWebpack。本当はgulp使いたかったけどシェアがWebpackの方が圧倒的に高いという話を聞いておそるおそる使ってみました。複雑なことはしてないので評価しづらいですが、不都合はないです。

GitHub Actions

このツールは、作った本人も沢山JSON作って公開しているので、JSONを追加したらmenuにも自動で追加して、git pushするだけでGitHub Pagesに反映される仕組みをGitHub Actionsで作りました。

GitHub PagesはGitHubにあるものをWebページとして公開できる仕組みで、色々なやりかたはありますが、gh-pagesブランチにHTMLを置く方法で使っています。

GitHub Actionsは他の人が作ったものをplugin的に使う機能があり、gh-pagesブランチに成果物をcommitするものもあります。

https://github.com/peaceiris/actions-gh-pages

実は最初は自前でそのためのスクリプトを作っていたんですが、GitHub Actionsの実行権限ではGitHub Pagesの中身を変更することができないらしく、GitHub Actionsだとgh-pagesは更新されるのにサイトは更新されない仕様があって、特に理由がないならこれを使った方がいいです。

  1. TypeScriptをビルドする
  2. JSONリストをシェルで錬成
  3. 以上の変更を先のAction使ってgh-pagesにpush

という流れになっています。

レンダリング部

SVGのレンダリングはライブラリ使っています。当初snapsvgでレンダリングしてたんですが、webpackかTypeScriptと相性が悪い感じなのか動かなかったので、途中でRaphaelに変更しました。大天使の名前を冠する厨二病感がすごい。snapsvgと違って@typesが入ってて型の補完効くのが良いです。

実際にSVGをレンダリングしている部分はひたすら配置に合わせてレンダリング位置を調整していくだけです。調整が退屈な上に気を抜くとすぐ読めなくなるほど複雑化します。今まであんま経験ないプログラミングなので結構苦戦しました。新機能入れるたびにリファクタしてます。あと綺麗なJSONを前提に作っているので、変なJSON食わせると簡単に鼻から悪魔が出てきそうです…。

We are hiring !!

おきまりですが、エムスリーでは技術に自信があるとか、ビジネスをまわしていける、というエンジニアを募集しています。見ていってください。

jobs.m3.com