This PR contains the first couple of steps toward using Avenger as an in-browser Vega renderer. Prior to this PR, the only way to render Vega charts with Avenger was to export the Vega SceneGraph to JSON using vl-convert, and then convert the JSON scenegraph to an Avenger SceneGraph with the avenger-vega crate.
This PR adds a new avenger-vega-renderer crates which compiles to WebAssembly (WASM) with wasm-pack. In contains some pure JavaScript code to implement and a Vega renderer which interfaces with avenger through the WASM API. Here is an example (from examples/vega-renderer` for a 40k scatter plot.
Initially, I tried deserializing the scenegraph object from JS to rust using serde, but this turned out to be really slow. It's much faster to build up TypedArrays on the JavaScript side and pass these across the WASM boundary. Unfortunately this will require reimplementing all of the avenger-vega logic in JavaScript, but the performance benefit will be worth it. So far, I've only implemented part of symbol, rule, and text marks.
Speaking of text, this PR refactors text support to abstract of the text layout/rasterization engine (e.g. cosmic-text). For the wasm build, text glyphs are rasterized to images using the browser's canvas text rendering engine. They are then stored in a text atlas and rendered on the GPU as with the cosmic-text engine.
I also added some initial testing support using the Python playwright library. Tests in this case are compared between the canvas renderer and the avenger renderer.
There is a lot of work left to do to fill out support translating all of the mark types to avenger in avenger-vega-renderer, but I wanted to make this it's own PR since it's already gotten pretty large.
This PR contains the first couple of steps toward using Avenger as an in-browser Vega renderer. Prior to this PR, the only way to render Vega charts with Avenger was to export the Vega SceneGraph to JSON using vl-convert, and then convert the JSON scenegraph to an Avenger SceneGraph with the
avenger-vega
crate.This PR adds a new
avenger-vega-renderer
crates which compiles to WebAssembly (WASM) with wasm-pack. In contains some pure JavaScript code to implement and a Vega renderer which interfaces with avenger through the WASM API. Here is an example (from examples/vega-renderer` for a 40k scatter plot.https://github.com/jonmmease/avenger/assets/15064365/4494c577-d7cd-437e-a380-bc302832523b
Initially, I tried deserializing the scenegraph object from JS to rust using serde, but this turned out to be really slow. It's much faster to build up TypedArrays on the JavaScript side and pass these across the WASM boundary. Unfortunately this will require reimplementing all of the
avenger-vega
logic in JavaScript, but the performance benefit will be worth it. So far, I've only implemented part of symbol, rule, and text marks.Speaking of text, this PR refactors text support to abstract of the text layout/rasterization engine (e.g. cosmic-text). For the wasm build, text glyphs are rasterized to images using the browser's canvas text rendering engine. They are then stored in a text atlas and rendered on the GPU as with the cosmic-text engine.
I also added some initial testing support using the Python playwright library. Tests in this case are compared between the canvas renderer and the avenger renderer.
There is a lot of work left to do to fill out support translating all of the mark types to avenger in
avenger-vega-renderer
, but I wanted to make this it's own PR since it's already gotten pretty large.