Is there a way to make Vega Lite work with web workers?
I tried something like that:
Vega Lite Web Workers
I found the basic idea here:
An update to the worker utility
Thank you very much!!!
Is there a way to make Vega Lite work with web workers?
I tried something like that:
Vega Lite Web Workers
I found the basic idea here:
An update to the worker utility
Thank you very much!!!
I donât think so, at least not in a straight-forward way. Observableâs vl
is a wrapper around multiple liibraries:
and importing that directly from stdlib will fail because the packages get loaded via d3-require, which expects a document
to attach the <script>
elements to:
bar_chart = worker`
return (async()=>{
const vl = await import("https://esm.run/@observablehq/stdlib")
.then(m => new m.Library())
.then(l => l.vl())
return (${plot_data})(${olympians});
})()
`
Thank you very much!!!
Is it possible with another library, e.g. d3 or Plot?
Or which library is the best fit for scalability?
For multiple plots like in this example:
Visualizing Pairwise Feature Interactions in Neural Additive Models
Just with bigger datasets, like MIMIC-III or California Housing, so that the Main Thread doesnât get blocked.
Thank you!
It usually requires a lot of work to noticeably block the main thread. In my experience youâre more likely to run into rendering performance issues with complex SVGs (unless youâre doing some heavy computation), so vega-lite may have an edge here because the Observable wrapper defaults to the canvas renderer.
If your browser starts to lag you can wrap the rendering of each Plot or chart in requestAnimationFrame() which should give the browser UI enough room to catch up.
In Observable notebooks you can also await each cellâs visibility()
promise which will only resolve once the cell is within the browserâs viewport:
myChart = (await visibility()), renderSomeChart()
or
myChart = {
await visibility();
return renderSomeChart();
}
For interactive charts that rerender on input changes you can debounce those updates if they happen too frequently.
In summary, I wouldnât worry about it unless youâre starting to see real issues.
Thank you!!!
I guess the main problem in my case is that all vega-lite plots get precomputed and are then displayed at once in a html-container.
I would have to rewrite the code, in a sense, that each plot is rendered separately, once finished.
Do you have a notebook that you can share?
Sure, if I load the California Housing dataset instead of the Penguins dataset, the whole notebook freezes for a minute.
Notebook:
Feature Interactions
Thank you!!!
The first thing that youâll want to change is to get rid of any document queries. In Observable you can name your cells and then reference HTML from variable names:
plotsContainer = html`<div id="plots-container"></div>`
{
const barChartContainers = plotsContainer.querySelectorAll(
".bar-chart-container"
);
// ....
The next thing to replace are side effect cells. In general youâll want to ensure that cells only affect their own output or the output of cells that depend on them, otherwise youâll run into dependency issues during imports, are prone to attaching event handlers that never get removed, and it becomes more difficult to reason about the dataflow in your notebook.
To ease the strain on the browser you can add a function
nextFrame = new Promise(resolve => requestAnimationFrame(resolve))
and then await it in precomputePlots()
:
// ...
const { key, dimension } = featureMap;
await nextFrame();
const plot =
// ...
The downside here of course is that it will still take forever before the results become visible. So an alternative might be turn precomputePlaceholders into a generator function and let Observable process the generator for you (which also happens via requestAnimationFrame ):
async function* precomputePlots(originalData, featureMaps, minMaxPerClass) {
// ...
precomputedPlots[className][key] = plot;
yield precomputedPlots;
// ...
Note however that every yield will cause downstream cells to invalidate, so youâll want to make sure that thereâs not much happening down the line. In my tests the sandbox iframe frequently crashed, likely due to GPU related issues.
Thank you very much! The generator hint works well in first tests.