How to translate vega-lite window transform grammar to pure vega-lite-api code?

I came across following vega-lite grammar example in the docs:

{
  "data": {"url": "data/movies.json"},
  "transform": [{
    "sort": [{"field": "IMDB Rating"}],
    "window": [{"op": "count", "field": "count", "as": "Cumulative Count"}],
    "frame": [null, 0]
  }],
  "mark": "area",
  "encoding": {
    "x": {
      "field": "IMDB Rating",
      "type": "quantitative"
    },
    "y": {
      "field": "Cumulative Count",
      "type": "quantitative"
    }
  }
}

I am trying to generate the same plot using vega-lite-api.
I can do it as follows:

   const plot = vl.markArea()
                    .data(data)
                    .transform(
                        {
                            "sort": [{"field": "IMDB Rating"}],
                            "window": [{"op": "count", "field": "count", "as": "Cumulative Count"}],
                            "frame": [null, 0]
                        }
                    )
                    .encode(
                        vl.x().fieldQ('IMDB Rating'),
                        vl.y().fieldQ('Cumulative Count')
                    )
    return plot.toObject();
}

It generates the same cdf plot. I have following doubt:

Q. As you can see in above vega-lite-api code, I have specified following vega-lite grammar inside transform():

{
    "sort": [{"field": "IMDB Rating"}],
    "window": [{"op": "count", "field": "count", "as": "Cumulative Count"}],
    "frame": [null, 0]
}

How can I do the same with pure vega-lite-api, using window() API?

You may have discovered by now that Vega-Lite isn’t supported very well through this forum. I’d suggest to try the official support channels:

(from A High-Level Grammar of Interactive Graphics | Vega-Lite)

Then what is preferred here for visualization? I have already posted on stackoverflow few days back, but have no response. Also got no response for some hours on slack too.

One option is Observable Plot, our own visualization library. (Though you are welcome to use Vega-Lite or any other visualization library on Observable! I’m just mentioning Plot because you’re more likely to get help with it here.) Here’s how you’d do this with Plot:

Plot.plot({
  marks: [
    Plot.areaY(movies, Plot.map({y1: "cumsum"}, {x: "IMDB Rating", y: 1, sort: "IMDB Rating"})),
    Plot.ruleY([0])
  ]
})

I think this in fact shows a bug in the Vega-Lite example, where they are treating the 213 data points with a null IMDb rating as a rating of zero (hence the cliff at ~1.4, the lowest non-null IMDb rating in this dataset).

If you want more of a continuous curve, rather than steps at each discrete change in rating (there is only one decimal point of precision in the ratings here), you could apply the group transform.

Plot.plot({
  marks: [
    Plot.areaY(movies, Plot.mapY("cumsum", Plot.groupX({y: "count"}, {x: "IMDB Rating"}))),
    Plot.ruleY([0])
  ]
})

Another possibility for this data, if you want more control over the aggregation, is to combine the bin transform and rect mark:

Plot.plot({
  marks: [
    Plot.rectY(movies, Plot.binX({y: "count", cumulative: true}, {x: "IMDB Rating"})),
    Plot.ruleY([0])
  ]
})

Live notebook: Cumulative IMDb ratings plot / Observable / Observable

Ohh!! Thanks for suggesting observable plot. Surprisingly I wasnt aware of it. I started with d3, and found that d3 is overkill for routine charting with moderate customization need. So I explored and found that people are using vega-lite a lot. I want to prepare some dashboards for a website. Can you give some quick points for observable plots vs vega-lite in the context of website dashboard making?
I referred this comparison, plot docs. I vega-lite seems more matured, but am finding it difficult to get hold of its expression language, on the other hand plot seems new, but seems more intuitive as it uses plain JS and has great docs.

Any suggestions for vega-lite vs plot for website dashboard development?