1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ChartConfig {
6 pub title: String,
7 pub x_axis: String,
8 pub y_axis: String,
9 pub chart_type: ChartType,
10 pub query: String,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub enum ChartType {
15 Line,
16 Scatter,
17 Bar,
18 Candlestick,
19}
20
21#[derive(Debug, Clone)]
22pub struct DataSeries {
23 pub name: String,
24 pub points: Vec<DataPoint>,
25 pub x_range: (f64, f64),
26 pub y_range: (f64, f64),
27}
28
29#[derive(Debug, Clone)]
30pub struct DataPoint {
31 pub x: f64,
32 pub y: f64,
33 pub timestamp: Option<DateTime<Utc>>,
34 pub label: Option<String>,
35}
36
37#[derive(Debug, Clone)]
38pub struct ChartViewport {
39 pub x_min: f64,
40 pub x_max: f64,
41 pub y_min: f64,
42 pub y_max: f64,
43 pub zoom_level: f64,
44}
45
46impl ChartViewport {
47 pub fn new(x_range: (f64, f64), y_range: (f64, f64)) -> Self {
48 Self {
49 x_min: x_range.0,
50 x_max: x_range.1,
51 y_min: y_range.0,
52 y_max: y_range.1,
53 zoom_level: 1.0,
54 }
55 }
56
57 pub fn auto_scale(&mut self, data: &DataSeries) {
58 self.x_min = data.x_range.0;
59 self.x_max = data.x_range.1;
60
61 let y_span = data.y_range.1 - data.y_range.0;
63 let padding = y_span * 0.1; self.y_min = data.y_range.0 - padding;
65 self.y_max = data.y_range.1 + padding;
66 }
67
68 pub fn pan(&mut self, dx: f64, dy: f64) {
69 let x_span = self.x_max - self.x_min;
70 let y_span = self.y_max - self.y_min;
71
72 self.x_min += dx * x_span * 0.1;
73 self.x_max += dx * x_span * 0.1;
74 self.y_min += dy * y_span * 0.1;
75 self.y_max += dy * y_span * 0.1;
76 }
77
78 pub fn zoom(&mut self, factor: f64, center_x: f64, center_y: f64) {
79 let x_span = self.x_max - self.x_min;
80 let y_span = self.y_max - self.y_min;
81
82 let new_x_span = x_span / factor;
83 let new_y_span = y_span / factor;
84
85 self.x_min = center_x - new_x_span / 2.0;
86 self.x_max = center_x + new_x_span / 2.0;
87 self.y_min = center_y - new_y_span / 2.0;
88 self.y_max = center_y + new_y_span / 2.0;
89
90 self.zoom_level *= factor;
91 }
92}
93
94impl Default for ChartType {
95 fn default() -> Self {
96 ChartType::Line
97 }
98}