@@ -5,14 +5,14 @@ use web_sys::{js_sys::Function, window, HtmlElement};
55/// Provides utilities for binding Plotly.js click events to Rust closures
66/// via `wasm-bindgen`.
77///
8- /// This module defines a `PlotlyDiv` foreign type for the Plotly `<div>` element,
9- /// a high-level `bind_click` function to wire up Rust callbacks, and
8+ /// This module defines a `PlotlyDiv` foreign type for the Plotly `<div>`
9+ /// element, a high-level `bind_click` function to wire up Rust callbacks, and
1010/// the `ClickPoint`/`ClickEvent` data structures to deserialize event payloads.
11-
1211#[ wasm_bindgen]
1312extern "C" {
1413
15- /// A wrapper around the JavaScript `HTMLElement` representing a Plotly `<div>`.
14+ /// A wrapper around the JavaScript `HTMLElement` representing a Plotly
15+ /// `<div>`.
1616 ///
1717 /// This type extends `web_sys::HtmlElement` and exposes Plotly’s
1818 /// `.on(eventName, callback)` method for attaching event listeners.
@@ -37,17 +37,18 @@ extern "C" {
3737/// Bind a Rust callback to the Plotly `plotly_click` event on a given `<div>`.
3838///
3939/// # Type Parameters
40- /// - `F`: A `'static + FnMut(ClickEvent)` closure type to handle the click data.
40+ /// - `F`: A `'static + FnMut(ClickEvent)` closure type to handle the click
41+ /// data.
4142///
4243/// # Parameters
4344/// - `div_id`: The DOM `id` attribute of the Plotly `<div>`.
4445/// - `cb`: A mutable Rust closure that will be called with a `ClickEvent`.
4546///
4647/// # Details
47- /// 1. Looks up the element by `div_id`, converts it to `PlotlyDiv`.
48- /// 2. Wraps a `Closure<dyn FnMut(JsValue)>` that deserializes the JS event
49- /// into our `ClickEvent` type via `serde_wasm_bindgen`.
50- /// 3. Calls `plot_div.on("plotly_click", …)` to register the listener.
48+ /// 1. Looks up the element by `div_id`, converts it to `PlotlyDiv`.
49+ /// 2. Wraps a `Closure<dyn FnMut(JsValue)>` that deserializes the JS event into
50+ /// our `ClickEvent` type via `serde_wasm_bindgen`.
51+ /// 3. Calls `plot_div.on("plotly_click", …)` to register the listener.
5152/// 4. Forgets the closure so it lives for the lifetime of the page.
5253///
5354/// # Example
@@ -56,43 +57,41 @@ extern "C" {
5657/// web_sys::console::log_1(&format!("{:?}", evt).into());
5758/// });
5859/// ```
59-
60-
6160pub fn bind_click < F > ( div_id : & str , mut cb : F )
62- where
63- F : ' static + FnMut ( ClickEvent )
61+ where
62+ F : ' static + FnMut ( ClickEvent ) ,
6463{
65-
66- let plot_div: PlotlyDiv = window ( ) . unwrap ( )
67- . document ( ) . unwrap ( )
68- . get_element_by_id ( div_id) . unwrap ( )
64+ let plot_div: PlotlyDiv = window ( )
65+ . unwrap ( )
66+ . document ( )
67+ . unwrap ( )
68+ . get_element_by_id ( div_id)
69+ . unwrap ( )
6970 . unchecked_into ( ) ;
7071 let closure = Closure :: wrap ( Box :: new ( move |event : JsValue | {
71- let event: ClickEvent = serde_wasm_bindgen :: from_value ( event )
72- . expect ( "\n Couldn't serialize the event \n " ) ;
72+ let event: ClickEvent =
73+ serde_wasm_bindgen :: from_value ( event ) . expect ( "\n Couldn't serialize the event \n " ) ;
7374 cb ( event) ;
7475 } ) as Box < dyn FnMut ( JsValue ) > ) ;
75- plot_div. on ( "plotly_click" , & closure. as_ref ( ) . unchecked_ref ( ) ) ;
76+ plot_div. on ( "plotly_click" , closure. as_ref ( ) . unchecked_ref ( ) ) ;
7677 closure. forget ( ) ;
7778}
7879
79-
8080/// Represents a single point from a Plotly click event.
8181///
8282/// Fields mirror Plotly’s `event.points[i]` properties, all optional
8383/// where appropriate:
8484///
8585/// - `curve_number`: The zero-based index of the trace that was clicked.
86- /// - `point_numbers`: An optional list of indices if multiple points were selected.
86+ /// - `point_numbers`: An optional list of indices if multiple points were
87+ /// selected.
8788/// - `point_number`: The index of the specific point clicked (if singular).
8889/// - `x`, `y`, `z`: Optional numeric coordinates in data space.
8990/// - `lat`, `lon`: Optional geographic coordinates (for map plots).
9091///
9192/// # Serialization
9293/// Uses `serde` with `camelCase` field names to match Plotly’s JS API.
93-
94-
95- #[ derive( Debug , Deserialize , Serialize , Default ) ]
94+ #[ derive( Debug , Deserialize , Serialize , Default ) ]
9695#[ serde( rename_all = "camelCase" ) ]
9796pub struct ClickPoint {
9897 pub curve_number : usize ,
@@ -102,41 +101,38 @@ pub struct ClickPoint {
102101 pub y : Option < f64 > ,
103102 pub z : Option < f64 > ,
104103 pub lat : Option < f64 > ,
105- pub lon : Option < f64 >
104+ pub lon : Option < f64 > ,
106105}
107106
108-
109107/// Provide a default single-point vector for `ClickEvent::points`.
110108///
111109/// Returns `vec![ClickPoint::default()]` so deserialization always yields
112110/// at least one element rather than an empty vector.
113-
114- fn default_click_event ( ) -> Vec < ClickPoint > { vec ! [ ClickPoint :: default ( ) ] }
115-
111+ fn default_click_event ( ) -> Vec < ClickPoint > {
112+ vec ! [ ClickPoint :: default ( ) ]
113+ }
116114
117115/// The top-level payload for a Plotly click event.
118116///
119- /// - `points`: A `Vec<ClickPoint>` containing all clicked points.
120- /// Defaults to the result of `default_click_event` to ensure
121- /// `points` is non-empty even if Plotly sends no data.
117+ /// - `points`: A `Vec<ClickPoint>` containing all clicked points. Defaults to
118+ /// the result of `default_click_event` to ensure `points` is non-empty even
119+ /// if Plotly sends no data.
122120///
123121/// # Serialization
124122/// Uses `serde` with `camelCase` names and a custom default so you can
125123/// call `event.points` without worrying about missing values.
126-
127- #[ derive( Debug , Deserialize , Serialize ) ]
128- #[ serde( rename_all="camelCase" , default ) ]
124+ #[ derive( Debug , Deserialize , Serialize ) ]
125+ #[ serde( rename_all = "camelCase" , default ) ]
129126pub struct ClickEvent {
130- #[ serde( default = "default_click_event" ) ]
131- pub points : Vec < ClickPoint >
127+ #[ serde( default = "default_click_event" ) ]
128+ pub points : Vec < ClickPoint > ,
132129}
133130
134131/// A `Default` implementation yielding an empty `points` vector.
135132///
136133/// Useful when you need a zero-event placeholder (e.g., initial state).
137-
138134impl Default for ClickEvent {
139135 fn default ( ) -> Self {
140136 ClickEvent { points : vec ! [ ] }
141137 }
142- }
138+ }
0 commit comments