1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use crate::{
chart_data::ChartData, chart_renderer::ChartRenderer, info_bar::InfoBar,
volume_pane::VolumePane, y_axis::YAxis,
};
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
pub struct Candle {
pub open: f64,
pub high: f64,
pub low: f64,
pub close: f64,
pub volume: Option<f64>,
pub timestamp: Option<i64>,
}
pub(crate) enum CandleType {
Bearish,
Bullish,
}
impl Candle {
#[allow(dead_code)]
pub fn new(
open: f64,
high: f64,
low: f64,
close: f64,
volume: Option<f64>,
timestamp: Option<i64>,
) -> Candle {
Candle {
open,
high,
low,
close,
volume,
timestamp,
}
}
pub(crate) fn get_type(&self) -> CandleType {
match self.open < self.close {
true => CandleType::Bullish,
false => CandleType::Bearish,
}
}
}
pub struct Chart {
pub(crate) renderer: ChartRenderer,
pub(crate) y_axis: YAxis,
pub(crate) chart_data: Rc<RefCell<ChartData>>,
pub(crate) info_bar: InfoBar,
pub(crate) volume_pane: VolumePane,
}
impl Chart {
pub fn new(candles: &[Candle]) -> Self {
let renderer = ChartRenderer::new();
let chart_data = Rc::new(RefCell::new(ChartData::new(candles.to_vec())));
let y_axis = YAxis::new(chart_data.clone());
let info_bar = InfoBar::new("APPLE".to_string(), chart_data.clone());
let volume_pane = VolumePane::new(
chart_data.clone(),
(chart_data.borrow().terminal_size.1 / 6) as i64,
);
chart_data.borrow_mut().compute_height(&volume_pane);
Chart {
renderer,
y_axis,
chart_data,
info_bar,
volume_pane,
}
}
pub fn draw(&self) {
self.renderer.render(self);
}
pub fn set_name(&mut self, name: String) {
self.info_bar.name = name;
}
pub fn set_bear_color(&mut self, r: u8, g: u8, b: u8) {
self.renderer.bearish_color = (r, g, b);
}
pub fn set_bull_color(&mut self, r: u8, g: u8, b: u8) {
self.renderer.bullish_color = (r, g, b);
}
pub fn set_vol_bear_color(&mut self, r: u8, g: u8, b: u8) {
self.volume_pane.bearish_color = (r, g, b);
}
pub fn set_vol_bull_color(&mut self, r: u8, g: u8, b: u8) {
self.volume_pane.bullish_color = (r, g, b);
}
pub fn set_volume_pane_enabled(&mut self, enabled: bool) {
self.volume_pane.enabled = enabled;
}
pub fn set_volume_pane_unicode_fill(&mut self, unicode_fill: char) {
self.volume_pane.unicode_fill = unicode_fill;
}
pub fn set_volume_pane_height(&mut self, height: i64) {
self.volume_pane.height = height;
}
}