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