vega 란
공홈 : https://vega.github.io/vega/
JSON 방식으로 시각화 문법을 작성하여 차트를 그리는 툴 입니다.
d3.js 의 복잡한 메서드나 로직을 가지고 그리는 것이 아니라 vega에서 정해진 rule대로 json 을 작성하면 해당 규칙대로 차트를 그려줍니다.
장점
- config 처럼 셋팅만으로도 차트를 그릴 수 있습니다.
- 온라인 툴을 제공하고 있어서 미리 셋팅된 config를 데이터 및 차트를 확인 할 수 있습니다.
- 다양한 example을 제공하고 있습니다.
단점
- d3.js를 다뤄 보지 않았다면 용어나 단어에 의해 러닝커브가 발생 됩니다.
- config json에 차트 관련 메서드들도 string 값으로 넘겨야 하고, 정확히 무슨 값을 넘겨야 하는지 모른다면 방대한 문서를 읽어야 합니다.
- 온라인 툴에서 미리 확인 할 수 있는 데이터가 너무 길어질 경우에는 온라인 툴에서 확인하기가 어렵습니다. ( 개인적으로 View 메서드를 이용해서 돌려보라고 안내해줍니다. )
react-vega
github : https://github.com/vega/react-vega/tree/master/packages/react-vega
vega로 그려지는 차트를 컴포넌트로 만들어주는 라이브러리
- 차트를 그리는 config 를 입력으로 받아 컴포넌트를 만든다.
-
해당 컴포넌트의 props API는 https://github.com/vega/vega-embed API 를 참고하면 됩니다.
- mode, theme, defaultStyle, renderer, logLovel, tooltip, loader, patch, width, height, padding, actions, scaleFactor, config, editorUrl, sourceHeader, sourceFooter, hover, i18n, downloadFileName
사용
example code : https://github.com/vega/react-vega/tree/master/packages/react-vega#example-code
예시 ( 트리 차트 )
import { createClassFromSpec } from "react-vega";
export default createClassFromSpec({
mode: "vega",
spec: {
$schema: "https://vega.github.io/schema/vega/v5.json",
width: 1200,
// height: 1500,
padding: 5,
background: "white",
autosize: { type: "fit-x", contains: "padding" },
signals: [
// 대화 형 동작을 유도 할 수있는 동적 변수
{ name: "colorIn", value: "firebrick" },
{ name: "colorOut", value: "forestgreen" },
{
name: "active",
value: null, // 마우스 오버에 따라서 active value에 동적으로 다른 값이 들어간다.
on: [
{ events: "text:mouseover", update: "datum.id" },
{ events: "mouseover[!event.item]", update: "null" }
]
},
{
name: "activeNode",
value: null, // 마우스 오버에 따라서 active value에 동적으로 다른 값이 들어간다.
on: [
{ events: "text:mouseover", update: "datum" },
{ events: "mouseover[!event.item]", update: "null" }
]
},
{
name: "activeParent",
value: null, // 마우스 오버에 따라서 active value에 동적으로 다른 값이 들어간다.
on: [
{ events: "text:mouseover", update: "datum.parent" },
{ events: "mouseover[!event.item]", update: "null" }
]
}
],
data: [ // 데이터 세트 정의 및 변환은 로드 할 데이터와 처리 방법을 정의합니다.
{
name: "tree",
// values: [# 데이터가 들어갈 영역],
transform: [
{
type: "stratify",
key: "id",
parentKey: "parent"
},
{
type: "tree",
method: "tidy",
size: [{ signal: "height" }, { signal: "width" }],
separation: true,
as: ["y", "x", "depth", "children"]
},
{
type: "formula",
expr: "slice(datum.id, 0, 1)",
as: "type"
}
]
},
{
name: "links",
source: "tree",
transform: [
{ type: "treelinks" },
{
type: "linkpath",
orient: "horizontal",
shape: "diagonal"
}
]
},
{
name: "ancestors", // 기존 tree 데이터를 기반으로 ancestor를 생성한 파생된 데이터를 만든다.
source: "tree",
transform: [
{
type: "formula",
expr: "treeAncestors('tree', datum.id)", // 리턴 배열
as: "ancestors",
initonly: true
}
]
},
{
name: "treeAncestorsFlatten", // ancestors 데이터를 기반으로 배열값인 ancestors 열 값을 flatten 하게 만든다.
source: "ancestors",
transform: [{ type: "flatten", fields: ["ancestors"] }]
},
{
name: "selected",
source: "treeAncestorsFlatten",
transform: [
{
type: "filter",
expr:
"datum.id === active || datum.parent === active || datum.id === activeParent || datum.ancestors.id === active"
}
]
}
],
marks: [
{
type: "path",
from: { data: "links" },
encode: {
update: {
path: { field: "path" },
stroke: [
{
test:
"indata('selected', 'id', datum.source.id) && indata('selected', 'id', datum.target.id)",
signal: "colorIn"
},
{
test:
"indata('selected', 'ancestors.id', datum.source.id) && indata('selected', 'ancestors.id', datum.target.id)",
signal: "colorIn"
},
{ value: "#ddd" }
]
}
}
},
{
type: "symbol",
from: { data: "tree" },
encode: {
enter: {
size: { value: 100 },
stroke: { value: "#fff" }
},
update: {
x: { field: "x" },
y: { field: "y" },
fill: [
{ test: "datum.id === active", value: "red" },
{ test: "indata('selected', 'id', datum.id)", signal: "colorIn" },
{
test: "indata('selected', 'ancestors.id', datum.id)",
signal: "colorIn"
},
{ value: "#e4cccc" }
]
}
}
},
{
type: "text",
from: { data: "tree" },
encode: {
enter: {
text: { signal: "datum.id + ' ' + datum.name" },
fontSize: { value: 12 },
baseline: { value: "middle" }
},
update: {
x: { field: "x" },
y: { field: "y" },
dx: { signal: "datum.children ? -7 : 7" },
align: { signal: "datum.children ? 'right' : 'left'" },
tooltip: { signal: "datum.name" },
fill: [
{ test: "datum.id === active", value: "red" },
{ test: "indata('selected', 'id', datum.id)", signal: "colorIn" },
{
test: "indata('selected', 'ancestors.id', datum.id)",
signal: "colorIn"
},
{ value: "#333" }
]
}
}
}
]
}
});
// 사용법
<TagTreeChart
data={tagChartData}
actions={false}
height={resultChartHeight}
renderer={"svg"}
></TagTreeChart>