Vega 解説 ~時系列データを処理する~

今回は、時系列のデータからグラフを描画します。(前回は[ここ](https://qiita.com/ihgs/items/7715bd7f6d2f7987f73a))
以下のような簡単なデータから始めます。


```json
[
  {"month": "2019-04", "amount": 28},
  {"month": "2019-05", "amount": 55},
  {"month": "2019-09", "amount": 10}
]
```
最終的なグラフ
![グラフ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/9b1b7139-37a6-d503-4b19-752cccc1c2e1.png)


### データの型決め

まずは、`month`要素が、文字列でなく時間型であることを教える必要があります。
ここでは、`format`プロパティを利用し、`month`要素を`date`型でparseするとします。

```json
  "data": [
    {
      "name": "table",
      "format": {"type": "json", "parse": {"month": "date"}},
      "values": [
        {"month": "2019-04", "amount": 28},
        {"month": "2019-05", "amount": 55},
        {"month": "2019-09", "amount": 10}
      ]
    }
  ],
```

### scale, 図の設定

前回までは、`type` に`band` を指定していましたが、`time` を指定します。

```
  "scales": [
    {
      "name": "xscale",
      "type": "time",
      "domain": {"data": "table", "field": "month"},
      "range": "width",
      "round": true
    },
```

一旦、`marks`のtypeを`rect` でなく、`symbol` にし、散布図のように表示してみます。

```
  "marks": [
    {
      "name": "layer_0",
      "type": "symbol",
      "from": {"data":"table"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "date"},
          "y": {"scale": "yscale", "field": "amount"},
          "fill": {"value": "steelblue"}
        }
      }
    }
  ]
```

こんな感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/8075c092-9577-6d1b-1856-ddd5b7603190.png)
[Vega Editorで開く](https://vega.github.io/editor/#/gist/54fcc244e57c652c3d4d227881fcdecc/06_time_barchart_01.json)


日付ごとのデータであればこのグラフでもいいですが、今回は月ごとのデータで表示領域も狭いので、棒グラフへと変更していきたいと思います。

## 散布図から棒グラフへの変更

棒グラフにするために、marks のtypeを`rect`にします。前回までは、棒の幅(width)として、`{"scale":"xscale", "band":1}`を指定して表現していました。
しかし、今回xscaleは`time`であるためbandがありません。そこで、`width`の代わりに`x2`を利用し、`x2`に翌月の位置を指定することで棒グラフを作成します。４月の場合、４月頭から５月までといった形です。

Vegaには、データに対して様々な加工が可能になっています。これを利用し各データの翌月の値を求めます。
データを拡張する`formula`を使います。各行データ(`datum`)から、年と月を取得した上で、１ヶ月足した値を`month_end`とし、各行に追加します。
※ 5.8 以上から[別の書き方](#散布図から棒グラフへの変更58-追記)ができます。　

```json
  "data": [
    {
      "name": "table",
      "format": {"type": "json", "parse": {"month": "date"}},
      "values": [
        {"month": "2019-04", "amount": 28},
        {"month": "2019-05", "amount": 55},
        {"month": "2019-09", "amount": 10}
      ],
      "transform": [
        {
          "type":"formula",
          "as": "month_end",
          "expr": "time(datetime(year(datum.month), month(datum.month)+1))"
        }
      ]
    }
  ],
```
こんな感じにデータが追加されます。

![data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/5458e544-3488-3976-fbc5-72bd4f1acebd.png)


このデータを使って描画します。`x2`に先ほど作成した`month_end`を指定します。このままでは、棒グラフが接してしまうため、`offset:-1`を指定し、終了位置を少しずらします。

```json
"marks": [
    {
      "name": "layer_0",
      "type": "rect",
      "from": {"data":"table"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "month"},
          "x2": {"scale": "xscale", "field": "month_end", "offset":-1},
          "y": {"scale": "yscale", "field": "amount"},
          "y2": {"scale": "yscale", "value": 0},
          "fill": {"value": "steelblue"}
        }
      }
    }
  ]
```

![スクリーンショット 2019-11-12 22.58.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/35930e43-5fe5-9fca-bcb9-f1f24bfc18da.png)

x軸の始まりと終わりが中途半端になっているので、`xscale` に`"nice":"month"` を指定します。
`nice`は、いい感じに軸を拡張してくれます。 4/10~9/15までのデータの場合、`month`を指定すると、4月頭から９月末までがグラフ内に収まるようになり、`year`を指定すると、1月頭から12月末までがグラフ内に収まるようになります。
これを設定することで、最初の完成形になります。

[Vega Editorで開く](https://vega.github.io/editor/#/gist/54fcc244e57c652c3d4d227881fcdecc/06_time_barchart_02.json)


## 散布図から棒グラフへの変更(>=5.8) 追記

5.8から、transformに`timeunit` が追加されていました。これを利用することで、範囲の取得を簡単にできるようになりました。

```json
"data": [
    {
      "name": "table",
      "format": {"type": "json", "parse": {"month": "date"}},
      "values": [
        {"month": "2019-04", "amount": 28},
        {"month": "2019-05", "amount": 55},
        {"month": "2019-09", "amount": 10}
      ],
      "transform": [
        {
          "type":"timeunit",
          "field":"month",
          "units": ["year", "month"]
        }
      ]
    }
  ],
```

こんなデータに変換されます。

![スクリーンショット 2019-12-08 9.59.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51316/acf04be5-29bc-e8a0-3ea2-d8c9492d7702.png)

units で指定された、年月に従い、月初から月末の値が、unit0,1に入ります。
`["month"]` のみを指定すると、年の情報は無視された値がはいります。複数年にわたるデータで、月ごとの特性をみたいときに使います。
他に`quarter` も指定できます。
https://vega.github.io/vega/docs/transforms/timeunit/#time-units

[Vega Editorで開く](https://vega.github.io/editor/#/gist/54fcc244e57c652c3d4d227881fcdecc/06_time_barchart_02_2.json)





次回は、何か実際のデータを活用しながら、グラフを書いていこうかなと考えています（未定）