gnuplot/
options.rs1// Copyright (c) 2013-2014 by SiegeLord
2//
3// All rights reserved. Distributed under LGPL 3.0. For full terms see the file LICENSE.
4
5pub use self::AlignType::*;
6pub use self::ArrowheadType::*;
7pub use self::AutoOption::*;
8pub use self::BorderLocation2D::*;
9pub use self::ContourStyle::*;
10pub use self::DashType::*;
11pub use self::FillPatternType::*;
12pub use self::FillRegionType::*;
13pub use self::LabelOption::*;
14pub use self::LegendOption::*;
15pub use self::MarginSide::*;
16pub use self::PaletteType::*;
17pub use self::PlotOption::*;
18pub use self::Tick::*;
19pub use self::TickOption::*;
20pub use self::XAxis::*;
21pub use self::YAxis::*;
22use crate::util::OneWayOwned;
23use crate::writer::Writer;
24use crate::ColorType;
25
26/// An enumeration of plot options you can supply to plotting commands, governing
27/// things like line width, color and others
28#[derive(Clone, Debug, PartialOrd, PartialEq)]
29pub enum PlotOption<T>
30{
31 /// Sets the symbol used for points. The valid characters are as follows:
32 ///
33 /// * `.` - dot
34 /// * `+` - plus
35 /// * `x` - cross
36 /// * `*` - star
37 /// * `s` - empty square
38 /// * `S` - filled square
39 /// * `o` - empty circle
40 /// * `O` - filled circle
41 /// * `t` - empty triangle
42 /// * `T` - filled triangle
43 /// * `d` - empty del (upside down triangle)
44 /// * `D` - filled del (upside down triangle)
45 /// * `r` - empty rhombus
46 /// * `R` - filled rhombus
47 PointSymbol(char),
48 /// Sets the size of the points. The size acts as a multiplier, with 1.0 being the default.
49 PointSize(f64),
50 /// Sets the caption of the plot element. Set to empty to hide it from the legend.
51 Caption(T),
52 /// Sets the width of lines.
53 LineWidth(f64),
54 /// Sets the color of the plot element. The passed string can be a color name
55 /// (e.g. "black" works), or an HTML color specifier (e.g. "#FFFFFF" is white). This specifies the fill color of a filled plot.
56 Color(ColorType<T>),
57 /// Sets the color of the border of a filled plot (if it has one). The passed string can be a color name
58 /// (e.g. "black" works), or an HTML color specifier (e.g. "#FFFFFF" is white).
59 BorderColor(ColorType<T>),
60 /// Sets the style of the line. Note that not all gnuplot terminals support dashed lines. See DashType for the available styles.
61 LineStyle(DashType),
62 /// Sets the transparency of a filled plot. `0.0` - fully transparent, `1.0` - fully opaque. Cannot be used with `FillPattern`.
63 FillAlpha(f64),
64 /// Sets the fill region. See `FillRegionType` for the available regions.
65 FillRegion(FillRegionType),
66 /// Sets the fill pattern. If left at `Auto`, the pattern alternates automatically. Otherwise, see `FillPatternType` for
67 /// the available patterns. Cannot be used with `FillAlpha`.
68 FillPattern(AutoOption<FillPatternType>),
69 /// Sets what an arrowhead looks like
70 ArrowType(ArrowheadType),
71 /// Sets the size of the arrowhead. This is specified in the units of graph (i.e. `1.0` would make the arrow as big as the graph).
72 ArrowSize(f64),
73 /// Width of the whisker bars (as a fraction of the box width) for box and whisker plots.
74 WhiskerBars(f64),
75 /// Which axis pair to use for the plot element.
76 Axes(XAxis, YAxis),
77 /// Box width set per box for box plots: each element is the width of one box
78 BoxWidth(Vec<f64>),
79}
80
81impl<'l> OneWayOwned for PlotOption<&'l str>
82{
83 type Output = PlotOption<String>;
84 fn to_one_way_owned(&self) -> Self::Output
85 {
86 match *self
87 {
88 PointSymbol(v) => PointSymbol(v),
89 PointSize(v) => PointSize(v),
90 Caption(v) => Caption(v.into()),
91 LineWidth(v) => LineWidth(v),
92 Color(ref v) => Color(v.to_one_way_owned()),
93 BorderColor(ref v) => BorderColor(v.to_one_way_owned()),
94 LineStyle(v) => LineStyle(v),
95 FillAlpha(v) => FillAlpha(v),
96 FillRegion(v) => FillRegion(v),
97 ArrowType(v) => ArrowType(v),
98 ArrowSize(v) => ArrowSize(v),
99 WhiskerBars(v) => WhiskerBars(v),
100 FillPattern(v) => FillPattern(v),
101 Axes(x, y) => Axes(x, y),
102 BoxWidth(ref d) => BoxWidth(d.clone()),
103 }
104 }
105}
106
107/// An enumeration of possible X-axes
108#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
109pub enum XAxis
110{
111 X1,
112 X2,
113}
114
115/// An enumeration of possible Y-axes
116#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
117pub enum YAxis
118{
119 Y1,
120 Y2,
121}
122
123/// An enumeration of possible fill regions
124#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
125pub enum FillRegionType
126{
127 Above,
128 Below,
129 Between,
130}
131
132/// An enumeration of possible text and label alignments
133#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
134pub enum AlignType
135{
136 AlignLeft,
137 AlignRight,
138 AlignCenter,
139 AlignTop,
140 AlignBottom,
141}
142
143/// An enumeration of possible dash styles
144#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
145pub enum DashType
146{
147 Solid,
148 SmallDot,
149 Dot,
150 Dash,
151 DotDash,
152 DotDotDash,
153}
154
155impl DashType
156{
157 pub fn to_int(&self) -> i32
158 {
159 match *self
160 {
161 Solid => 1,
162 SmallDot => 0,
163 Dash => 2,
164 Dot => 3,
165 DotDash => 4,
166 DotDotDash => 5,
167 }
168 }
169}
170
171/// An enumeration of possible arrow head styles
172#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
173pub enum ArrowheadType
174{
175 /// An arrow head shaped like a 'V'
176 Open,
177 /// An arrow head shaped like an outlined triangle
178 Closed,
179 /// An arrow head shaped like a filled triangle
180 Filled,
181 /// No arrow head
182 NoArrow,
183}
184
185/// An enumeration of something that can either be fixed (e.g. the maximum of X values),
186/// or automatically determined
187#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
188pub enum AutoOption<T>
189{
190 /// Fixes the value to a specific value
191 Fix(T),
192 /// Lets the value scale automatically
193 Auto,
194}
195
196impl<T> AutoOption<T>
197{
198 /// Same as `Option::map`
199 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> AutoOption<U>
200 {
201 match self
202 {
203 Fix(v) => Fix(f(v)),
204 Auto => Auto,
205 }
206 }
207}
208
209impl<T: ToString> OneWayOwned for AutoOption<T>
210{
211 type Output = AutoOption<String>;
212 fn to_one_way_owned(&self) -> Self::Output
213 {
214 match self
215 {
216 Fix(v) => Fix(v.to_string()),
217 Auto => Auto,
218 }
219 }
220}
221
222/// An enumeration of label options that control label attributes
223#[derive(Clone, Debug, PartialOrd, PartialEq)]
224pub enum LabelOption<T>
225{
226 /// Sets the offset of the label in characters
227 TextOffset(f64, f64),
228 /// Sets the font of the label. The string specifies the font type (e.g. "Arial") and the number specifies the size (the units are terminal dependent, but are often points)
229 Font(T, f64),
230 /// Sets the color of the label text. The passed string can be a color name
231 /// (e.g. "black" works), or an HTML color specifier (e.g. "#FFFFFF" is white)
232 TextColor(ColorType<T>),
233 /// Rotates the label by a certain number of degrees
234 Rotate(f64),
235 /// Sets the horizontal alignment of the label text (default is left alignment). See AlignType.
236 TextAlign(AlignType),
237 /// Sets a marker for the label. By default no marker is drawn. The valid characters are as follows:
238 ///
239 /// * `.` - dot
240 /// * `+` - plus
241 /// * `x` - cross
242 /// * `*` - star
243 /// * `s` - empty square
244 /// * `S` - filled square
245 /// * `o` - empty circle
246 /// * `O` - filled circle
247 /// * `t` - empty triangle
248 /// * `T` - filled triangle
249 /// * `d` - empty del (upside down triangle)
250 /// * `D` - filled del (upside down triangle)
251 /// * `r` - empty rhombus
252 /// * `R` - filled rhombus
253 MarkerSymbol(char),
254 /// Sets the color of the marker. The passed string can be a color name
255 /// (e.g. "black" works), or an HTML color specifier (e.g. "#FFFFFF" is white)
256 MarkerColor(ColorType<T>),
257 /// Sets the size of the marker. The size acts as a multiplier, with 1.0 being the default.
258 MarkerSize(f64),
259}
260
261impl<'l> OneWayOwned for LabelOption<&'l str>
262{
263 type Output = LabelOption<String>;
264 fn to_one_way_owned(&self) -> Self::Output
265 {
266 match self.clone()
267 {
268 TextOffset(v1, v2) => TextOffset(v1, v2),
269 Font(v1, v2) => Font(v1.into(), v2),
270 TextColor(v) => TextColor(v.to_one_way_owned()),
271 Rotate(v) => Rotate(v),
272 TextAlign(v) => TextAlign(v),
273 MarkerSymbol(v) => MarkerSymbol(v),
274 MarkerColor(v) => MarkerColor(v.to_one_way_owned()),
275 MarkerSize(v) => MarkerSize(v),
276 }
277 }
278}
279
280/// An enumeration of axis tick options
281#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
282pub enum TickOption<T>
283{
284 /// Specifies whether the ticks are drawn at the borders of the plot, or on the axis
285 OnAxis(bool),
286 /// If the axes are drawn on the border, this specifies whether to draw the ticks on the opposite border as well
287 Mirror(bool),
288 /// If the axes are drawn on the border, this specifies whether to draw the ticks pointing inward or outward
289 Inward(bool),
290 /// Sets the scale of the minor ticks
291 MinorScale(f64),
292 /// Sets the scale of the major ticks
293 MajorScale(f64),
294 /// Format of the tick labels, e.g. "%.1f ms" will produces labels with "1 ms, 2 ms" etc.
295 Format(T),
296}
297
298impl<'l> OneWayOwned for TickOption<&'l str>
299{
300 type Output = TickOption<String>;
301 fn to_one_way_owned(&self) -> Self::Output
302 {
303 match *self
304 {
305 OnAxis(v) => OnAxis(v),
306 Mirror(v) => Mirror(v),
307 Inward(v) => Inward(v),
308 MinorScale(v) => MinorScale(v),
309 MajorScale(v) => MajorScale(v),
310 Format(v) => Format(v.into()),
311 }
312 }
313}
314
315/// Specifies a type of axis tick
316#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
317pub enum Tick<T, S>
318{
319 /// Major ticks have position and an optional label. The label may have a single C-style format specifier which will be replaced by the location of the tick
320 Major(T, AutoOption<S>),
321 /// Minor ticks only have position
322 Minor(T),
323}
324
325impl<'l, T: Clone, S: ToString> OneWayOwned for Tick<T, S>
326{
327 type Output = Tick<T, String>;
328 fn to_one_way_owned(&self) -> Self::Output
329 {
330 match self
331 {
332 Minor(v) => Minor(v.clone()),
333 Major(v, s) => Major(v.clone(), s.to_one_way_owned()),
334 }
335 }
336}
337
338/// Plot border locations
339#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
340pub enum BorderLocation2D
341{
342 Bottom = 1,
343 Left = 2,
344 Top = 4,
345 Right = 8,
346}
347
348/// Plot margins
349#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
350pub enum MarginSide
351{
352 MarginLeft(f32),
353 MarginRight(f32),
354 MarginTop(f32),
355 MarginBottom(f32),
356}
357
358/// Legend options
359#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
360pub enum LegendOption<T>
361{
362 /// Puts curve samples to the left of the label
363 Reverse,
364 /// Displays legend entries in opposite order
365 Invert,
366 /// Makes the legend horizontal (default is vertical)
367 Horizontal,
368 /// Specifies the location of the legend. The first argument specifies the horizontal
369 /// placement with respect to its position, and the second argument specifies the vertical placement
370 Placement(AlignType, AlignType),
371 /// Title of the legend
372 Title(T),
373 /// Specifies the maximum number of rows, when the legend is vertical
374 MaxRows(u32),
375 /// Specifies the maximum number of columns, when the legend is horizontal
376 MaxCols(u32),
377}
378
379impl<'l> OneWayOwned for LegendOption<&'l str>
380{
381 type Output = LegendOption<String>;
382 fn to_one_way_owned(&self) -> Self::Output
383 {
384 match *self
385 {
386 Reverse => Reverse,
387 Invert => Invert,
388 Horizontal => Horizontal,
389 Placement(v1, v2) => Placement(v1, v2),
390 Title(v) => Title(v.into()),
391 MaxRows(v) => MaxRows(v),
392 MaxCols(v) => MaxCols(v),
393 }
394 }
395}
396
397/// Specifies how the contours are drawn
398#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
399pub enum ContourStyle
400{
401 /// Draw lines between points of equal value
402 Linear,
403 /// Draw somewhat smoother curves between points with equal value.
404 ///
405 /// The argument specifies the number of points to use to approximate the
406 /// curve for the final drawing step (clamped to range from 2 to 100).
407 Cubic(u32),
408 /// Draw an even smoother curve, this time approximating the locations of
409 /// points with equal value (clamped to range from 2 to 100).
410 ///
411 /// The first argument specifies the number of points to use to approximate
412 /// the curve for the final drawing step. The second argument specifies the
413 /// order of the polynomial (clamped to range from 2 to 10).
414 Spline(u32, u32),
415}
416
417/// Specifies what sort of palette to use
418#[derive(Clone, Debug, PartialOrd, PartialEq)]
419pub enum PaletteType<T>
420{
421 /// Use a gray palette with a specified gamma
422 Gray(f32),
423 /// Use a palette with that uses a predefined formula for each color component.
424 /// Each formula is identified by an integer between [-36, 36]. See gnuplot documentation, or use the pre-defined constants.
425 Formula(i32, i32, i32),
426 /// Use a cube helix palette, with a certain start (in radians), cycles, saturation and gamma.
427 CubeHelix(f32, f32, f32, f32),
428 /// A custom palette
429 /// is specified by a sequence of 4-tuples (with at least two elements). The first
430 /// element is the grayscale value that is mapped to the remaining three elements
431 /// which specify the red, green and blue components of the color.
432 /// The grayscale values must be non-decreasing. All values must range from 0 to 1.
433 Custom(T),
434}
435
436impl<'l> OneWayOwned for PaletteType<&'l [(f32, f32, f32, f32)]>
437{
438 type Output = PaletteType<Vec<(f32, f32, f32, f32)>>;
439 fn to_one_way_owned(&self) -> Self::Output
440 {
441 match *self
442 {
443 Gray(v) => Gray(v),
444 Formula(v1, v2, v3) => Formula(v1, v2, v3),
445 CubeHelix(v1, v2, v3, v4) => CubeHelix(v1, v2, v3, v4),
446 Custom(v) => Custom(v.into()),
447 }
448 }
449}
450
451/// A gray palette
452pub const GRAY: PaletteType<&'static [(f32, f32, f32, f32)]> = Gray(1.0);
453/// Default Gnuplot palette
454pub const COLOR: PaletteType<&'static [(f32, f32, f32, f32)]> = Formula(7, 5, 15);
455/// Classic rainbow palette with terrible perceptual properties
456pub const RAINBOW: PaletteType<&'static [(f32, f32, f32, f32)]> = Formula(33, 13, 10);
457/// A black body palette
458pub const HOT: PaletteType<&'static [(f32, f32, f32, f32)]> = Formula(34, 35, 36);
459/// A nice default for a cube helix
460pub const HELIX: PaletteType<&'static [(f32, f32, f32, f32)]> = CubeHelix(0.5, -0.8, 2.0, 1.0);
461
462impl PaletteType<Vec<(f32, f32, f32, f32)>>
463{
464 pub fn write_out_commands(&self, w: &mut dyn Writer)
465 {
466 match *self
467 {
468 Gray(gamma) =>
469 {
470 assert!(gamma > 0.0, "Gamma must be positive");
471 writeln!(w, "set palette gray gamma {:.12e}", gamma);
472 }
473 Formula(r, g, b) =>
474 {
475 assert!(r >= -36 && r <= 36, "Invalid r formula!");
476 assert!(g >= -36 && g <= 36, "Invalid g formula!");
477 assert!(b >= -36 && b <= 36, "Invalid b formula!");
478 writeln!(w, "set palette rgbformulae {},{},{}", r, g, b);
479 }
480 CubeHelix(start, rev, sat, gamma) =>
481 {
482 assert!(sat >= 0.0, "Saturation must be non-negative");
483 assert!(gamma > 0.0, "Gamma must be positive");
484 writeln!(
485 w,
486 "set palette cubehelix start {:.12e} cycles {:.12e} saturation {:.12e} gamma {:.12e}",
487 start, rev, sat, gamma
488 );
489 }
490 Custom(ref entries) =>
491 {
492 if entries.len() < 2
493 {
494 panic!("Need at least 2 elements in a custom palette");
495 }
496 write!(w, "set palette defined (");
497
498 let mut first = true;
499 let mut old_x = 0.0;
500 for &(x, r, g, b) in entries
501 {
502 if first
503 {
504 old_x = x;
505 first = false;
506 }
507 else
508 {
509 write!(w, ",");
510 }
511 assert!(x >= old_x, "The gray levels must be non-decreasing!");
512 old_x = x;
513
514 write!(w, "{:.12e} {:.12e} {:.12e} {:.12e}", x, r, g, b);
515 }
516 writeln!(w, ")");
517 }
518 }
519 }
520}
521
522/// Gnuplot version identifier. This is used to handle version-specific
523/// features.
524#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
525pub struct GnuplotVersion
526{
527 pub major: i32,
528 pub minor: i32,
529}
530
531/// Fill patterns.
532///
533/// Note that these are not guaranteed to be consistent between terminals,
534/// but the following names appear to be the most common interpretations of
535/// the numerical values of these patterns.
536#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
537pub enum FillPatternType
538{
539 Pattern0 = 0,
540 BigCrosses = 1,
541 SmallCrosses = 2,
542 Pattern3 = 3,
543 BigBackSlashes = 4,
544 BigForwardSlashes = 5,
545 SmallBackSlashes = 6,
546 SmallForwardSlashes = 7,
547 Pattern8 = 8,
548}
549
550/// Multiplot Fill Order Options
551#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
552pub enum MultiplotFillOrder
553{
554 /// "rowsfirst" gnuplot option.
555 RowsFirst,
556 /// "columnfirst" gnuplot option.
557 ColumnsFirst,
558}
559
560/// Multiplot Fill Order Options
561#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
562pub enum MultiplotFillDirection
563{
564 /// "downward" gnuplot option.
565 Downwards,
566 /// "upward" gnuplot option.
567 Upwards,
568}