Forum Discussion
Anonymous
3 years agoNot applicable
Custom visual based on seat allocation
Is there a power bi custom visual based on seat allocation? for example: or is there anything similar custom visual to the screenshot above? All the colours are allocated seat in a company ...
- 3 years ago
I got this to work in the attached file by just modifying the Vega spec you posted slightly. Note that I needed to add a "person" field in my example to effectively generate a row per seat
{ "$schema": "https://vega.github.io/schema/vega/v5.json", "width": 550, "height": 300, "signals": [ { "name": "dataLength", "update": "length(data('dataset'))" }, { "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": "dataset", "transform": [ { "type": "project", "fields": ["Person", "Party"] }, { "type": "window", "ops": ["row_number"], "fields": [null], "as": ["index"], "sort": { "field": "Party", "order": "descending" } } ] }, { "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": ["Person"], "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": "dataset", "key": "index", "fields": ["lookup"], "values": ["Party"], "as": ["finalParty"] } ] } ], "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": "finalParty" }, "range": {"scheme": "pbiColorNominal"} } ], "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": "finalParty" } } } } ] }This is the updated Vega specification (note you need to change the setting in the Deneb visual to use the "Vega" provider instead of the default "Vega-Lite" provider)
d_gosbell
3 years agoSuper User
I got this to work in the attached file by just modifying the Vega spec you posted slightly. Note that I needed to add a "person" field in my example to effectively generate a row per seat
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 550,
"height": 300,
"signals": [
{
"name": "dataLength",
"update": "length(data('dataset'))"
},
{
"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": "dataset",
"transform": [
{
"type": "project",
"fields": ["Person", "Party"]
},
{
"type": "window",
"ops": ["row_number"],
"fields": [null],
"as": ["index"],
"sort": {
"field": "Party",
"order": "descending"
}
}
]
},
{
"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": ["Person"],
"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": "dataset",
"key": "index",
"fields": ["lookup"],
"values": ["Party"],
"as": ["finalParty"]
}
]
}
],
"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": "finalParty"
},
"range": {"scheme": "pbiColorNominal"}
}
],
"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": "finalParty"
}
}
}
}
]
}
This is the updated Vega specification (note you need to change the setting in the Deneb visual to use the "Vega" provider instead of the default "Vega-Lite" provider)