openpine_vm/visuals/
series_graph.rs

1use core::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use crate::visuals::{
6    BackgroundColor, Fill, Plot, PlotArrow, PlotBar, PlotCandle, PlotChar, PlotDisplay, PlotShape,
7};
8
9/// Stable identifier for a per-series graph stored in a
10/// [`Chart`](crate::visuals::Chart).
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
12pub struct SeriesGraphId(pub(crate) i64);
13
14impl fmt::Display for SeriesGraphId {
15    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16        write!(f, "{}", self.0)
17    }
18}
19
20impl SeriesGraphId {
21    /// Returns the underlying id value.
22    #[inline]
23    pub fn as_i64(&self) -> i64 {
24        self.0
25    }
26}
27
28/// A per-series visual output (e.g. plot or bar colors).
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub enum SeriesGraph {
31    /// A standard plot output.
32    Plot(Plot),
33    /// Background color output.
34    BackgroundColors(BackgroundColor),
35    /// Fill output between two series/hline anchors.
36    Fill(Fill),
37    /// Plotarrow output.
38    PlotArrow(PlotArrow),
39    /// Plotbar output.
40    PlotBar(PlotBar),
41    /// Plotcandle output.
42    PlotCandle(PlotCandle),
43    /// Plotchar output.
44    PlotChar(PlotChar),
45    /// Plotshape output.
46    PlotShape(PlotShape),
47}
48
49impl SeriesGraph {
50    /// Returns the underlying [`Plot`] if this is a plot.
51    #[inline]
52    pub fn as_plot(&self) -> Option<&Plot> {
53        match self {
54            SeriesGraph::Plot(plot) => Some(plot),
55            _ => None,
56        }
57    }
58
59    #[inline]
60    pub(crate) fn as_plot_mut(&mut self) -> Option<&mut Plot> {
61        match self {
62            SeriesGraph::Plot(plot) => Some(plot),
63            _ => None,
64        }
65    }
66
67    /// Returns the underlying [`BackgroundColor`] if this is a background color
68    /// series.
69    #[inline]
70    pub fn as_background_color(&self) -> Option<&BackgroundColor> {
71        match self {
72            SeriesGraph::BackgroundColors(bg_colors) => Some(bg_colors),
73            _ => None,
74        }
75    }
76
77    #[inline]
78    pub(crate) fn as_background_color_mut(&mut self) -> Option<&mut BackgroundColor> {
79        match self {
80            SeriesGraph::BackgroundColors(bg_colors) => Some(bg_colors),
81            _ => None,
82        }
83    }
84
85    /// Returns the underlying [`Fill`] if this is a fill series.
86    #[inline]
87    pub fn as_fill(&self) -> Option<&Fill> {
88        match self {
89            SeriesGraph::Fill(fill) => Some(fill),
90            _ => None,
91        }
92    }
93
94    #[inline]
95    pub(crate) fn as_fill_mut(&mut self) -> Option<&mut Fill> {
96        match self {
97            SeriesGraph::Fill(fill) => Some(fill),
98            _ => None,
99        }
100    }
101
102    /// Returns the underlying [`PlotArrow`] if this is a plotarrow series.
103    #[inline]
104    pub fn as_plot_arrow(&self) -> Option<&PlotArrow> {
105        match self {
106            SeriesGraph::PlotArrow(plot_arrow) => Some(plot_arrow),
107            _ => None,
108        }
109    }
110
111    #[inline]
112    pub(crate) fn as_plot_arrow_mut(&mut self) -> Option<&mut PlotArrow> {
113        match self {
114            SeriesGraph::PlotArrow(plot_arrow) => Some(plot_arrow),
115            _ => None,
116        }
117    }
118
119    /// Returns the underlying [`PlotBar`] if this is a plotbar series.
120    #[inline]
121    pub fn as_plot_bar(&self) -> Option<&PlotBar> {
122        match self {
123            SeriesGraph::PlotBar(plot_bar) => Some(plot_bar),
124            _ => None,
125        }
126    }
127
128    #[inline]
129    pub(crate) fn as_plot_bar_mut(&mut self) -> Option<&mut PlotBar> {
130        match self {
131            SeriesGraph::PlotBar(plot_bar) => Some(plot_bar),
132            _ => None,
133        }
134    }
135
136    /// Returns the underlying [`PlotCandle`] if this is a plotcandle series.
137    #[inline]
138    pub fn as_plot_candle(&self) -> Option<&PlotCandle> {
139        match self {
140            SeriesGraph::PlotCandle(plot_candle) => Some(plot_candle),
141            _ => None,
142        }
143    }
144
145    #[inline]
146    pub(crate) fn as_plot_candle_mut(&mut self) -> Option<&mut PlotCandle> {
147        match self {
148            SeriesGraph::PlotCandle(plot_candle) => Some(plot_candle),
149            _ => None,
150        }
151    }
152
153    /// Returns the underlying [`PlotChar`] if this is a plotchar series.
154    #[inline]
155    pub fn as_plot_char(&self) -> Option<&PlotChar> {
156        match self {
157            SeriesGraph::PlotChar(plot_char) => Some(plot_char),
158            _ => None,
159        }
160    }
161
162    #[inline]
163    pub(crate) fn as_plot_char_mut(&mut self) -> Option<&mut PlotChar> {
164        match self {
165            SeriesGraph::PlotChar(plot_char) => Some(plot_char),
166            _ => None,
167        }
168    }
169
170    /// Returns the underlying [`PlotShape`] if this is a plotshape series.
171    #[inline]
172    pub fn as_plot_shape(&self) -> Option<&PlotShape> {
173        match self {
174            SeriesGraph::PlotShape(plot_shape) => Some(plot_shape),
175            _ => None,
176        }
177    }
178
179    #[inline]
180    pub(crate) fn as_plot_shape_mut(&mut self) -> Option<&mut PlotShape> {
181        match self {
182            SeriesGraph::PlotShape(plot_shape) => Some(plot_shape),
183            _ => None,
184        }
185    }
186
187    /// Returns `(force_overlay, display)` for series graphs that have these
188    /// fields, or `None` for variants that don't drive pane layout (e.g.
189    /// `Fill`).
190    pub fn pane_flags(&self) -> Option<(bool, PlotDisplay)> {
191        match self {
192            SeriesGraph::Plot(p) => Some((p.force_overlay, p.display)),
193            SeriesGraph::PlotArrow(p) => Some((p.force_overlay, p.display)),
194            SeriesGraph::PlotBar(p) => Some((p.force_overlay, p.display)),
195            SeriesGraph::PlotCandle(p) => Some((p.force_overlay, p.display)),
196            SeriesGraph::PlotChar(p) => Some((p.force_overlay, p.display)),
197            SeriesGraph::PlotShape(p) => Some((p.force_overlay, p.display)),
198            SeriesGraph::BackgroundColors(p) => Some((p.force_overlay, p.display)),
199            SeriesGraph::Fill(_) => None,
200        }
201    }
202
203    /// Whether this series graph is user-editable (can be configured in the
204    /// settings dialog).
205    pub fn is_editable(&self) -> bool {
206        match self {
207            SeriesGraph::Plot(p) => p.editable,
208            SeriesGraph::BackgroundColors(bg) => bg.editable,
209            SeriesGraph::Fill(f) => f.editable,
210            SeriesGraph::PlotArrow(pa) => pa.editable,
211            SeriesGraph::PlotBar(pb) => pb.editable,
212            SeriesGraph::PlotCandle(pc) => pc.editable,
213            SeriesGraph::PlotChar(pc) => pc.editable,
214            SeriesGraph::PlotShape(ps) => ps.editable,
215        }
216    }
217
218    pub(crate) fn append_new(&mut self) {
219        match self {
220            SeriesGraph::Plot(plot) => plot.append_new(),
221            SeriesGraph::BackgroundColors(background_color) => background_color.append_new(),
222            SeriesGraph::Fill(fill) => fill.append_new(),
223            SeriesGraph::PlotArrow(plot_arrow) => plot_arrow.append_new(),
224            SeriesGraph::PlotBar(plot_bar) => plot_bar.append_new(),
225            SeriesGraph::PlotCandle(plot_candle) => plot_candle.append_new(),
226            SeriesGraph::PlotChar(plot_char) => plot_char.append_new(),
227            SeriesGraph::PlotShape(plot_shape) => plot_shape.append_new(),
228        }
229    }
230}