FUJITSU アドベントカレンダー23日目の記事です。
はじめに
Vega はjsonでデータや描画の設定を記述することで、視覚化できるツールです。いろんなグラフを表現できますが、今回はグラフでなくクリスマスツリーをVegaで表現してみたいと思います。
出来上がったもの
中身
データとしては、「幹」「葉っぱ」「星」「白いライン」「丸い飾り」で構成しています。
それぞれ、抜粋しながらポイントを書いておきます。
幹
rect(四角形)を描画してます。
"data": [
{"name": "tree", "values": [{"x": 0, "y": 0}]},
],
...
"marks": [
{
"type": "rect",
"from": {"data": "tree"},
"encode": {
"update": {
"x": {"scale": "xscale", "signal": "datum.x - 0.8"},
"x2": {"scale": "xscale", "signal": "datum.x + 0.8"},
"y": {"scale": "yscale", "value": 10},
"y2": {"scale": "yscale", "value": 0},
"fill": {"value": "#864A2b"}
}
}
},
葉っぱ
高さ(y)とサイズ(size)を変えて、緑色の三角形を並べて表現しています。
"data": [
{
"name": "leaves",
"values": [
{"x": 0, "y": 15, "size": 18000},
{"x": 0, "y": 20, "size": 15000},
{"x": 0, "y": 25, "size": 13000},
{"x": 0, "y": 30, "size": 10000},
{"x": 0, "y": 36, "size": 6000}
]
},
...
"marks": [
{
"type": "symbol",
"from": {"data": "leaves"},
"encode": {
"update": {
"x": {"scale": "xscale", "field": "x"},
"y": {"scale": "yscale", "field": "y"},
"size": {"field": "size"},
"shape": {"value": "triangle"},
"fill": {"value": "green"}
}
}
},
]
星
中身(x=0)に高さ(y)を調整し、星形を作ります。
星形は、SVG pathで表現しています。
"data": [
{"name": "star", "values": [{"x": 0, "y": 42, "size": 1000}]
],
...
"marks":[
{
"type": "symbol",
"from": {"data": "star"},
"encode": {
"enter": {"fill": {"value": "#939597"}, "stroke": {"value": "#652c90"}},
"update": {
"x": {"scale": "xscale", "field": "x"},
"y": {"scale": "yscale", "field": "y"},
"size": {"field": "size"},
"shape": {
"value": "M0,.5L.6,.8L.5,.1L1,-.3L.3,-.4L0,-1L-.3,-.4L-1,-.3L-.5,.1L-.6,.8L0,.5Z"
},
"fill": {"value": "yellow"}
}
}
},
]
白いライン
layerによって、group化することで、一つのデータセットから複数の斜め上にいく線を表現しています。
本来は、葉のうえだけ描画するのが正しいですが、白色にすることで背景色と同一にしごまかしています。
"data":[
{
"name": "lines",
"values": [
{"x": -4, "y": 10, "layer": 1},
{"x": 4, "y": 20, "layer": 1},
{"x": -4, "y": 20, "layer": 2},
{"x": 4, "y": 30, "layer": 2},
{"x": -4, "y": 30, "layer": 3},
{"x": 4, "y": 40, "layer": 3}
]
},
],
...
"marks": [
{
"type": "group",
"from": {"facet": {"data": "lines", "name": "facet", "groupby": "layer"}},
"marks": [
{
"type": "line",
"from": {"data": "facet"},
"encode": {
"update": {
"x": {"scale": "xscale", "field": "x"},
"y": {"scale": "yscale", "field": "y"},
"strokeWidth": {"value": 5},
"stroke": {"value": "white"}
}
}
}
]
},
]
丸い飾り
横の位置(x)と高さ(y)をツリーの上に来るように配置し、飾りの色はxとyを掛けた値をcとして、pastel
カラーで振り分けるように、color スケールをつくって表現します。
"data":[
{
"name": "bolls",
"values": [
{"x": -2, "y": 15},
{"x": 2, "y": 12},
{"x": -1, "y": 25},
{"x": 1.2, "y": 20},
{"x": -0.8, "y": 10},
{"x": 0.4, "y": 32},
{"x": -0.6, "y": 38}
],
"transform": [{"type": "formula", "as": "c", "expr": "datum.x * datum.y"}]
}
],
"scales": [
{
"name": "color",
"domain": {"data": "bolls", "field": "c"},
"range": {"scheme": "pastel1"}
}
],
...
"marks": [
{
"type": "symbol",
"from": {"data": "bolls"},
"encode": {
"update": {
"x": {"scale": "xscale", "field": "x"},
"y": {"scale": "yscale", "field": "y"},
"size": {"value": 150},
"fill": {"scale": "color", "field": "c"}
}
}
}
]
おわりに
急遽思いついて試してみましたが思った以上にクリスマスツリーになりました。