@@ -5,14 +5,15 @@ 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.
1111
1212#[ wasm_bindgen]
1313extern "C" {
1414
15- /// A wrapper around the JavaScript `HTMLElement` representing a Plotly `<div>`.
15+ /// A wrapper around the JavaScript `HTMLElement` representing a Plotly
16+ /// `<div>`.
1617 ///
1718 /// This type extends `web_sys::HtmlElement` and exposes Plotly’s
1819 /// `.on(eventName, callback)` method for attaching event listeners.
@@ -37,17 +38,18 @@ extern "C" {
3738/// Bind a Rust callback to the Plotly `plotly_click` event on a given `<div>`.
3839///
3940/// # Type Parameters
40- /// - `F`: A `'static + FnMut(ClickEvent)` closure type to handle the click data.
41+ /// - `F`: A `'static + FnMut(ClickEvent)` closure type to handle the click
42+ /// data.
4143///
4244/// # Parameters
4345/// - `div_id`: The DOM `id` attribute of the Plotly `<div>`.
4446/// - `cb`: A mutable Rust closure that will be called with a `ClickEvent`.
4547///
4648/// # 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.
49+ /// 1. Looks up the element by `div_id`, converts it to `PlotlyDiv`.
50+ /// 2. Wraps a `Closure<dyn FnMut(JsValue)>` that deserializes the JS event
51+ /// into our `ClickEvent` type via `serde_wasm_bindgen`.
52+ /// 3. Calls `plot_div.on("plotly_click", …)` to register the listener.
5153/// 4. Forgets the closure so it lives for the lifetime of the page.
5254///
5355/// # Example
@@ -57,42 +59,42 @@ extern "C" {
5759/// });
5860/// ```
5961
60-
6162pub fn bind_click < F > ( div_id : & str , mut cb : F )
62- where
63- F : ' static + FnMut ( ClickEvent )
63+ where
64+ F : ' static + FnMut ( ClickEvent ) ,
6465{
65-
66- let plot_div: PlotlyDiv = window ( ) . unwrap ( )
67- . document ( ) . unwrap ( )
68- . get_element_by_id ( div_id) . unwrap ( )
66+ let plot_div: PlotlyDiv = window ( )
67+ . unwrap ( )
68+ . document ( )
69+ . unwrap ( )
70+ . get_element_by_id ( div_id)
71+ . unwrap ( )
6972 . unchecked_into ( ) ;
7073 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 " ) ;
74+ let event: ClickEvent =
75+ serde_wasm_bindgen :: from_value ( event ) . expect ( "\n Couldn't serialize the event \n " ) ;
7376 cb ( event) ;
7477 } ) as Box < dyn FnMut ( JsValue ) > ) ;
7578 plot_div. on ( "plotly_click" , & closure. as_ref ( ) . unchecked_ref ( ) ) ;
7679 closure. forget ( ) ;
7780}
7881
79-
8082/// Represents a single point from a Plotly click event.
8183///
8284/// Fields mirror Plotly’s `event.points[i]` properties, all optional
8385/// where appropriate:
8486///
8587/// - `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.
88+ /// - `point_numbers`: An optional list of indices if multiple points were
89+ /// selected.
8790/// - `point_number`: The index of the specific point clicked (if singular).
8891/// - `x`, `y`, `z`: Optional numeric coordinates in data space.
8992/// - `lat`, `lon`: Optional geographic coordinates (for map plots).
9093///
9194/// # Serialization
9295/// Uses `serde` with `camelCase` field names to match Plotly’s JS API.
9396
94-
95- #[ derive( Debug , Deserialize , Serialize , Default ) ]
97+ #[ derive( Debug , Deserialize , Serialize , Default ) ]
9698#[ serde( rename_all = "camelCase" ) ]
9799pub struct ClickPoint {
98100 pub curve_number : usize ,
@@ -102,33 +104,33 @@ pub struct ClickPoint {
102104 pub y : Option < f64 > ,
103105 pub z : Option < f64 > ,
104106 pub lat : Option < f64 > ,
105- pub lon : Option < f64 >
107+ pub lon : Option < f64 > ,
106108}
107109
108-
109110/// Provide a default single-point vector for `ClickEvent::points`.
110111///
111112/// Returns `vec![ClickPoint::default()]` so deserialization always yields
112113/// at least one element rather than an empty vector.
113114
114- fn default_click_event ( ) -> Vec < ClickPoint > { vec ! [ ClickPoint :: default ( ) ] }
115-
115+ fn default_click_event ( ) -> Vec < ClickPoint > {
116+ vec ! [ ClickPoint :: default ( ) ]
117+ }
116118
117119/// The top-level payload for a Plotly click event.
118120///
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.
121+ /// - `points`: A `Vec<ClickPoint>` containing all clicked points. Defaults to
122+ /// the result of `default_click_event` to ensure `points` is non-empty even
123+ /// if Plotly sends no data.
122124///
123125/// # Serialization
124126/// Uses `serde` with `camelCase` names and a custom default so you can
125127/// call `event.points` without worrying about missing values.
126128
127- #[ derive( Debug , Deserialize , Serialize ) ]
128- #[ serde( rename_all= "camelCase" , default ) ]
129+ #[ derive( Debug , Deserialize , Serialize ) ]
130+ #[ serde( rename_all = "camelCase" , default ) ]
129131pub struct ClickEvent {
130- #[ serde( default = "default_click_event" ) ]
131- pub points : Vec < ClickPoint >
132+ #[ serde( default = "default_click_event" ) ]
133+ pub points : Vec < ClickPoint > ,
132134}
133135
134136/// A `Default` implementation yielding an empty `points` vector.
@@ -139,4 +141,4 @@ impl Default for ClickEvent {
139141 fn default ( ) -> Self {
140142 ClickEvent { points : vec ! [ ] }
141143 }
142- }
144+ }
0 commit comments