Skip to content

[Feature Request] Available in WebAssembly within web worker #482

Open

Description

@lyhanburger

What is the feature ?

I'd like use plotters wasm in the web worker, but the plotters/src/style/font/web.rs estimate_layout method use the window. Worker has any window context.

(Optional) Why this feature is useful and how people would use the feature ?

  1. Improving rendering efficiency when multiple charts are present.
  2. I prefer performing heavy data processing in a worker and, once the data processing is complete, invoking the chart within the worker instead of sending the chart data back to the main thread.

(Optional) Additional Information

I have implemented a simple version of it,it worked for me. (base the plotters 0.3.5)

// plotters/src/style/font/web.rs
    fn estimate_layout(&self, size: f64, text: &str) -> Result<LayoutBox, Self::ErrorType> {
        let canvas = OffscreenCanvas::new(300, 300).unwrap();
        let context = canvas
            .get_context("2d")
            .ok()
            .unwrap()
            .unwrap()
            .dyn_into::<OffscreenCanvasRenderingContext2d>()
            .unwrap();
        context.set_font(&format!("{}px {}", size, self.0));
        context.fill_text(&text, 0.0, 0.0);
        let bbox = context.measure_text(&text).unwrap();
        let width = bbox.width();
        let ascent = bbox.font_bounding_box_ascent();
        let descent = bbox.font_bounding_box_descent();
        let height = (descent - ascent).abs();
        // let window = window().unwrap();
        // let document = window.document().unwrap();
        // let body = document.body().unwrap();
        // let span = document.create_element("span").unwrap();
        // span.set_text_content(Some(text));
        // span.set_attribute("style", &format!("display: inline-block; font-family:{}; font-size: {}px; position: fixed; top: 100%", self.0, size)).unwrap();
        // let span = span.into();
        // body.append_with_node_1(&span).unwrap();
        // let elem = JsCast::dyn_into::<HtmlElement>(span).unwrap();
        // let height = elem.offset_height() as i32;
        // let width = elem.offset_width() as i32;
        // elem.remove();
        Ok(((0, 0), (width as i32, height as i32)))
    }
[target.'cfg(all(target_arch = "wasm32", not(target_os = "wasi")))'.dependencies.web-sys]
version = "0.3.64"
features = [
        "Document",
        "DomRect",
        "Element",
        "HtmlElement",
        "Node",
        "Window",
        "HtmlCanvasElement",
        "CanvasRenderingContext2d",
        # new add
        "OffscreenCanvas",
        "OffscreenCanvasRenderingContext2d",
        "TextMetrics",
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions