Search code examples
powerbivisualizationpowerbi-desktopvega-litedeneb

Setting a dynamic domain (min and max axis) in Vega-Lite (Deneb)


Another week, another Vega-lite question I´m turning to you guys. It´s actually pretty easy to create KPI cards in Deneb however what´s causing me headache is the positioning of marks.

As you can see on the picture below when the delta is positive it´s pushing the line to the top and when negative then to the bottom of the visual. I´ve tried to set fixed axis which solved my problem however it was not right because you have KPIs where the delta range differs most of the time. So I can´t put a range [-15%,15%] because at KPIs where range is between [-2%,2%] it´s creating a flat line basically. And I don´t want to set axis KPI by KPI separately.

Not even talking about when adding a text label to the visual it can be pushed out from the picture.

Do you have any idea of a workaround that could solve this issue?

Thanks a lot!

Positive delta vs Negative delta


Solution

  • The domain can be calculated dynamically as +/- 10% from your data. e.g. this example with no fixing.

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {
        "values": [
          {"x": 1, "y": 10},
          {"x": 2, "y": 10},
          {"x": 3, "y": 10},
          {"x": 4, "y": 10},
          {"x": 5, "y": 10},
          {"x": 6, "y": 10},
          {"x": 7, "y": 10}
        ]
      },
      "mark": {"type": "line", "point": true},
      "encoding": {
        "x": {"field": "x", "type": "quantitative"},
        "y": {"field": "y", "type": "quantitative"}
      }
    }
    

    Here it is scaled dynamically.

    enter image description here

    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "data": {
        "values": [
          {"x": 1, "y": 10},
          {"x": 2, "y": 10},
          {"x": 3, "y": 10},
          {"x": 4, "y": 10},
          {"x": 5, "y": 10},
          {"x": 6, "y": 10},
          {"x": 7, "y": 10}
        ]
      },
      "transform": [
        {
          "joinaggregate": [
            {"op": "max", "field": "y", "as": "max"},
            {"op": "min", "field": "y", "as": "min"}
          ]
        },
        {"calculate": "datum.max * 1.2", "as": "max"},
        {"calculate": "datum.min * 0.8", "as": "min"}
      ],
      "params": [
        {"name": "max", "expr": "data('data_0')[0]['max']"},
        {"name": "min", "expr": "data('data_0')[0]['min']"}
      ],
      "mark": {"type": "line", "point": true},
      "encoding": {
        "x": {"field": "x", "type": "quantitative"},
        "y": {
          "field": "y",
          "type": "quantitative",
          "scale": {"domain": {"expr": "[min,max]"}}
        }
      }
    }