你很幸运!我确实刚刚在Deneb中制作了类似的东西。
完整代码:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 550,
"height": 300,
"signals": [
{"name": "dataLength", "update": "length(data('penguins'))"},
{"name": "row0Radius", "value": 280},
{"name": "row1Radius", "value": 260},
{"name": "row2Radius", "value": 240},
{"name": "row3Radius", "value": 220},
{"name": "row4Radius", "value": 200},
{"name": "row5Radius", "value": 180},
{"name": "row6Radius", "value": 160},
{"name": "row0Circ", "update": "PI*row0Radius"},
{"name": "row1Circ", "update": "PI*row1Radius"},
{"name": "row2Circ", "update": "PI*row2Radius"},
{"name": "row3Circ", "update": "PI*row3Radius"},
{"name": "row4Circ", "update": "PI*row4Radius"},
{"name": "row5Circ", "update": "PI*row5Radius"},
{"name": "row6Circ", "update": "PI*row6Radius"},
{
"name": "totalLength",
"update": "row0Circ+row1Circ+row2Circ+row3Circ+row4Circ+row5Circ+row6Circ "
}
],
"data": [
{
"name": "penguins",
"url": "data/penguins.json",
"transform": [
{"type": "project", "fields": ["Species", "Island"]},
{
"type": "window",
"ops": ["row_number"],
"fields": [null],
"as": ["index"],
"sort": {"field": "Island", "order": "ascending"}
}
]
},
{
"name": "placement",
"transform": [
{
"type": "sequence",
"start": 1,
"stop": {"signal": "dataLength+1"},
"as": "index"
},
{
"type": "formula",
"as": "wholeCirc",
"expr": "totalLength/dataLength"
},
{
"type": "window",
"ops": ["sum"],
"fields": ["wholeCirc"],
"as": ["cumWholeCirc"]
},
{
"type": "formula",
"as": "row",
"expr": "datum.cumWholeCirc <row0Circ?0:datum.cumWholeCirc <row0Circ+row1Circ?1:datum.cumWholeCirc <row0Circ+row1Circ+row2Circ?2:datum.cumWholeCirc <row0Circ+row1Circ+row2Circ+row3Circ?3:datum.cumWholeCirc <row0Circ+row1Circ+row2Circ+row3Circ+row4Circ?4:datum.cumWholeCirc <row0Circ+row1Circ+row2Circ+row3Circ+row4Circ+row5Circ?5:6 "
},
{
"type": "joinaggregate",
"fields": ["Species"],
"ops": ["count"],
"groupby": ["row"],
"as": ["rowCount"]
},
{
"type": "formula",
"as": "rowCirc",
"expr": "datum.row==0?(row0Circ/(datum.rowCount-1)):datum.row==1?(row1Circ/(datum.rowCount-1)):datum.row==2?(row2Circ/(datum.rowCount-1)):datum.row==3?(row3Circ/(datum.rowCount-1)):datum.row==4?(row4Circ/(datum.rowCount-1)):datum.row==5?(row5Circ/(datum.rowCount-1)):datum.row==6?(row6Circ/(datum.rowCount-1)):0"
},
{
"type": "window",
"ops": ["sum"],
"fields": ["rowCirc"],
"groupby": ["row"],
"sort": {"field": "index", "order": "descending"},
"as": ["cumRowCirc"]
},
{
"type": "formula",
"as": "cumRowCircAct",
"expr": "datum.cumRowCirc - datum.rowCirc "
},
{
"type": "formula",
"as": "theta",
"expr": "datum.cumRowCircAct==0?0:datum.row==0?(datum.cumRowCircAct/row0Radius):datum.row==1?(datum.cumRowCircAct/row1Radius):datum.row==2?datum.cumRowCircAct/row2Radius:datum.row==3?datum.cumRowCircAct/row3Radius:datum.row==4?datum.cumRowCircAct/row4Radius:datum.row==5?datum.cumRowCircAct/row5Radius:datum.row==6?datum.cumRowCircAct/row6Radius:0"
},
{
"type": "formula",
"as": "x",
"expr": "datum.row==0?row0Radius*cos(datum.theta):datum.row==1?row1Radius*cos(datum.theta):datum.row==2?row2Radius*cos(datum.theta):datum.row==3?row3Radius*cos(datum.theta):datum.row==4?row4Radius*cos(datum.theta):datum.row==5?row5Radius*cos(datum.theta):datum.row==6?row6Radius*cos(datum.theta):0"
},
{
"type": "formula",
"as": "y",
"expr": "datum.row==0?row0Radius*sin(datum.theta):datum.row==1?row1Radius*sin(datum.theta):datum.row==2?row2Radius*sin(datum.theta):datum.row==3?row3Radius*sin(datum.theta):datum.row==4?row4Radius*sin(datum.theta):datum.row==5?row5Radius*sin(datum.theta):datum.row==6?row6Radius*sin(datum.theta):0"
},
{
"type": "window",
"sort": {"field": "theta", "order": "ascending"},
"ops": ["row_number"],
"fields": ["row_number"],
"as": ["lookup"]
},
{
"type": "lookup",
"from": "penguins",
"key": "index",
"fields": ["lookup"],
"values": ["Island"],
"as": ["finalIsland"]
}
]
}
],
"scales": [
{
"name": "x",
"type": "linear",
"round": true,
"nice": true,
"zero": true,
"domain": {"field": "x", "data": "placement"},
"range": "width"
},
{
"name": "y",
"type": "linear",
"round": true,
"nice": true,
"zero": true,
"domain": {"field": "y", "data": "placement"},
"range": "height"
},
{
"name": "color",
"type": "ordinal",
"domain": {"data": "placement", "field": "finalIsland"},
"range": {"scheme": "category10"}
}
],
"marks": [
{
"name": "marks",
"type": "symbol",
"from": {"data": "placement"},
"encode": {
"update": {
"x": {"scale": "x", "field": "x"},
"y": {"scale": "y", "field": "y"},
"shape": {"value": "circle"},
"size": {"value": 130},
"stroke": {"value": "#4682b4"},
"tooltip": {"signal": "datum"},
"fill": {"scale": "color", "field": "finalIsland"}
}
}
}
]
}