1 //! "Candlestick" plots 2 3 use std::borrow::Cow; 4 use std::iter::IntoIterator; 5 6 use crate::data::Matrix; 7 use crate::traits::{self, Data, Set}; 8 use crate::{Color, Default, Display, Figure, Label, LineType, LineWidth, Plot, Script}; 9 10 /// Properties common to candlestick plots 11 pub struct Properties { 12 color: Option<Color>, 13 label: Option<Cow<'static, str>>, 14 line_type: LineType, 15 linewidth: Option<f64>, 16 } 17 18 impl Default for Properties { default() -> Properties19 fn default() -> Properties { 20 Properties { 21 color: None, 22 label: None, 23 line_type: LineType::Solid, 24 linewidth: None, 25 } 26 } 27 } 28 29 impl Script for Properties { 30 // Allow clippy::format_push_string even with older versions of rust (<1.62) which 31 // don't have it defined. 32 #[allow(clippy::all)] script(&self) -> String33 fn script(&self) -> String { 34 let mut script = String::from("with candlesticks "); 35 36 script.push_str(&format!("lt {} ", self.line_type.display())); 37 38 if let Some(lw) = self.linewidth { 39 script.push_str(&format!("lw {} ", lw)) 40 } 41 42 if let Some(color) = self.color { 43 script.push_str(&format!("lc rgb '{}' ", color.display())); 44 } 45 46 if let Some(ref label) = self.label { 47 script.push_str("title '"); 48 script.push_str(label); 49 script.push('\'') 50 } else { 51 script.push_str("notitle") 52 } 53 54 script 55 } 56 } 57 58 impl Set<Color> for Properties { 59 /// Sets the line color set(&mut self, color: Color) -> &mut Properties60 fn set(&mut self, color: Color) -> &mut Properties { 61 self.color = Some(color); 62 self 63 } 64 } 65 66 impl Set<Label> for Properties { 67 /// Sets the legend label set(&mut self, label: Label) -> &mut Properties68 fn set(&mut self, label: Label) -> &mut Properties { 69 self.label = Some(label.0); 70 self 71 } 72 } 73 74 impl Set<LineType> for Properties { 75 /// Changes the line type 76 /// 77 /// **Note** By default `Solid` lines are used set(&mut self, lt: LineType) -> &mut Properties78 fn set(&mut self, lt: LineType) -> &mut Properties { 79 self.line_type = lt; 80 self 81 } 82 } 83 84 impl Set<LineWidth> for Properties { 85 /// Changes the width of the line 86 /// 87 /// # Panics 88 /// 89 /// Panics if `width` is a non-positive value set(&mut self, lw: LineWidth) -> &mut Properties90 fn set(&mut self, lw: LineWidth) -> &mut Properties { 91 let lw = lw.0; 92 93 assert!(lw > 0.); 94 95 self.linewidth = Some(lw); 96 self 97 } 98 } 99 100 /// A candlestick consists of a box and two whiskers that extend beyond the box 101 pub struct Candlesticks<X, WM, BM, BH, WH> { 102 /// X coordinate of the candlestick 103 pub x: X, 104 /// Y coordinate of the end point of the bottom whisker 105 pub whisker_min: WM, 106 /// Y coordinate of the bottom of the box 107 pub box_min: BM, 108 /// Y coordinate of the top of the box 109 pub box_high: BH, 110 /// Y coordinate of the end point of the top whisker 111 pub whisker_high: WH, 112 } 113 114 impl<X, WM, BM, BH, WH> traits::Plot<Candlesticks<X, WM, BM, BH, WH>> for Figure 115 where 116 BH: IntoIterator, 117 BH::Item: Data, 118 BM: IntoIterator, 119 BM::Item: Data, 120 WH: IntoIterator, 121 WH::Item: Data, 122 WM: IntoIterator, 123 WM::Item: Data, 124 X: IntoIterator, 125 X::Item: Data, 126 { 127 type Properties = Properties; 128 plot<F>( &mut self, candlesticks: Candlesticks<X, WM, BM, BH, WH>, configure: F, ) -> &mut Figure where F: FnOnce(&mut Properties) -> &mut Properties,129 fn plot<F>( 130 &mut self, 131 candlesticks: Candlesticks<X, WM, BM, BH, WH>, 132 configure: F, 133 ) -> &mut Figure 134 where 135 F: FnOnce(&mut Properties) -> &mut Properties, 136 { 137 let (x_factor, y_factor) = crate::scale_factor(&self.axes, crate::Axes::BottomXLeftY); 138 let Candlesticks { 139 x, 140 whisker_min, 141 box_min, 142 box_high, 143 whisker_high, 144 } = candlesticks; 145 146 let data = Matrix::new( 147 izip!(x, box_min, whisker_min, whisker_high, box_high), 148 (x_factor, y_factor, y_factor, y_factor, y_factor), 149 ); 150 self.plots 151 .push(Plot::new(data, configure(&mut Default::default()))); 152 self 153 } 154 } 155