Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
3 years ago
Solved

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 ...
  • d_gosbell's avatar
    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)