1use super::GraphMaker;
2use num_traits::Num;
3use std::fmt::Write;
4
5pub struct Text {
44 color: String, align_horizontal: String, align_vertical: String, fontsize: f64, rotation: Option<f64>, bbox: bool, bbox_facecolor: String, bbox_edgecolor: String, bbox_alpha: f64, bbox_style: String, extra: String, buffer: String, }
62
63impl Text {
64 pub fn new() -> Self {
66 Text {
67 color: String::new(),
68 align_horizontal: String::new(),
69 align_vertical: String::new(),
70 fontsize: 0.0,
71 rotation: None,
72 bbox: false,
73 bbox_facecolor: String::new(),
74 bbox_edgecolor: String::new(),
75 bbox_alpha: 1.0,
76 bbox_style: String::new(),
77 extra: String::new(),
78 buffer: String::new(),
79 }
80 }
81
82 pub fn draw<T>(&mut self, x: T, y: T, message: &str)
84 where
85 T: std::fmt::Display + Num,
86 {
87 let opt = self.options();
88 write!(&mut self.buffer, "t=plt.text({},{},r'{}'{})\n", x, y, message, &opt).unwrap();
89 if self.bbox {
90 let opt_bbox = self.options_bbox();
91 write!(&mut self.buffer, "t.set_bbox(dict({}))\n", opt_bbox).unwrap();
92 }
93 }
94
95 pub fn draw_3d<T>(&mut self, x: T, y: T, z: T, message: &str)
97 where
98 T: std::fmt::Display + Num,
99 {
100 let opt = self.options();
101 write!(
102 &mut self.buffer,
103 "t=ax3d().text({},{},{},r'{}'{})\n",
104 x, y, z, message, &opt
105 )
106 .unwrap();
107 if self.bbox {
108 let opt_bbox = self.options_bbox();
109 write!(&mut self.buffer, "t.set_bbox(dict({}))\n", opt_bbox).unwrap();
110 }
111 }
112
113 pub fn set_color(&mut self, color: &str) -> &mut Self {
115 self.color = String::from(color);
116 self
117 }
118
119 pub fn set_align_horizontal(&mut self, option: &str) -> &mut Self {
123 self.align_horizontal = String::from(option);
124 self
125 }
126
127 pub fn set_align_vertical(&mut self, option: &str) -> &mut Self {
131 self.align_vertical = String::from(option);
132 self
133 }
134
135 pub fn set_fontsize(&mut self, fontsize: f64) -> &mut Self {
137 self.fontsize = fontsize;
138 self
139 }
140
141 pub fn set_rotation(&mut self, rotation: f64) -> &mut Self {
145 self.rotation = Some(rotation);
146 self
147 }
148
149 pub fn set_bbox(&mut self, flag: bool) -> &mut Self {
151 self.bbox = flag;
152 self
153 }
154
155 pub fn set_bbox_facecolor(&mut self, color: &str) -> &mut Self {
157 self.bbox_facecolor = String::from(color);
158 self
159 }
160
161 pub fn set_bbox_edgecolor(&mut self, color: &str) -> &mut Self {
163 self.bbox_edgecolor = String::from(color);
164 self
165 }
166
167 pub fn set_bbox_alpha(&mut self, value: f64) -> &mut Self {
169 self.bbox_alpha = value;
170 self
171 }
172
173 pub fn set_bbox_style(&mut self, style: &str) -> &mut Self {
189 self.bbox_style = String::from(style);
190 self
191 }
192
193 pub fn set_extra(&mut self, extra: &str) -> &mut Self {
203 self.extra = extra.to_string();
204 self
205 }
206
207 fn options(&self) -> String {
209 let mut opt = String::new();
210 if self.color != "" {
211 write!(&mut opt, ",color='{}'", self.color).unwrap();
212 }
213 if self.align_horizontal != "" {
214 write!(&mut opt, ",ha='{}'", self.align_horizontal).unwrap();
215 }
216 if self.align_vertical != "" {
217 write!(&mut opt, ",va='{}'", self.align_vertical).unwrap();
218 }
219 if self.fontsize > 0.0 {
220 write!(&mut opt, ",fontsize={}", self.fontsize).unwrap();
221 }
222 if let Some(rotation) = self.rotation {
223 write!(&mut opt, ",rotation={}", rotation).unwrap();
224 }
225 if self.extra != "" {
226 write!(&mut opt, ",{}", self.extra).unwrap();
227 }
228 opt
229 }
230
231 fn options_bbox(&self) -> String {
233 let mut opt = String::new();
234 if self.bbox_facecolor != "" {
235 write!(&mut opt, "facecolor='{}',", self.bbox_facecolor).unwrap();
236 }
237 if self.bbox_edgecolor != "" {
238 write!(&mut opt, "edgecolor='{}',", self.bbox_edgecolor).unwrap();
239 }
240 write!(&mut opt, "alpha={},", self.bbox_alpha).unwrap();
241 if self.bbox_style != "" {
242 write!(&mut opt, "boxstyle='{}',", self.bbox_style).unwrap();
243 }
244 opt
245 }
246}
247
248impl GraphMaker for Text {
249 fn get_buffer<'a>(&'a self) -> &'a String {
250 &self.buffer
251 }
252 fn clear_buffer(&mut self) {
253 self.buffer.clear();
254 }
255}
256
257#[cfg(test)]
260mod tests {
261 use super::Text;
262 use crate::GraphMaker;
263
264 #[test]
265 fn new_works() {
266 let text = Text::new();
267 assert_eq!(text.color.len(), 0);
268 assert_eq!(text.align_horizontal.len(), 0);
269 assert_eq!(text.align_vertical.len(), 0);
270 assert_eq!(text.fontsize, 0.0);
271 assert_eq!(text.rotation, None);
272 assert_eq!(text.buffer.len(), 0);
273 }
274
275 #[test]
276 fn options_works() {
277 let mut text = Text::new();
278 text.set_color("red")
279 .set_align_horizontal("center")
280 .set_align_vertical("center")
281 .set_fontsize(8.0)
282 .set_rotation(45.0);
283 let opt = text.options();
284 assert_eq!(
285 opt,
286 ",color='red'\
287 ,ha='center'\
288 ,va='center'\
289 ,fontsize=8\
290 ,rotation=45"
291 );
292 }
293
294 #[test]
295 fn options_box_works() {
296 let mut text = Text::new();
297 text.set_bbox(true)
298 .set_bbox_facecolor("pink")
299 .set_bbox_edgecolor("black")
300 .set_bbox_alpha(0.3)
301 .set_bbox_style("round,pad=0.4");
302 assert_eq!(text.bbox, true);
303 let opt = text.options_bbox();
304 assert_eq!(
305 opt,
306 "facecolor='pink',\
307 edgecolor='black',\
308 alpha=0.3,\
309 boxstyle='round,pad=0.4',"
310 );
311 }
312
313 #[test]
314 fn draw_works() {
315 let mut text = Text::new();
316 text.draw(1.2, 3.4, &"message".to_string());
317 let b: &str = "t=plt.text(1.2,3.4,r'message')\n";
318 assert_eq!(text.buffer, b);
319 text.clear_buffer();
320 assert_eq!(text.buffer, "");
321 }
322
323 #[test]
324 fn draw_3d_works() {
325 let mut text = Text::new();
326 text.draw_3d(1.2, 3.4, 5.6, &"message".to_string());
327 let b: &str = "t=ax3d().text(1.2,3.4,5.6,r'message')\n";
328 assert_eq!(text.buffer, b);
329 }
330}