FUJITSU アドベントカレンダーの記事です。
はじめに
去年は、Vega1 でクリスマスツリーを描きましたが、今年はVegaでアドベントカレンダーを表現してみます。
完成形は以下の様な感じです。日にちが進むとBoxが空いていきます。
Vega エディタで以下から動作を確認できます(25日以降は全部空いた悲しい見た目になります)
Online editor
Gist
中身
作成方針はBoxを一つのグラフとし、25個のグラフを5x5に並べていきます。
データ
timeSequence
関数を使って、12/1~12/25までの1日ごとの連続する日付データ day
を作成します。その後 transform/formula
で、処理しやすい様に日にちだけのでデータを作ります。
"data": [
{
"name": "days",
"values": {
"signal": "timeSequence('day', datetime(2021,11,1), datetime(2021,11,26))"
},
"transform": [
{
"type": "formula",
"as": "date",
"expr": "datum"
},
{
"type": "formula",
"as": "day",
"expr": "date(datum)"
}
]
}
],
以下の様なデータになります。
[{"date": "Tue, 30 Nov 2021 15:00:00 GMT", "day":1},
{"date": "Wed, 01 Dec 2021 15:00:00 GMT", "day":2},
...
この一行のデータがひとつのグラフをあらわす様にします。
layout
で、columnsで5を指定して、5列にします。
marks
では、day
でグルーピングすることによって、各日ごとのグラフを生成できるようにします。
"layout": {
"padding": {"signal": "box_padding"},
"columns": 5,
"align": "all"
},
"marks": [
{
"type": "group",
"from": {
"facet": {
"name": "facet",
"data": "days",
"groupby": ["day"]
}
},
"marks": [...
グラグ(Box)
上のグルーピングされたデータでグラフを作成していきます。
ひとつのグラフの構成要素は、
- 四角形
- 日付の数字
- 切り取り線/切り取り後の箱
四角形
boxの縦横のサイズを指定するsignal box_length
を用意しておき、
rect の {x:0,y:0, width:box_length, height: box_length}を指定することで、
縦横の長さが box_length
の箱を描画します。
"marks": [
{
"type": "rect",
"name": "box",
"from": {
"data": "facet"
},
"encode": {
"enter": {
"x": {
"value": 0
},
"width": {
"signal": "box_length"
},
"y": {
"value": 0
},
"height": {
"signal": "box_length"
}
}
}
}
]
日付の数字
グラフの中心に日付の数字を描画します。
{
"type": "text",
"from": {
"data": "facet"
},
"encode": {
"enter":{
"text": {"field": "day"},
"x": {"signal": "box_length*0.5"},
"y": {"signal": "box_length*0.5"},
"fontSize": {"signal": "box_length*0.5"},
"align": {"value": "center"},
"baseline": {"value": "middle"},
"fill": {"value": "white"}
}
}
}
切り取り線/切り取り後の箱
Boxの中に一回り小さい四角を作成したうえで、
現在時刻と比較し透明度(opacity
)を変更することで、本日以前の場合は白い四角を表示することでBoxが切り取られたように見せ、以降の場合は切り取り線だけを表示するようにします。
{
"type": "rect",
"name": "blankbox",
"from": {
"data": "facet"
},
"encode": {
"enter": {
"x": {
"value": 0,
"offset": {
"signal": "box_length*0.2"
}
},
"width": {
"signal": "box_length*0.6"
},
"y": {
"value": 0,
"offset": {
"signal": "box_length*0.2"
}
},
"height": {
"signal": "box_length*0.6"
},
"fill": {
"value": "white"
},
"fillOpacity": [
{"test": "datum.date > now()", "value": 0},
{"value": 1}
],
"stroke":{"value": "white"},
"strokeWidth": {"value": 0.5},
"strokeOpacity": [
{"test": "datum.date > now()", "value": 1},
{"value": 0}
],
"strokeDash": {"value": [2,2]}
}
}
}
以上を組み合わせることで、アドベントカレンダーの完成です。
参考
Vegaで普通のグラフを書く場合は以下を参照してみてください