powerbivisualizationpowerbi-desktopvega-litedeneb

Vega-Lite (Deneb) | Waterfall Chart (Start & End Column Problem)


I have hit a dead-end trying to create both a BEGIN / END column for a waterfall chart.

I've managed to create the END column which correctly sits at the end of the X-axis (Jan to Dec). However, I'm unable to successfully add the BEGIN column to appear before the Jan on the x-axis. It either doesn't appear, or sits after Jan insteaod of before. Sorting the x-axis doesn't appear to work either.

Is this possible to do directly in Vega-Lite?

Here is the link to the pbix: waterfall_pbix_file

Here is a screen shot of my current failed attempts. waterfall attempt

I hope I've provided enough information. Thank you for your help in advance!

{
  "data": {
    "name": "dataset"
  },
  "transform": [
    {
      "sort": [
        {
          "field": "MonthNo"
        }
      ],
      "window": [
        {
          "op": "lag",
          "field": "salesCY",
          "as": "salesCY_previous"
        },
        {
          "op": "lag",
          "field": "Month",
          "as": "month_previous"
        },
        {
          "op": "lead",
          "field": "salesCY",
          "as": "salesCY_following"
        },
        {
          "op": "lead",
          "field": "Month",
          "as": "month_following"
        }
      ]
    },
    {
      "calculate": "datum.month_previous == null ? 'BEGIN' : datum.month_previous",
      "as": "month_previous"
    },
    {
      "calculate": "datum.month_following == null ? 'END' : datum.month_following",
      "as": "month_following"
    },
    {
      "calculate": "datum.month_previous === 'BEGIN' ? -999 : datum.month_following === 'END' ? 999 : datum.MonthNo",
      "as": "sort_order"
    }
  ],
  "width": 500,
  "height": 200,
  "layer": [
    {
      "mark": {
        "type": "bar",
        "fill": {
          "expr": "datum.salesCY > datum.salesCY_previous ? '#0291DC' : '#F0535A' "
        },
        "width": {
          "band": 0.8
        }
      }
    },
    {
      "transform": [
        {
          "filter": "datum.month_previous == 'BEGIN'"
        }
      ],
      "mark": {
        "type": "bar",
        "fill": "lightgrey",
        "stroke": "black",
        "strokeWidth": 0.5,
        "width": {
          "band": 0.8
        }
      },
      "encoding": {
        "x": {
          "field": "month_previous",
          "type": "nominal",
          "axis": {
            "title": null,
            "labels": true,
            "labelFontSize": 15,
            "labelColor": "grey",
            "labelExpr": "datum.label[0]",
            "labelAngle": 0,
            "labelPadding": 15,
            "domain": false,
            "ticks": false
          },
          "sort": {
            "field": "sort_order",
            "order": "ascending"
          },
          "scale": {
            "zero": true
          }
        },
        "y2": {
          "datum": 0,
          "type": "quantitative",
          "axis": {
            "title": null,
            "labels": false,
            "domain": false,
            "ticks": false,
            "grid": false
          }
        },
        "y": {
          "field": "salesCY",
          "type": "quantitative",
          "axis": {
            "title": null,
            "labels": false,
            "domain": false,
            "ticks": false,
            "grid": false
          }
        }
      }
    },
    {
      "transform": [
        {
          "filter": "datum.month_following == 'END'"
        }
      ],
      "mark": {
        "type": "bar",
        "fill": "black",
        "width": {
          "band": 0.8
        }
      },
      "encoding": {
        "x": {
          "field": "month_following",
          "type": "nominal",
          "axis": {
            "title": null,
            "labels": true,
            "labelColor": "grey",
            "labelExpr": "datum.label[0]",
            "labelAngle": 0,
            "domain": false,
            "ticks": false
          },
          "sort": null,
          "scale": {
            "zero": true
          }
        },
        "y2": {
          "datum": 0,
          "type": "quantitative",
          "axis": {
            "title": null,
            "labels": false,
            "domain": false,
            "ticks": false,
            "grid": false
          }
        },
        "y": {
          "field": "salesCY",
          "type": "quantitative",
          "axis": {
            "title": null,
            "labels": false,
            "domain": false,
            "ticks": false,
            "grid": false
          }
        }
      }
    }
  ],
  "encoding": {
    "x": {
      "field": "Month",
      "type": "nominal",
      "axis": {
        "title": null,
        "labels": true,
        "labelColor": "grey",
        "labelExpr": "datum.label[0]",
        "labelAngle": 0,
        "domain": false,
        "ticks": false
      },
      "sort": {
        "field": "sort_order",
        "type": "ordinal"
      },
      "scale": {
        "zero": true
      }
    },
    "y2": {
      "field": "salesCY_previous",
      "type": "quantitative",
      "axis": {
        "title": null,
        "labels": false,
        "domain": false,
        "ticks": false,
        "grid": false
      }
    },
    "y": {
      "field": "salesCY",
      "type": "quantitative",
      "axis": {
        "title": null,
        "labels": false,
        "domain": false,
        "ticks": false,
        "grid": false
      }
    }
  }
}

