microBioRust_heatmap/
lib.rs1#![allow(non_snake_case)]
11pub mod heatmap_data;
12pub mod canvas;
13
14use canvas::drawing::draw_responsive_heatmap;
16use heatmap_data::HeatmapData;
17
18use wasm_bindgen::prelude::*;
20use wasm_bindgen::JsValue;
21use web_sys::{window, HtmlCanvasElement, CanvasRenderingContext2d};
22use web_sys::console;
23use std::rc::Rc;
24
25#[wasm_bindgen(start)]
27pub fn start() -> Result<(), JsValue> {
28 console::log_1(&JsValue::from_str(&format!("literal start")));
30 let window = window().ok_or(JsValue::from_str("should have a window in this context"))?;
31 let window = Rc::new(window);
32 let window_clone = Rc::clone(&window);
33 let document = window.document().ok_or(JsValue::from_str("no document"))?;
34 console::log_1(&JsValue::from_str(&format!("up in the start of the function")));
35 let canvas = document
37 .get_element_by_id("heatmap")
38 .ok_or(JsValue::from_str("Canvas element not found"))?
39 .dyn_into::<HtmlCanvasElement>()?;
40 console::log_1(&JsValue::from_str(&format!("called the canvas")));
41 let heatmap_values = vec![
42 vec![2, 1, 0, 1, 0], vec![1, 2, 0, 0, 1], vec![2, 0, 1, 2, 1], vec![0, 0, 0, 2, 0], vec![1, 2, 0, 1, 1], ];
48 console::log_1(&JsValue::from_str(&format!("called the heatmap vals")));
49 let x_labels: Vec<String> = vec!["A", "B", "C", "D", "E"].iter().map(|s| s.to_string()).collect();
50 let y_labels: Vec<String> = vec!["R1", "R2", "R3", "R4", "R5"].iter().map(|s| s.to_string()).collect();
51
52 let num_rows = heatmap_values.len(); let num_cols = heatmap_values[0].len(); let mut heatmap_data = HeatmapData::new();
55 heatmap_data.values = heatmap_values.clone();
56 heatmap_data.x_labels = x_labels.clone();
57 heatmap_data.y_labels = y_labels.clone();
58 let box_size = 100.0;
59 let device_pixel_ratio = window.device_pixel_ratio();
60 console::log_1(&JsValue::from_str(&format!("num rows are {:?} num cols are {:?}", &num_rows, &num_cols)));
61
62 let canvas_width = num_cols as f64 * box_size; let canvas_height = num_rows as f64 * box_size; canvas.set_width(canvas_width as u32);
66 canvas.set_height(canvas_height as u32);
67 console::log_1(&JsValue::from_str(&format!(
68 "Canvas width: {}, height: {}",
69 canvas.width(),
70 canvas.height()
71 )));
72
73 let context = canvas
74 .get_context("2d")?
75 .ok_or(JsValue::from_str("Context not found"))?
76 .dyn_into::<CanvasRenderingContext2d>()?;
77
78 context.scale(device_pixel_ratio, device_pixel_ratio)?;
80
81 draw_responsive_heatmap(
82 &context,
83 heatmap_values.clone(),
84 x_labels.clone(),
85 y_labels.clone(),
86 canvas_width,
87 canvas_height,
88 device_pixel_ratio,
89 )?;
90
91 let handle_heatmap_resize = move || -> Result<(), JsValue> {
92 let new_width = window_clone.inner_width()
93 .map_err(|_| JsValue::from_str("error getting inner width"))?
94 .as_f64()
95 .ok_or(JsValue::from_str("error converting width to f64"))?;
96
97 let new_height = window_clone.inner_height()
98 .map_err(|_| JsValue::from_str("error getting inner height"))?
99 .as_f64()
100 .ok_or(JsValue::from_str("error converting height to f64"))?;
101
102 let canvas_new_width = (num_cols as f64 * box_size).min(new_width);
103 let canvas_new_height = (num_rows as f64 * box_size).min(new_height);
104
105 canvas.set_width(canvas_new_width as u32);
106 canvas.set_height(canvas_new_height as u32);
107
108 context.set_transform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)
109 .map_err(|_| JsValue::from_str("error setting transform"))?;
110 context.scale(device_pixel_ratio, device_pixel_ratio)
111 .map_err(|_| JsValue::from_str("error scaling context"))?;
112
113 draw_responsive_heatmap(
114 &context,
115 heatmap_values.clone(),
116 x_labels.clone(),
117 y_labels.clone(),
118 canvas_new_width,
119 canvas_new_height,
120 device_pixel_ratio,
121 )?;
122 Ok(())
123 };
124
125 let error_handled_heatmap_resize = move || {
127 if let Err(e) = handle_heatmap_resize() {
128 console::error_1(&e);
129 }
130 };
131
132 let closure = Closure::wrap(Box::new(error_handled_heatmap_resize) as Box<dyn FnMut()>);
133
134 window.add_event_listener_with_callback("resize", closure.as_ref().unchecked_ref())?;
135 closure.forget();
136
137 Ok(())
138}