charming_fork_zephyr/renderer/
wasm_renderer.rs1use crate::{theme::Theme, Chart, EchartsError};
2use serde::Serialize;
3use serde_wasm_bindgen::to_value;
4use wasm_bindgen::prelude::*;
5use wasm_bindgen::JsValue;
6
7pub struct WasmRenderer {
8 theme: Theme,
9 width: u32,
10 height: u32,
11}
12
13impl WasmRenderer {
14 pub fn new(width: u32, height: u32) -> Self {
15 Self {
16 theme: Theme::Default,
17 width,
18 height,
19 }
20 }
21
22 pub fn theme(mut self, theme: Theme) -> Self {
23 self.theme = theme;
24 self
25 }
26
27 pub fn render(&self, id: &str, chart: &Chart) -> Result<Echarts, EchartsError> {
28 let window = web_sys::window().ok_or(EchartsError::WasmError(
29 "no `window` object found".to_string(),
30 ))?;
31 let document = window.document().ok_or(EchartsError::WasmError(
32 "no `document` object found".to_string(),
33 ))?;
34 let element = document
35 .get_element_by_id(id)
36 .ok_or(EchartsError::WasmError(format!(
37 "no element with id `{}` found",
38 id
39 )))?;
40 let echarts = init(
41 &element,
42 self.theme.to_str().0,
43 to_value(&ChartSize {
44 width: self.width,
45 height: self.height,
46 })
47 .unwrap(),
48 );
49 echarts.set_option(to_value(chart).unwrap());
50
51 Ok(echarts)
52 }
53
54 pub fn resize_chart(echarts: &Echarts, chart_size: ChartResize) {
56 echarts
57 .resize(to_value(&chart_size).expect("could not convert resize options to `JsValue`"));
58 }
59
60 pub fn update(echarts: &Echarts, chart: &Chart) {
61 echarts.set_option(to_value(chart).unwrap());
62 }
63}
64
65#[derive(Serialize)]
66struct ChartSize {
67 width: u32,
68 height: u32,
69}
70
71#[derive(Serialize)]
72pub struct ChartResize {
73 width: u32,
75 height: u32,
77 silent: bool,
79 animation: Option<Animation>,
81}
82
83#[derive(Serialize)]
84pub struct Animation {
85 pub duration: u32,
87 #[serde(skip_serializing_if = "Option::is_none")]
89 pub easing: Option<Easing>,
90}
91
92#[derive(Clone, Debug, Default, Serialize)]
94#[serde(rename_all = "camelCase")]
95pub enum Easing {
96 #[default]
97 Linear,
98 QuadraticIn,
99 QuadraticOut,
100 QuadraticInOut,
101 CubicIn,
102 CubicOut,
103 CubicInOut,
104 QuarticIn,
105 QuarticOut,
106 QuarticInOut,
107 QuinticIn,
108 QuinticOut,
109 QuinticInOut,
110 SinusoidalIn,
111 SinusoidalOut,
112 SinusoidalInOut,
113 ExponentialIn,
114 ExponentialOut,
115 ExponentialInOut,
116 CircularIn,
117 CircularOut,
118 CircularInOut,
119 ElasticIn,
120 ElasticOut,
121 ElasticInOut,
122 BackIn,
123 BackOut,
124 BackInOut,
125 BounceIn,
126 BounceOut,
127 BounceInOut,
128}
129
130impl Default for Animation {
131 fn default() -> Self {
132 Self {
133 duration: 100,
134 easing: Some(Easing::default()),
135 }
136 }
137}
138
139impl Animation {
140 pub fn new(duration: u32, easing: Option<Easing>) -> Self {
141 Self {
142 duration,
143 easing: easing.or_else(|| Some(Easing::default())),
144 }
145 }
146}
147
148#[wasm_bindgen]
149extern "C" {
150 #[wasm_bindgen(js_name = echarts)]
151 pub type Echarts;
152
153 #[wasm_bindgen(js_namespace = echarts, js_name = init)]
154 fn init(id: &web_sys::Element, theme: &str, size: JsValue) -> Echarts;
155
156 #[wasm_bindgen(method, js_name = "setOption")]
157 fn set_option(this: &Echarts, option: JsValue);
158
159 #[wasm_bindgen(method, js_name = "resize")]
160 pub fn resize(this: &Echarts, opts: JsValue);
161}