1use std::borrow::Cow;
4
5use crate::map;
6use crate::traits::{Configure, Data, Set};
7use crate::{
8 grid, Axis, Default, Display, Grid, Label, Range, Scale, ScaleFactor, Script, TicLabels,
9};
10
11#[derive(Clone)]
13pub struct Properties {
14 grids: map::grid::Map<grid::Properties>,
15 hidden: bool,
16 label: Option<Cow<'static, str>>,
17 logarithmic: bool,
18 range: Option<(f64, f64)>,
19 scale_factor: f64,
20 tics: Option<String>,
21}
22
23impl Default for Properties {
24 fn default() -> Properties {
25 Properties {
26 grids: map::grid::Map::new(),
27 hidden: false,
28 label: None,
29 logarithmic: false,
30 range: None,
31 scale_factor: 1.,
32 tics: None,
33 }
34 }
35}
36
37impl Properties {
38 pub fn hide(&mut self) -> &mut Properties {
42 self.hidden = true;
43 self
44 }
45
46 pub fn show(&mut self) -> &mut Properties {
50 self.hidden = false;
51 self
52 }
53}
54
55impl Configure<Grid> for Properties {
56 type Properties = grid::Properties;
57
58 fn configure<F>(&mut self, grid: Grid, configure: F) -> &mut Properties
60 where
61 F: FnOnce(&mut grid::Properties) -> &mut grid::Properties,
62 {
63 if self.grids.contains_key(grid) {
64 configure(self.grids.get_mut(grid).unwrap());
65 } else {
66 let mut properties = Default::default();
67 configure(&mut properties);
68 self.grids.insert(grid, properties);
69 }
70
71 self
72 }
73}
74
75impl Set<Label> for Properties {
76 fn set(&mut self, label: Label) -> &mut Properties {
78 self.label = Some(label.0);
79 self
80 }
81}
82
83impl Set<Range> for Properties {
84 fn set(&mut self, range: Range) -> &mut Properties {
88 self.hidden = false;
89
90 match range {
91 Range::Auto => self.range = None,
92 Range::Limits(low, high) => self.range = Some((low, high)),
93 }
94
95 self
96 }
97}
98
99impl Set<Scale> for Properties {
100 fn set(&mut self, scale: Scale) -> &mut Properties {
104 self.hidden = false;
105
106 match scale {
107 Scale::Linear => self.logarithmic = false,
108 Scale::Logarithmic => self.logarithmic = true,
109 }
110
111 self
112 }
113}
114
115impl Set<ScaleFactor> for Properties {
116 fn set(&mut self, factor: ScaleFactor) -> &mut Properties {
123 self.scale_factor = factor.0;
124
125 self
126 }
127}
128
129impl<P, L> Set<TicLabels<P, L>> for Properties
130where
131 L: IntoIterator,
132 L::Item: AsRef<str>,
133 P: IntoIterator,
134 P::Item: Data,
135{
136 fn set(&mut self, tics: TicLabels<P, L>) -> &mut Properties {
138 let TicLabels { positions, labels } = tics;
139
140 let pairs = positions
141 .into_iter()
142 .zip(labels)
143 .map(|(pos, label)| format!("'{}' {}", label.as_ref(), pos.f64()))
144 .collect::<Vec<_>>();
145
146 if pairs.is_empty() {
147 self.tics = None
148 } else {
149 self.tics = Some(pairs.join(", "));
150 }
151
152 self
153 }
154}
155
156impl Script for (Axis, &Properties) {
157 fn script(&self) -> String {
158 let &(axis, properties) = self;
159 let axis_ = axis.display();
160
161 let mut script = if properties.hidden {
162 return format!("unset {}tics\n", axis_);
163 } else {
164 format!("set {}tics nomirror ", axis_)
165 };
166
167 if let Some(ref tics) = properties.tics {
168 script.push_str(&format!("({})", tics))
169 }
170
171 script.push('\n');
172
173 if let Some(ref label) = properties.label {
174 script.push_str(&format!("set {}label '{}'\n", axis_, label))
175 }
176
177 if let Some((low, high)) = properties.range {
178 script.push_str(&format!("set {}range [{}:{}]\n", axis_, low, high))
179 }
180
181 if properties.logarithmic {
182 script.push_str(&format!("set logscale {}\n", axis_));
183 }
184
185 for (grid, properties) in properties.grids.iter() {
186 script.push_str(&(axis, grid, properties).script());
187 }
188
189 script
190 }
191}
192
193impl crate::ScaleFactorTrait for Properties {
194 fn scale_factor(&self) -> f64 {
195 self.scale_factor
196 }
197}