openpine_vm/visuals/
mod.rs1mod bar_colors;
2mod bgcolors;
3mod r#box;
4mod extend;
5mod fill;
6mod graph;
7mod hline;
8mod label;
9mod line;
10mod linefill;
11mod location;
12mod plot;
13mod plot_display;
14mod plot_format;
15mod plotarrow;
16mod plotbar;
17mod plotcandle;
18mod plotchar;
19mod plotshape;
20mod polyline;
21mod position;
22mod series_graph;
23mod shape;
24mod size;
25mod table;
26mod text;
27mod xylocation;
28
29use std::collections::BTreeMap;
30
31pub use bar_colors::*;
32pub use bgcolors::*;
33pub use extend::*;
34pub use fill::*;
35pub use graph::*;
36pub use hline::*;
37pub use label::*;
38pub use line::*;
39pub use linefill::*;
40pub use location::*;
41pub type Color = openpine_compiler::instructions::Color;
43pub use r#box::*;
44pub use plot::*;
45pub use plot_display::*;
46pub use plot_format::*;
47pub use plotarrow::*;
48pub use plotbar::*;
49pub use plotcandle::*;
50pub use plotchar::*;
51pub use plotshape::*;
52pub use polyline::*;
53pub use position::*;
54use serde::{Deserialize, Serialize};
55pub use series_graph::*;
56pub use shape::*;
57pub use size::*;
58pub use table::*;
59pub use text::*;
60pub use xylocation::*;
61
62#[derive(Debug, Clone, Serialize, Deserialize)]
69pub struct FilledOrder {
70 pub order_id: String,
72 pub price: f64,
74 pub quantity: f64,
76}
77
78#[derive(Debug, Default, Clone, Serialize, Deserialize)]
123pub struct Chart {
124 background_color: Option<Color>,
125 series_graphs: BTreeMap<SeriesGraphId, SeriesGraph>,
126 graphs: BTreeMap<GraphId, Graph>,
127 bar_colors: BarColors,
128 graph_id_counter: i64,
129 filled_orders: BTreeMap<usize, Vec<FilledOrder>>,
134}
135
136impl Chart {
137 #[inline]
139 pub(crate) fn set_background_color(&mut self, color: impl Into<Option<Color>>) {
140 self.background_color = color.into();
141 }
142
143 #[inline]
145 pub fn background_color(&self) -> Option<Color> {
146 self.background_color
147 }
148
149 #[inline]
150 pub(crate) fn add_series_graph(&mut self, id: SeriesGraphId, mut graph: SeriesGraph) {
151 graph.append_new();
152 self.series_graphs.insert(id, graph);
153 }
154
155 #[inline]
157 pub fn series_graphs(&self) -> impl Iterator<Item = (SeriesGraphId, &SeriesGraph)> {
158 self.series_graphs.iter().map(|(id, graph)| (*id, graph))
159 }
160
161 #[inline]
163 pub fn series_graph(&self, id: SeriesGraphId) -> Option<&SeriesGraph> {
164 self.series_graphs.get(&id)
165 }
166
167 #[inline]
168 pub(crate) fn series_graph_mut(&mut self, id: SeriesGraphId) -> Option<&mut SeriesGraph> {
169 self.series_graphs.get_mut(&id)
170 }
171
172 #[inline]
173 pub(crate) fn add_graph(&mut self, graph: Graph) -> GraphId {
174 let id = GraphId(self.graph_id_counter);
175 self.graph_id_counter += 1;
176 self.graphs.insert(id, graph);
177 id
178 }
179
180 pub(crate) fn add_graph_evicting(
187 &mut self,
188 graph: Graph,
189 max_count: usize,
190 ) -> (GraphId, Vec<(GraphId, Graph)>) {
191 let disc = std::mem::discriminant(&graph);
192 let same_kind_ids: Vec<GraphId> = self
193 .graphs
194 .iter()
195 .filter(|(_, g)| std::mem::discriminant(*g) == disc)
196 .map(|(&id, _)| id)
197 .collect();
198
199 let total_after_add = same_kind_ids.len() + 1;
200 let mut evicted = Vec::new();
201 if total_after_add > max_count {
202 let excess = total_after_add - max_count;
203 for &id in same_kind_ids.iter().take(excess) {
204 if let Some(graph) = self.graphs.remove(&id) {
205 evicted.push((id, graph));
206 }
207 }
208 }
209
210 let new_id = self.add_graph(graph);
211 (new_id, evicted)
212 }
213
214 #[inline]
216 pub(crate) fn restore_graph(&mut self, id: GraphId, graph: Graph) {
217 self.graphs.insert(id, graph);
218 }
219
220 #[inline]
222 pub fn graphs(&self) -> impl Iterator<Item = (GraphId, &Graph)> {
223 self.graphs.iter().map(|(id, graph)| (*id, graph))
224 }
225
226 #[inline]
228 pub fn graph(&self, id: GraphId) -> Option<&Graph> {
229 self.graphs.get(&id)
230 }
231
232 #[inline]
233 pub(crate) fn graph_mut(&mut self, id: GraphId) -> Option<&mut Graph> {
234 self.graphs.get_mut(&id)
235 }
236
237 #[inline]
238 pub(crate) fn remove_graph(&mut self, id: GraphId) {
239 self.graphs.remove(&id);
240 }
241
242 #[inline]
243 pub(crate) fn retain_graphs<F>(&mut self, mut f: F)
244 where
245 F: FnMut(&Graph) -> bool,
246 {
247 self.graphs.retain(|_, graph| f(graph));
248 }
249
250 #[inline]
252 pub fn series_len(&self) -> usize {
253 self.bar_colors.colors.len()
254 }
255
256 #[inline]
258 pub fn bar_colors(&self) -> &BarColors {
259 &self.bar_colors
260 }
261
262 #[inline]
263 pub(crate) fn bar_colors_mut(&mut self) -> &mut BarColors {
264 &mut self.bar_colors
265 }
266
267 pub(crate) fn append_new(&mut self) {
268 self.bar_colors.append_new();
269 for graph in self.series_graphs.values_mut() {
270 graph.append_new();
271 }
272 }
273
274 #[inline]
279 pub fn filled_orders_on_bar(&self, bar_index: usize) -> &[FilledOrder] {
280 self.filled_orders
281 .get(&bar_index)
282 .map(Vec::as_slice)
283 .unwrap_or(&[])
284 }
285
286 #[inline]
287 pub(crate) fn record_filled_order(&mut self, bar_index: usize, order: FilledOrder) {
288 self.filled_orders.entry(bar_index).or_default().push(order);
289 }
290}