[英]How to render class/org/flow/state chart/diagrams with Vega / Vega-lite
I can't find an example of a state/class/flow chart/org chart diagram with Vega.我找不到 Vega 的状态/类/流程图/组织结构图示例。 Are there any out there?外面有吗?
It feels like Vega is perfectly suited for this (if a bit overpowered), but without an example to start from it's a rather steep learning curve.感觉 Vega 非常适合这个(如果有点过分),但没有一个例子可以从它开始,这是一个相当陡峭的学习曲线。 There are some examples on a "How Vega Works" page, but no links to how they're built: “织女星的工作原理”页面上有一些示例,但没有链接到它们的构建方式:
There's also the tree layout example, but it's not clear how one would begin converting this into blocks suitable for a flow-chart style diagram.还有树布局示例,但不清楚如何开始将其转换为适合流程图样式图的块。
Here's some examples of the sort of output desired (plus other shapes eg diamonds/triangles) from eg mermaid.js这是来自例如mermaid.js 的所需输出类型的一些示例(以及其他形状,例如菱形/三角形)
Suppose you're able to represent your chart as follows:假设您可以按如下方式表示图表:
"values": [
{"id": "1", "parent": null, "title": "Animal"},
{"id": "2", "parent": "1", "title": "Duck"},
{"id": "3", "parent": "1", "title": "Fish"},
{"id": "4", "parent": "1", "title": "Zebra"}
]
What you can then do is to lay the nodes out in a tree-like shape ( stratify
does the job):然后你可以做的是将节点布置成树状( stratify
完成这项工作):
"transform": [
{
"type": "stratify",
"key": "id",
"parentKey": "parent"
},
{
"type": "tree",
"method": "tidy",
"separation": true,
"size": [{"signal": "width"}, {"signal": "height"}]
}
]
having laid out the nodes, you need to generate connecting lines, treelinks
+ linkpath
combo does exactly that:布置节点后,您需要生成连接线, treelinks
+ linkpath
组合正是这样做的:
{
"name": "links",
"source": "tree", // take datasource "tree" as input
"transform": [
{ "type": "treelinks" }, // apply transform 1
{ "type": "linkpath", // follow up with next transform
"shape": "diagonal"
}
]
}
now that you've got your data sources, you want to draw actual objects.现在您已经获得了数据源,您想要绘制实际对象。 in Vega these are called marks
.在 Vega 中,这些被称为marks
。 I guess this is where I'm going to deviate from your desired output as I'm only drawing one rectangle with a title for each data point and some basic lines to connect:我想这就是我将偏离您想要的输出的地方,因为我只绘制一个矩形,每个数据点都有一个标题和一些基本的连接线:
"marks": [
{
"type": "path",
"from": {"data": "links"}, // dataset we defined above
"encode": {
"enter": {
"path": {"field": "path"} // linkpath generated a dataset with "path" field in it - we just grab it here
}
}
},
{
"type": "rect",
"from": {"data": "tree"},
"encode": {
"enter": {
"stroke": {"value": "black"},
"width": {"value": 100},
"height": {"value": 20},
"x": {"field": "x"},
"y": {"field": "y"}
}
}
},
{
"type": "text",
"from": {"data": "tree"}, // use data set we defined earlier
"encode": {
"enter": {
"stroke": {"value": "black"},
"text": {"field": "title"}, // we can use data fields to display actual values
"x": {"field": "x"}, // use data fields to draw values from
"y": {"field": "y"},
"dx": {"value":50}, // offset the mark to appear in rectangle center
"dy": {"value":13},
"align": {"value": "center"}
}
}
}
]
All in all I arrived at a very basic approximation of your target state.总而言之,我得到了您目标状态的一个非常基本的近似值。 It's definitely not an exact match: the rectangles there should probably be replaced with groups
and connection paths will need some work too.这绝对不是完全匹配:那里的矩形可能应该用groups
替换,连接路径也需要一些工作。 You will notice I'm not using any signals
to feed dynamic user inputs and update
/ exit
/ hover
instructions - again, for simplicity.您会注意到我没有使用任何signals
来提供动态用户输入和update
/ exit
/ hover
指令 - 再次,为简单起见。
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 800,
"height": 300,
"padding": 5,
"data": [
{
"name": "tree",
"values": [
{"id": "1", "parent": null, "title": "Animal"},
{"id": "2", "parent": "1", "title": "Duck"},
{"id": "3", "parent": "1", "title": "Fish"},
{"id": "4", "parent": "1", "title": "Zebra"}
],
"transform": [
{
"type": "stratify",
"key": "id",
"parentKey": "parent"
},
{
"type": "tree",
"method": "tidy",
"separation": true,
"size": [{"signal": "width"}, {"signal": "height"}]
}
]
},
{
"name": "links",
"source": "tree",
"transform": [
{ "type": "treelinks" },
{ "type": "linkpath",
"shape": "diagonal"
}
]
},
{
"name": "tree-boxes",
"source": "tree",
"transform": [
{
"type": "filter",
"expr": "datum.parent == null"
}
]
},
{
"name": "tree-circles",
"source": "tree",
"transform": [
{
"type": "filter",
"expr": "datum.parent != null"
}
]
}
],
"marks": [
{
"type": "path",
"from": {"data": "links"},
"encode": {
"enter": {
"path": {"field": "path"}
}
}
},
{
"type": "rect",
"from": {"data": "tree-boxes"},
"encode": {
"enter": {
"stroke": {"value": "black"},
"width": {"value": 100},
"height": {"value": 20},
"x": {"field": "x"},
"y": {"field": "y"}
}
}
},
{
"type": "symbol",
"from": {"data": "tree-circles"},
"encode": {
"enter": {
"stroke": {"value": "black"},
"width": {"value": 100},
"height": {"value": 20},
"x": {"field": "x"},
"y": {"field": "y"}
}
}
},
{
"type": "rect",
"from": {"data": "tree"},
"encode": {
"enter": {
"stroke": {"value": "black"},
"width": {"value": 100},
"height": {"value": 20},
"x": {"field": "x"},
"y": {"field": "y"}
}
}
},
{
"type": "text",
"from": {"data": "tree"},
"encode": {
"enter": {
"stroke": {"value": "black"},
"text": {"field": "title"},
"x": {"field": "x"},
"y": {"field": "y"},
"dx": {"value":50},
"dy": {"value":13},
"align": {"value": "center"}
}
}
}
]
}
UPD : suppose, you would like to render different shapes for root and leaf nodes of your chart. UPD :假设您想为图表的根节点和叶节点呈现不同的形状。 One way to achieve this will be to add two filter
transformations based on your tree
dataset and filter them accordingly:实现此目的的一种方法是根据您的tree
数据集添加两个filter
转换并相应地过滤它们:
{
"name": "tree-boxes",
"source": "tree", // grab the existing data
"transform": [
{
"type": "filter",
"expr": "datum.parent == null" // run it through a filter defined by expression
}
]
},
{
"name": "tree-circles",
"source": "tree",
"transform": [
{
"type": "filter",
"expr": "datum.parent != null"
}
]
}
then instead of rendering all marks as rect
you'd want two different shapes for respective transformed datasets:然后,不是将所有标记渲染为rect
而是需要为各自的转换数据集提供两种不同的形状:
{
"type": "rect",
"from": {"data": "tree-boxes"},
"encode": {
"enter": {
"stroke": {"value": "black"},
"width": {"value": 100},
"height": {"value": 20},
"x": {"field": "x"},
"y": {"field": "y"}
}
}
},
{
"type": "symbol",
"from": {"data": "tree-circles"},
"encode": {
"enter": {
"stroke": {"value": "black"},
"width": {"value": 100},
"height": {"value": 20},
"x": {"field": "x"},
"y": {"field": "y"}
}
}
}
You can refer to this solution - Working with trees which covers您可以参考此解决方案 - 使用覆盖的树木
Step 1 - Extracting Nodes from Tabular Data步骤 1 - 从表格数据中提取节点
Step 2 - Extracting Links from Stratified Node Data步骤 2 - 从分层节点数据中提取链接
Step 3 - How to bring them together第 3 步 - 如何将它们组合在一起
Step 4 - Add labels第 4 步 - 添加标签
Step 5 - Add Color第 5 步 - 添加颜色
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.