Reactとvis.jsで時系列データのタイムライン表示

いろいろなJavaScriptの視覚化用のライブラリがありますが、今回はその中でもvis.jsを使って時系列のデータをタイムライン表示してみます。

vis.jsをReactのアプリで使ってみたので簡単に紹介します。
react-visjs-timelineというライブラリを使うと簡単にこんな感じのタイムラインがフロントエンドに組み込めます。

![opsshare_timeline_chart.png](https://qiita-image-store.s3.amazonaws.com/0/45851/17a57378-38a1-b0ce-0d54-42f7495eebd8.png)


# react-visjs-timeline導入

npmで以下を実行。

```shell
$ npm install --save vis
$ npm install --save react-visjs-timeline
```

これだけでOK

# timelineを構成する要素

timelineは、グループとアイテムから成ります。

* グループはタイムラインを用途ごとにレーンで分ける際に利用する要素です
* アイテムはタイムライン上の各イベントと紐付く要素です。アイテムのタイプは以下の4種類
    * box: イベントの開始時刻のポイントと内容表記
    * point: イベントの開始時刻へのポイントプロット表記
    * range: 開始〜終了の幅での表記
    * background: グループの行幅いっぱいに指定の開始〜終了の時間分表記

![visjs_timeline_item_type.png](https://qiita-image-store.s3.amazonaws.com/0/45851/8334b5f7-ff64-34d1-e7b5-791714713ba4.png)


# Reactのコードへの組み込み

コードには以下のような感じで組み込みます。

```react
import Timeline from 'react-visjs-timeline'

const timelineOptions = { //timelineのオプションを定義
  width: '100%',　 //timelineの表示
  stack: true, //時刻が近くて表示が重なるようなケースにどう扱うかの指定(trueにすると冒頭の例のようにずらして表示)
  showMajorLabels: true,
  showCurrentTime: true, //現在の時刻のポイントにラインを表示
  zoomMin: 1000, //最大でどこまで時間軸を拡大できるようにするか(ミリ秒単位で指定)。1000だと1秒粒度での拡大まで許容する設定。
  type: 'box', //デフォルトのアイテムのタイプ指定
  maxHeight: '800px', //timelineの表示の最大幅
  minHeight: '10px',　//timelineの表示の最小幅
  format: {　// 時間軸の表記フォーマット指定
    minorLabels: {
      minute: 'h:mma',
      hour: 'ha'
    }
  }
}

・・・略
const items = [{ //タイムラインに表示するアイテムの定義
  className: 'range-type-class', // アイテムの表示箇所のdivに追加設定するクラス名
  start: new Date(2018, 2, 20, 10, 10, 0), // rangeの開始時刻指定(Dateオブジェクト)
  end: new Date(2018, 2, 20, 11, 9, 0), // rangeの終端時刻指定
  content: 'range type item', // rangeのアイテム内に表示する文字列
  type: 'range', //　アイテムのタイプ
  group: 1, // アイテムを表示させる先のグループID
},{
  className: 'background-type-class',
  start: new Date(2018, 2, 20, 9, 10, 0),
  end: new Date(2018, 2, 20, 9, 20, 0), 
  content: 'background type',
  type: 'background',
  group: 2,
},{
  className: 'point-type-class',
  start: new Date(2018, 2, 20, 9, 23, 0),
  content: 'point type',
  type: 'point',
  group: 3,
},{
  className: 'box-type-class',
  start: new Date(2018, 2, 20, 9, 30, 0),
  content: 'box type',
  type: 'box',
  group: 4,
}]

const groups = [{ //グループの定義
  id: 1, // グループの識別ID設定
  content: 'range type group', // タイムラインに表記するグループ名
},{
  id: 2,
  content: 'background type group',
},{
  id: 3,
  content: 'point type group',
},{
  id: 4,
  content: 'box type group',
}]

class Main extends Component {
    render() {
        return ( // <Timeline>というVirtualDOMで組み込み
            <Timeline 
                options={timelineOptions}
                items={items}
                groups={groups}
            />
        );
    }
}
```
ベース、アイテム、グループそれぞれのオプションは様々あるので詳しくはマニュアルをご覧下さい。
[http://visjs.org/docs/timeline/](http://visjs.org/docs/timeline/)

# スタイルの変更

vis.jsはスタイルを簡単にカスタマイズできるよう、各div要素にクラス名を自動で割り振ってくれています。

* .vis-item: 各アイテム要素のクラス
* .vis-range: rangeタイプのアイテムのクラス
* .vis-odd: timelineの時間軸の区分の奇数列を示すクラス
* .vis-even: timelineの時間軸の区分の偶数列を示すクラス
* .classNameで指定した名称: classNameが該当する要素を示すクラス

等々

なので、cssとして以下のような感じで指定し、

```css:timeline_custom.css
.vis-item {
  background-color: #80DEEA;
}
.vis-odd {
  background: #ECEFF1;
}
.vis-even {
  background: #CFD8DC;
}
.vis-range {
  border-radius: 5px;
  color: #FFFFFF;
  border: 0px;
}
.box-type-class {
  color: #000;
}
```

あとはimportすればOK。

```react
import 'cssの配置ディレクトリパス/custom_timeline.css'
```
便利ですね。
以上です。