Search code examples
powerbivega-litedeneb

How to scale the indivisual bar height in Vega Lite


I want to scale the bar height according to the SUM_A + SUM_B value.

In this example I would like to have the first graph to have the same height as the last one.

And I would like the first bar to have the height of the sum of the height of the bars in the last graph.

{
  "data": {
    "values": [
      {
        "EBENE_1": "A",
        "EBENE_2": "AA",
        "EBENE_3": "AAA",
        "EBENE_4": "AAAA",
        "STORNO": -70,
        "EINGANG": 41
      },
      {
        "EBENE_1": "A",
        "EBENE_2": "AA",
        "EBENE_3": "AAB",
        "EBENE_4": "AABB",
        "STORNO": -22,
        "EINGANG": 81
      },
      {
        "EBENE_1": "A",
        "EBENE_2": "AB",
        "EBENE_3": "ABC",
        "EBENE_4": "ABCC",
        "STORNO": -31,
        "EINGANG": 89
      },
      {
        "EBENE_1": "A",
        "EBENE_2": "AB",
        "EBENE_3": "ABDD",
        "EBENE_4": "ABDD",
        "STORNO": -28,
        "EINGANG": 8
      },
      {
        "EBENE_1": "A",
        "EBENE_2": "AC",
        "EBENE_3": "ACE",
        "EBENE_4": "ACEE",
        "STORNO": -39,
        "EINGANG": 55
      },
      {
        "EBENE_1": "A",
        "EBENE_2": "AC",
        "EBENE_3": "ACE",
        "EBENE_4": "ACEF",
        "STORNO": -78,
        "EINGANG": 78
      },
      {
        "EBENE_1": "A",
        "EBENE_2": "AC",
        "EBENE_3": "ACF",
        "EBENE_4": "ACFG",
        "STORNO": -99,
        "EINGANG": 88
      },
      {
        "EBENE_1": "A",
        "EBENE_2": "AC",
        "EBENE_3": "ACF",
        "EBENE_4": "ACFH",
        "STORNO": -85,
        "EINGANG": 67
      }
    ]
  },
  "transform": [
    {"joinaggregate": [{"op": "sum", "field": "STORNO", "as": "SumA"}]},
    {"joinaggregate": [{"op": "sum", "field": "EINGANG", "as": "SumB"}]}
  ],
  "params": [
    {"name": "lowerLimit", "expr": "data('data_0')[0]['SumA']-200"},
    {"name": "upperLimit", "expr": "data('data_0')[0]['SumB']+100"}
  ],
  "repeat": {
    "layer": ["STORNO", "EINGANG"],
    "column": ["EBENE_1", "EBENE_2", "EBENE_3", "EBENE_4"]
  },
  "spec": {
    "height": 400,
    "width": 300,
    "mark": {"type": "bar"},
    "encoding": {
      "x": {
        "field": {"repeat": "layer"},
        "aggregate": "sum", 
            "scale": {
              "domain": [{"expr": "lowerLimit"},{"expr": "upperLimit"}], "zero": "true"
            }
      },
      "y": {"field": {"repeat": "column"}, "size": {"field": "sum"}
      }
    }
  }
}

i tried to use scale, but this scaled everything and not just the height.


Solution

  • I solved the Problem for me in Vega:

    1. Define a variable for the height of the visual, as I used it in the Deneb Plugin in PBI I used the pbiContainerHeight as reference:
        "signals": [
            {
              "name": "visualHeight",
              "update": "pbiContainerHeight"
            }]
    
    1. I created a rolling count for Ebene_4 (layer 4) as this is the smallest elemente and created a dataset for every EBENE (layer) containing the amount of EBENE_4 elements.
        {
          "name": "EBENE_X_GRAPH",
          "source": "data_0",
          "transform": [
                    {
              "type": "window",
              "ops": ["sum"],
              "fields": ["count_EBENE_4"],
              "as": [
                "cumulative_count_ebene_4"
              ]
            }
          ]
        }
    
    1. Then I calculated the Y and height of every element:
                  "y": {
                    "signal": "count_EBENE_4_height*(datum.cumulative_count_ebene_4-datum.count_EBENE_4)"
                  },
                  "height": {
                    "signal": "(count_EBENE_4_height*datum.count_EBENE_4)-5"
                  }
    
    1. As lables didn´t work anymore I had to recreate them as text marks and use an offset of half the height to place them.