Skip to main content

sandbox_quant/charting/
scene.rs

1use crate::charting::style::{ChartTheme, RgbColor};
2
3/// Millisecond timestamp wrapper kept backend-neutral for future extractability.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
5pub struct EpochMs(i64);
6
7impl EpochMs {
8    pub const fn new(value: i64) -> Self {
9        Self(value)
10    }
11
12    pub const fn as_i64(self) -> i64 {
13        self.0
14    }
15}
16
17impl From<i64> for EpochMs {
18    fn from(value: i64) -> Self {
19        Self::new(value)
20    }
21}
22
23#[derive(Debug, Clone, PartialEq)]
24pub struct RenderRequest {
25    pub width_px: u32,
26    pub height_px: u32,
27    pub pixel_ratio: f32,
28    pub oversample: u8,
29}
30
31#[derive(Debug, Clone, PartialEq)]
32pub struct RenderedFrame {
33    pub width_px: u32,
34    pub height_px: u32,
35    pub rgb: Vec<u8>,
36}
37
38#[derive(Debug, Clone, PartialEq)]
39pub struct ChartScene {
40    pub title: String,
41    pub time_label_format: String,
42    pub theme: ChartTheme,
43    pub viewport: Viewport,
44    /// Optional shared hover/crosshair state that backends may visualize.
45    pub hover: Option<HoverModel>,
46    pub panes: Vec<Pane>,
47}
48
49#[derive(Debug, Clone, PartialEq, Eq, Default)]
50pub struct Viewport {
51    pub x_range: Option<(EpochMs, EpochMs)>,
52}
53
54#[derive(Debug, Clone, PartialEq)]
55pub struct Pane {
56    pub id: String,
57    pub title: Option<String>,
58    /// Relative vertical weight used when a scene is split into stacked panes.
59    pub weight: u16,
60    pub y_axis: YAxisSpec,
61    pub series: Vec<Series>,
62}
63
64#[derive(Debug, Clone, PartialEq)]
65pub struct YAxisSpec {
66    pub label: Option<String>,
67    pub formatter: ValueFormatter,
68    pub include_zero: bool,
69}
70
71impl Default for YAxisSpec {
72    fn default() -> Self {
73        Self {
74            label: None,
75            formatter: ValueFormatter::Number {
76                decimals: 2,
77                prefix: String::new(),
78                suffix: String::new(),
79            },
80            include_zero: false,
81        }
82    }
83}
84
85#[derive(Debug, Clone, PartialEq)]
86pub enum ValueFormatter {
87    Number {
88        decimals: u8,
89        prefix: String,
90        suffix: String,
91    },
92    Compact {
93        decimals: u8,
94        prefix: String,
95        suffix: String,
96    },
97    Percent {
98        decimals: u8,
99    },
100}
101
102#[derive(Debug, Clone, PartialEq)]
103pub enum Series {
104    Candles(CandleSeries),
105    Bars(BarSeries),
106    Line(LineSeries),
107    Markers(MarkerSeries),
108}
109
110#[derive(Debug, Clone, PartialEq)]
111pub struct CandleSeries {
112    pub name: String,
113    pub up_color: Option<RgbColor>,
114    pub down_color: Option<RgbColor>,
115    pub candles: Vec<Candle>,
116}
117
118#[derive(Debug, Clone, PartialEq)]
119pub struct Candle {
120    pub open_time_ms: EpochMs,
121    pub close_time_ms: EpochMs,
122    pub open: f64,
123    pub high: f64,
124    pub low: f64,
125    pub close: f64,
126}
127
128#[derive(Debug, Clone, PartialEq)]
129pub struct BarSeries {
130    pub name: String,
131    pub color: RgbColor,
132    pub bars: Vec<Bar>,
133}
134
135#[derive(Debug, Clone, PartialEq)]
136pub struct Bar {
137    pub open_time_ms: EpochMs,
138    pub close_time_ms: EpochMs,
139    pub value: f64,
140    pub color: Option<RgbColor>,
141}
142
143#[derive(Debug, Clone, PartialEq)]
144pub struct LineSeries {
145    pub name: String,
146    pub color: RgbColor,
147    pub width: u32,
148    pub points: Vec<LinePoint>,
149}
150
151#[derive(Debug, Clone, PartialEq)]
152pub struct LinePoint {
153    pub time_ms: EpochMs,
154    pub value: f64,
155}
156
157#[derive(Debug, Clone, PartialEq)]
158pub struct MarkerSeries {
159    pub name: String,
160    pub markers: Vec<Marker>,
161}
162
163#[derive(Debug, Clone, PartialEq)]
164pub struct Marker {
165    pub label: String,
166    pub time_ms: EpochMs,
167    pub value: f64,
168    pub color: RgbColor,
169    pub size: i32,
170    pub shape: MarkerShape,
171}
172
173#[derive(Debug, Clone, Copy, PartialEq, Eq)]
174pub enum MarkerShape {
175    Circle,
176    Cross,
177}
178
179#[derive(Debug, Clone, PartialEq)]
180pub struct HoverModel {
181    pub crosshair: Option<Crosshair>,
182    pub tooltip: Option<TooltipModel>,
183}
184
185#[derive(Debug, Clone, PartialEq)]
186pub struct Crosshair {
187    pub time_ms: EpochMs,
188    pub value: Option<f64>,
189    pub color: Option<RgbColor>,
190}
191
192#[derive(Debug, Clone, PartialEq)]
193pub struct TooltipModel {
194    pub title: String,
195    pub sections: Vec<TooltipSection>,
196}
197
198#[derive(Debug, Clone, PartialEq)]
199pub struct TooltipSection {
200    pub title: String,
201    pub rows: Vec<TooltipRow>,
202}
203
204#[derive(Debug, Clone, PartialEq)]
205pub struct TooltipRow {
206    pub label: String,
207    pub value: String,
208}