scirs2_metrics/visualization/advanced_interactive/
widgets.rs

1//! Interactive widget system for advanced visualization
2//!
3//! This module provides the widget framework for creating interactive
4//! dashboard components with real-time data binding and user interactions.
5
6#![allow(clippy::too_many_arguments)]
7#![allow(dead_code)]
8
9use super::core::{Position, Size};
10use crate::error::{MetricsError, Result};
11use serde::{Deserialize, Serialize};
12use serde_json::Value;
13use std::collections::HashMap;
14use std::time::{Duration, Instant};
15
16/// Interactive widget trait
17pub trait InteractiveWidget: std::fmt::Debug + Send + Sync {
18    /// Get widget ID
19    fn id(&self) -> &str;
20
21    /// Get widget type
22    fn widget_type(&self) -> WidgetType;
23
24    /// Update widget with new data
25    fn update_data(&mut self, data: Value) -> Result<()>;
26
27    /// Handle user interaction
28    fn handle_interaction(&mut self, event: WidgetEvent) -> Result<Option<WidgetEventResponse>>;
29
30    /// Render widget to context
31    fn render(&self, context: &RenderContext) -> Result<WidgetRender>;
32
33    /// Get widget configuration
34    fn config(&self) -> &WidgetConfig;
35
36    /// Update widget configuration
37    fn update_config(&mut self, config: WidgetConfig) -> Result<()>;
38
39    /// Get current state
40    fn state(&self) -> Value;
41
42    /// Restore from state
43    fn restore_state(&mut self, state: Value) -> Result<()>;
44
45    /// Validate widget data
46    fn validate_data(&self, data: &Value) -> Result<()>;
47}
48
49/// Widget type enumeration
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub enum WidgetType {
52    /// Chart widget (line, bar, scatter, etc.)
53    Chart(ChartType),
54    /// Table widget
55    Table,
56    /// Text widget
57    Text,
58    /// Input widget (slider, dropdown, etc.)
59    Input(InputType),
60    /// Container widget
61    Container,
62    /// Custom widget
63    Custom(String),
64}
65
66/// Chart type enumeration
67#[derive(Debug, Clone, Serialize, Deserialize)]
68pub enum ChartType {
69    /// Line chart
70    Line,
71    /// Bar chart
72    Bar,
73    /// Scatter plot
74    Scatter,
75    /// Heatmap
76    Heatmap,
77    /// Pie chart
78    Pie,
79    /// Area chart
80    Area,
81    /// Histogram
82    Histogram,
83    /// Box plot
84    BoxPlot,
85}
86
87/// Input type enumeration
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub enum InputType {
90    /// Slider input
91    Slider,
92    /// Dropdown selection
93    Dropdown,
94    /// Text input
95    TextInput,
96    /// Checkbox
97    Checkbox,
98    /// Radio buttons
99    RadioButton,
100    /// Date picker
101    DatePicker,
102    /// File upload
103    FileUpload,
104}
105
106/// Widget configuration
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct WidgetConfig {
109    /// Widget ID
110    pub id: String,
111    /// Widget title
112    pub title: String,
113    /// Position in the dashboard
114    pub position: Position,
115    /// Size of the widget
116    pub size: Size,
117    /// Style configuration
118    pub style: StyleConfig,
119    /// Data binding configuration
120    pub data_binding: DataBindingConfig,
121    /// Interaction settings
122    pub interactions_enabled: bool,
123    /// Animation settings
124    pub animation_enabled: bool,
125    /// Visibility
126    pub visible: bool,
127    /// z-index for layering
128    pub z_index: i32,
129}
130
131/// Style configuration
132#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct StyleConfig {
134    /// Background color
135    pub background_color: String,
136    /// Border configuration
137    pub border: BorderConfig,
138    /// Shadow configuration
139    pub shadow: ShadowConfig,
140    /// Font configuration
141    pub font: FontConfig,
142    /// Custom CSS classes
143    pub css_classes: Vec<String>,
144    /// Custom CSS properties
145    pub css_properties: HashMap<String, String>,
146}
147
148/// Border configuration
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct BorderConfig {
151    /// Border width
152    pub width: u32,
153    /// Border color
154    pub color: String,
155    /// Border style
156    pub style: BorderStyle,
157    /// Border radius
158    pub radius: u32,
159}
160
161/// Border style enumeration
162#[derive(Debug, Clone, Serialize, Deserialize)]
163pub enum BorderStyle {
164    /// Solid border
165    Solid,
166    /// Dashed border
167    Dashed,
168    /// Dotted border
169    Dotted,
170    /// No border
171    None,
172}
173
174/// Shadow configuration
175#[derive(Debug, Clone, Serialize, Deserialize)]
176pub struct ShadowConfig {
177    /// Enable shadow
178    pub enabled: bool,
179    /// Shadow offset X
180    pub offset_x: i32,
181    /// Shadow offset Y
182    pub offset_y: i32,
183    /// Shadow blur radius
184    pub blur_radius: u32,
185    /// Shadow color
186    pub color: String,
187}
188
189/// Font configuration
190#[derive(Debug, Clone, Serialize, Deserialize)]
191pub struct FontConfig {
192    /// Font family
193    pub family: String,
194    /// Font size
195    pub size: u32,
196    /// Font weight
197    pub weight: FontWeight,
198    /// Font style
199    pub style: FontStyle,
200    /// Text color
201    pub color: String,
202}
203
204/// Font weight enumeration
205#[derive(Debug, Clone, Serialize, Deserialize)]
206pub enum FontWeight {
207    /// Normal weight
208    Normal,
209    /// Bold weight
210    Bold,
211    /// Light weight
212    Light,
213    /// Custom weight (100-900)
214    Custom(u32),
215}
216
217/// Font style enumeration
218#[derive(Debug, Clone, Serialize, Deserialize)]
219pub enum FontStyle {
220    /// Normal style
221    Normal,
222    /// Italic style
223    Italic,
224    /// Oblique style
225    Oblique,
226}
227
228/// Data binding configuration
229#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct DataBindingConfig {
231    /// Data source ID
232    pub source_id: String,
233    /// Data field mappings
234    pub field_mappings: HashMap<String, String>,
235    /// Update frequency
236    pub update_frequency: UpdateFrequency,
237    /// Data transformations
238    pub transformations: Vec<DataTransformation>,
239    /// Filtering configuration
240    pub filters: HashMap<String, Value>,
241    /// Aggregation method
242    pub aggregation: Option<AggregationMethod>,
243}
244
245/// Update frequency enumeration
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub enum UpdateFrequency {
248    /// Float-time updates
249    RealTime,
250    /// Fixed interval updates
251    Interval(Duration),
252    /// Manual updates only
253    Manual,
254    /// On-demand updates
255    OnDemand,
256}
257
258/// Data transformation enumeration
259#[derive(Debug, Clone, Serialize, Deserialize)]
260pub enum DataTransformation {
261    /// Filter data
262    Filter(String),
263    /// Sort data
264    Sort(String, bool), // field, ascending
265    /// Group data
266    Group(String),
267    /// Aggregate data
268    Aggregate(String, AggregationMethod),
269    /// Custom transformation
270    Custom(String),
271}
272
273/// Aggregation method enumeration
274#[derive(Debug, Clone, Serialize, Deserialize)]
275pub enum AggregationMethod {
276    /// Sum aggregation
277    Sum,
278    /// Average aggregation
279    Average,
280    /// Count aggregation
281    Count,
282    /// Minimum value
283    Min,
284    /// Maximum value
285    Max,
286    /// Standard deviation
287    StdDev,
288    /// Custom aggregation
289    Custom(String),
290}
291
292/// Render context for widgets
293#[derive(Debug, Clone)]
294pub struct RenderContext {
295    /// Canvas or surface to render to
296    pub canvas_id: String,
297    /// Device capabilities
298    pub device: DeviceCapabilities,
299    /// Rendering options
300    pub options: RenderOptions,
301    /// Current timestamp
302    pub timestamp: Instant,
303    /// Global theme settings
304    pub theme: super::core::ThemeConfig,
305}
306
307/// Device capabilities
308#[derive(Debug, Clone)]
309pub struct DeviceCapabilities {
310    /// Screen width
311    pub screen_width: u32,
312    /// Screen height
313    pub screen_height: u32,
314    /// Device pixel ratio
315    pub pixel_ratio: f64,
316    /// WebGL support
317    pub webgl_supported: bool,
318    /// Touch support
319    pub touch_supported: bool,
320    /// Maximum texture size
321    pub max_texture_size: u32,
322}
323
324/// Render options
325#[derive(Debug, Clone)]
326pub struct RenderOptions {
327    /// Render quality
328    pub quality: RenderQuality,
329    /// Enable anti-aliasing
330    pub antialiasing: bool,
331    /// Enable transparency
332    pub transparency: bool,
333    /// Preserve drawing buffer
334    pub preserve_buffer: bool,
335    /// Power preference
336    pub power_preference: String,
337}
338
339/// Render quality enumeration
340#[derive(Debug, Clone, Serialize, Deserialize)]
341pub enum RenderQuality {
342    /// Low quality (performance)
343    Low,
344    /// Medium quality
345    Medium,
346    /// High quality
347    High,
348    /// Ultra quality
349    Ultra,
350}
351
352/// Widget render result
353#[derive(Debug, Clone)]
354pub struct WidgetRender {
355    /// Rendered content
356    pub content: RenderContent,
357    /// Render metadata
358    pub metadata: RenderMetadata,
359    /// Required resources
360    pub resources: Vec<String>,
361}
362
363/// Render content enumeration
364#[derive(Debug, Clone)]
365pub enum RenderContent {
366    /// HTML content
367    Html(String),
368    /// SVG content
369    Svg(String),
370    /// Canvas drawing commands
371    Canvas(Vec<CanvasCommand>),
372    /// WebGL shader program
373    WebGL(ShaderProgram),
374}
375
376/// Canvas drawing command
377#[derive(Debug, Clone)]
378pub enum CanvasCommand {
379    /// Draw line
380    DrawLine {
381        from: Position,
382        to: Position,
383        color: String,
384        width: f64,
385    },
386    /// Draw rectangle
387    DrawRect {
388        position: Position,
389        size: Size,
390        color: String,
391    },
392    /// Draw circle
393    DrawCircle {
394        center: Position,
395        radius: f64,
396        color: String,
397    },
398    /// Draw text
399    DrawText {
400        position: Position,
401        text: String,
402        font: FontConfig,
403    },
404    /// Custom command
405    Custom(String, HashMap<String, Value>),
406}
407
408/// Shader program configuration
409#[derive(Debug, Clone)]
410pub struct ShaderProgram {
411    /// Vertex shader source
412    pub vertex_shader: String,
413    /// Fragment shader source
414    pub fragment_shader: String,
415    /// Uniform variables
416    pub uniforms: HashMap<String, UniformValue>,
417    /// Attribute bindings
418    pub attributes: HashMap<String, AttributeBinding>,
419}
420
421/// Uniform value enumeration
422#[derive(Debug, Clone)]
423pub enum UniformValue {
424    /// Float value
425    Float(f32),
426    /// Vector2 value
427    Vec2([f32; 2]),
428    /// Vector3 value
429    Vec3([f32; 3]),
430    /// Vector4 value
431    Vec4([f32; 4]),
432    /// Matrix4 value
433    Mat4([[f32; 4]; 4]),
434    /// Texture
435    Texture(String),
436}
437
438/// Attribute binding
439#[derive(Debug, Clone)]
440pub struct AttributeBinding {
441    /// Buffer name
442    pub buffer: String,
443    /// Component count
444    pub components: u32,
445    /// Data type
446    pub data_type: AttributeType,
447    /// Normalized
448    pub normalized: bool,
449}
450
451/// Attribute type enumeration
452#[derive(Debug, Clone)]
453pub enum AttributeType {
454    /// Float type
455    Float,
456    /// Unsigned byte type
457    UnsignedByte,
458    /// Short type
459    Short,
460    /// Unsigned short type
461    UnsignedShort,
462}
463
464/// Render metadata
465#[derive(Debug, Clone)]
466pub struct RenderMetadata {
467    /// Render time
468    pub render_time: Duration,
469    /// Frame rate
470    pub frame_rate: f64,
471    /// Memory usage
472    pub memory_usage: u64,
473    /// Error count
474    pub error_count: u32,
475}
476
477/// Widget event
478#[derive(Debug, Clone)]
479pub struct WidgetEvent {
480    /// Event ID
481    pub id: String,
482    /// Event type
483    pub event_type: EventType,
484    /// Timestamp
485    pub timestamp: Instant,
486    /// Event data
487    pub data: HashMap<String, Value>,
488    /// Source widget
489    pub source_widget: String,
490    /// Target element
491    pub target: Option<String>,
492}
493
494/// Event type enumeration
495#[derive(Debug, Clone)]
496pub enum EventType {
497    /// Click event
498    Click { position: Position, button: u32 },
499    /// Double click event
500    DoubleClick { position: Position },
501    /// Mouse move event
502    MouseMove { position: Position, delta: Position },
503    /// Mouse enter event
504    MouseEnter { position: Position },
505    /// Mouse leave event
506    MouseLeave { position: Position },
507    /// Key press event
508    KeyPress { key: String, modifiers: Vec<String> },
509    /// Touch event
510    Touch { touches: Vec<TouchPoint> },
511    /// Resize event
512    Resize { new_size: Size },
513    /// Focus event
514    Focus,
515    /// Blur event
516    Blur,
517    /// Custom event
518    Custom { name: String, data: Value },
519}
520
521/// Touch point
522#[derive(Debug, Clone)]
523pub struct TouchPoint {
524    /// Touch ID
525    pub id: u32,
526    /// Position
527    pub position: Position,
528    /// Pressure
529    pub pressure: f64,
530    /// Radius
531    pub radius: f64,
532}
533
534/// Widget event response
535#[derive(Debug, Clone)]
536pub struct WidgetEventResponse {
537    /// Response ID
538    pub id: String,
539    /// Actions to perform
540    pub actions: Vec<ResponseAction>,
541    /// Data updates
542    pub data_updates: HashMap<String, Value>,
543    /// State changes
544    pub state_changes: HashMap<String, Value>,
545}
546
547/// Response action enumeration
548#[derive(Debug, Clone)]
549pub enum ResponseAction {
550    /// Update widget data
551    UpdateData { widget_id: String, data: Value },
552    /// Trigger event
553    TriggerEvent { event: WidgetEvent },
554    /// Navigate to URL
555    Navigate { url: String },
556    /// Show notification
557    ShowNotification {
558        message: String,
559        level: NotificationLevel,
560    },
561    /// Execute custom action
562    Custom {
563        action: String,
564        params: HashMap<String, Value>,
565    },
566}
567
568/// Notification level enumeration
569#[derive(Debug, Clone)]
570pub enum NotificationLevel {
571    /// Info notification
572    Info,
573    /// Success notification
574    Success,
575    /// Warning notification
576    Warning,
577    /// Error notification
578    Error,
579}
580
581impl Default for WidgetConfig {
582    fn default() -> Self {
583        Self {
584            id: "widget".to_string(),
585            title: "Widget".to_string(),
586            position: Position::default(),
587            size: Size::default(),
588            style: StyleConfig::default(),
589            data_binding: DataBindingConfig::default(),
590            interactions_enabled: true,
591            animation_enabled: true,
592            visible: true,
593            z_index: 0,
594        }
595    }
596}
597
598impl Default for StyleConfig {
599    fn default() -> Self {
600        Self {
601            background_color: "#ffffff".to_string(),
602            border: BorderConfig::default(),
603            shadow: ShadowConfig::default(),
604            font: FontConfig::default(),
605            css_classes: Vec::new(),
606            css_properties: HashMap::new(),
607        }
608    }
609}
610
611impl Default for BorderConfig {
612    fn default() -> Self {
613        Self {
614            width: 1,
615            color: "#cccccc".to_string(),
616            style: BorderStyle::Solid,
617            radius: 4,
618        }
619    }
620}
621
622impl Default for ShadowConfig {
623    fn default() -> Self {
624        Self {
625            enabled: false,
626            offset_x: 2,
627            offset_y: 2,
628            blur_radius: 4,
629            color: "rgba(0,0,0,0.1)".to_string(),
630        }
631    }
632}
633
634impl Default for FontConfig {
635    fn default() -> Self {
636        Self {
637            family: "Arial, sans-serif".to_string(),
638            size: 14,
639            weight: FontWeight::Normal,
640            style: FontStyle::Normal,
641            color: "#333333".to_string(),
642        }
643    }
644}
645
646impl Default for DataBindingConfig {
647    fn default() -> Self {
648        Self {
649            source_id: "default".to_string(),
650            field_mappings: HashMap::new(),
651            update_frequency: UpdateFrequency::RealTime,
652            transformations: Vec::new(),
653            filters: HashMap::new(),
654            aggregation: None,
655        }
656    }
657}