Solution

  • Try this:

    {
      "data": {
        "name": "dataset"
      },
      "transform": [
        {
          "sort": [
            {
              "field": "MonthNo"
            }
          ],
          "window": [
            {
              "op": "lag",
              "field": "salesCY",
              "as": "salesCY_previous"
            },
            {
              "op": "lag",
              "field": "Month",
              "as": "month_previous"
            },
            {
              "op": "lead",
              "field": "salesCY",
              "as": "salesCY_following"
            },
            {
              "op": "lead",
              "field": "Month",
              "as": "month_following"
            }
          ]
        },
        {
          "calculate": "datum.month_previous == null ? 'BEGIN' : datum.month_previous",
          "as": "month_previous"
        },
        {
          "calculate": "datum.month_following == null ? 'END' : datum.month_following",
          "as": "month_following"
        },
        {
          "calculate": "datum.MonthNo",
          "as": "sort_order"
        }
      ],
      "width": 500,
      "height": 200,
      "layer": [
        {
          "mark": {
            "type": "bar",
            "fill": {
              "expr": "datum.salesCY > datum.salesCY_previous ? '#0291DC' : '#F0535A' "
            },
            "width": {
              "band": 0.8
            }
          }
        },
        {
          // CANT SEEM TO FIX THIS MARK TO APPEAR BEFORE THE JAN MONTH COLUMN
          "transform": [
            {
              "filter": "datum.month_previous == 'BEGIN'"
            },
            {
              "calculate": "-1",
              "as": "sort_order"
            }
          ],
          "mark": {
            "type": "bar",
            "fill": "lightgrey",
            "stroke": "black",
            "strokeWidth": 0.5,
            "width": {
              "band": 0.8
            }
          },
          "encoding": {
            "x": {
              "field": "month_previous",
              "type": "nominal",
              "axis": {
                "title": null,
                "labels": true,
                "labelFontSize": 15,
                "labelColor": "grey",
                "labelExpr": "datum.label[0]",
                "labelAngle": 0,
                "labelPadding": 15,
                "domain": false,
                "ticks": false
              },
              "sort": null,
              "scale": {
                "zero": true
              }
            },
            "y2": {
              "datum": 0,
              "type": "quantitative",
              "axis": {
                "title": null,
                "labels": false,
                "domain": false,
                "ticks": false,
                "grid": false
              }
            },
            "y": {
              "field": "salesCY",
              "type": "quantitative",
              "axis": {
                "title": null,
                "labels": false,
                "domain": false,
                "ticks": false,
                "grid": false
              }
            }
          }
        },
        {
          "transform": [
            {
              "filter": "datum.month_following == 'END'"
            },
            {
              "calculate": "1e6",
              "as": "sort_order"
            }
          ],
          "mark": {
            "type": "bar",
            "fill": "black",
            "width": {
              "band": 0.8
            }
          },
          "encoding": {
            "x": {
              "field": "month_following",
              "type": "nominal",
              "axis": {
                "title": null,
                "labels": true,
                "labelColor": "grey",
                "labelExpr": "datum.label[0]",
                "labelAngle": 0,
                "domain": false,
                "ticks": false
              },
              "sort": null,
              "scale": {
                "zero": true
              }
            },
            "y2": {
              "datum": 0,
              "type": "quantitative",
              "axis": {
                "title": null,
                "labels": false,
                "domain": false,
                "ticks": false,
                "grid": false
              }
            },
            "y": {
              "field": "salesCY",
              "type": "quantitative",
              "axis": {
                "title": null,
                "labels": false,
                "domain": false,
                "ticks": false,
                "grid": false
              }
            }
          }
        }
      ],
      "encoding": {
        "x": {
          "field": "Month",
          "type": "nominal",
          "axis": {
            "title": null,
            "labels": true,
            "labelColor": "grey",
            "labelExpr": "datum.label[0]",
            "labelAngle": 0,
            "domain": false,
            "ticks": false
          },
          "sort": {
            "field": "sort_order",
            "order": "ascending"
          },
          "scale": {
            "zero": true
          }
        },
        "y2": {
          "field": "salesCY_previous",
          "type": "quantitative",
          "axis": {
            "title": null,
            "labels": false,
            "domain": false,
            "ticks": false,
            "grid": false
          }
        },
        "y": {
          "field": "salesCY",
          "type": "quantitative",
          "axis": {
            "title": null,
            "labels": false,
            "domain": false,
            "ticks": false,
            "grid": false
          }
        }
      }
    }