plotlars_core/components/direction.rs
1use crate::components::Rgb;
2
3/// A structure representing the styling for candlestick directions (increasing/decreasing).
4///
5/// The `Direction` struct allows customization of how candlestick lines appear when the closing price
6/// is higher (increasing) or lower (decreasing) than the opening price. This includes setting
7/// the line color and width for the candlesticks.
8///
9/// Note: Fill color is not currently supported by the underlying plotly library.
10///
11/// # Example
12///
13/// ```rust
14/// use plotlars::{CandlestickPlot, Direction, Plot, Rgb};
15/// use polars::prelude::*;
16///
17/// let dates = vec!["2024-01-01", "2024-01-02", "2024-01-03"];
18/// let open_prices = vec![100.0, 102.5, 101.0];
19/// let high_prices = vec![103.0, 104.0, 103.5];
20/// let low_prices = vec![99.0, 101.5, 100.0];
21/// let close_prices = vec![102.5, 101.0, 103.5];
22///
23/// let stock_data = df! {
24/// "date" => dates,
25/// "open" => open_prices,
26/// "high" => high_prices,
27/// "low" => low_prices,
28/// "close" => close_prices,
29/// }
30/// .unwrap();
31///
32/// let increasing = Direction::new()
33/// .line_color(Rgb(0, 150, 255))
34/// .line_width(2.0);
35///
36/// let decreasing = Direction::new()
37/// .line_color(Rgb(200, 0, 100))
38/// .line_width(2.0);
39///
40/// CandlestickPlot::builder()
41/// .data(&stock_data)
42/// .dates("date")
43/// .open("open")
44/// .high("high")
45/// .low("low")
46/// .close("close")
47/// .increasing(&increasing)
48/// .decreasing(&decreasing)
49/// .build()
50/// .plot();
51/// ```
52///
53/// 
54#[derive(Clone, Default)]
55pub struct Direction {
56 pub line_color: Option<Rgb>,
57 pub line_width: Option<f64>,
58}
59
60impl Direction {
61 /// Creates a new `Direction` instance with default settings.
62 ///
63 /// # Returns
64 ///
65 /// A new `Direction` instance with no customizations applied.
66 pub fn new() -> Self {
67 Self::default()
68 }
69
70 /// Sets the line color for the candlestick outline and wicks.
71 ///
72 /// # Arguments
73 ///
74 /// * `color` - An `Rgb` color for the candlestick lines.
75 ///
76 /// # Returns
77 ///
78 /// The modified `Direction` instance for method chaining.
79 pub fn line_color(mut self, color: Rgb) -> Self {
80 self.line_color = Some(color);
81 self
82 }
83
84 /// Sets the line width for the candlestick outline and wicks.
85 ///
86 /// # Arguments
87 ///
88 /// * `width` - The width of the candlestick lines in pixels.
89 ///
90 /// # Returns
91 ///
92 /// The modified `Direction` instance for method chaining.
93 pub fn line_width(mut self, width: f64) -> Self {
94 self.line_width = Some(width);
95 self
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn test_default() {
105 let dir = Direction::new();
106 assert!(dir.line_color.is_none());
107 assert!(dir.line_width.is_none());
108 }
109
110 #[test]
111 fn test_line_color() {
112 let dir = Direction::new().line_color(Rgb(0, 255, 0));
113 let c = dir.line_color.unwrap();
114 assert_eq!(c.0, 0);
115 assert_eq!(c.1, 255);
116 assert_eq!(c.2, 0);
117 }
118
119 #[test]
120 fn test_line_width() {
121 let dir = Direction::new().line_width(2.0);
122 assert!((dir.line_width.unwrap() - 2.0).abs() < 1e-6);
123 }
124
125 #[test]
126 fn test_builder_chaining() {
127 let dir = Direction::new()
128 .line_color(Rgb(200, 0, 100))
129 .line_width(3.5);
130
131 let c = dir.line_color.unwrap();
132 assert_eq!(c.0, 200);
133 assert_eq!(c.1, 0);
134 assert_eq!(c.2, 100);
135 assert!((dir.line_width.unwrap() - 3.5).abs() < 1e-6);
136 }
137}