mod grid;
pub use self::grid::Gridline;
use std::borrow::Cow;
use std::iter::IntoIterator;
use traits::Data;
use {Default, Display, Script};
#[derive(Clone, Copy)]
pub enum Axis {
BottomX,
LeftY,
RightY,
TopX,
}
impl Axis {
pub(crate) fn next(self) -> Option<Axis> {
use Axis::*;
match self {
BottomX => Some(LeftY),
LeftY => Some(RightY),
RightY => Some(TopX),
TopX => None,
}
}
}
#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub enum Axes {
BottomXLeftY,
BottomXRightY,
TopXLeftY,
TopXRightY,
}
#[derive(Clone, Copy)]
pub enum Range {
Auto,
Limits(f64, f64),
}
#[allow(missing_docs)]
#[derive(Clone, Copy)]
pub enum Scale {
Linear,
Logarithmic,
}
pub struct TicLabels<P, L> {
pub labels: L,
pub positions: P,
}
#[derive(Clone)]
pub struct AxisProperties {
major_grid: Gridline,
minor_grid: Gridline,
hidden: bool,
label: Option<Cow<'static, str>>,
logarithmic: bool,
range: Option<(f64, f64)>,
scale_factor: f64,
tics: Option<String>,
}
impl Default for AxisProperties {
fn default() -> AxisProperties {
AxisProperties {
major_grid: Gridline::new(false),
minor_grid: Gridline::new(true),
hidden: false,
label: None,
logarithmic: false,
range: None,
scale_factor: 1.,
tics: None,
}
}
}
impl AxisProperties {
pub fn hide(&mut self) -> &mut AxisProperties {
self.hidden = true;
self
}
pub fn show(&mut self) -> &mut AxisProperties {
self.hidden = false;
self
}
pub fn label<S>(&mut self, label: S) -> &mut AxisProperties
where
S: Into<Cow<'static, str>>,
{
self.label = Some(label.into());
self
}
pub fn range(&mut self, range: Range) -> &mut AxisProperties {
self.hidden = false;
match range {
Range::Auto => self.range = None,
Range::Limits(low, high) => self.range = Some((low, high)),
}
self
}
pub fn scale(&mut self, scale: Scale) -> &mut AxisProperties {
self.hidden = false;
match scale {
Scale::Linear => self.logarithmic = false,
Scale::Logarithmic => self.logarithmic = true,
}
self
}
pub fn scale_factor(&mut self, factor: f64) -> &mut AxisProperties {
self.scale_factor = factor;
self
}
pub fn tick_labels<P, L>(&mut self, tics: TicLabels<P, L>) -> &mut AxisProperties
where
L: IntoIterator,
L::Item: AsRef<str>,
P: IntoIterator,
P::Item: Data,
{
let TicLabels { positions, labels } = tics;
let pairs = positions
.into_iter()
.zip(labels.into_iter())
.map(|(pos, label)| format!("'{}' {}", label.as_ref(), pos.f64()))
.collect::<Vec<_>>();
if pairs.is_empty() {
self.tics = None
} else {
self.tics = Some(pairs.join(", "));
}
self
}
pub fn configure_major_grid<F: FnOnce(&mut Gridline) -> &mut Gridline>(
&mut self,
configure: F,
) -> &mut AxisProperties {
configure(&mut self.major_grid);
self
}
pub fn configure_minor_grid<F: FnOnce(&mut Gridline) -> &mut Gridline>(
&mut self,
configure: F,
) -> &mut AxisProperties {
configure(&mut self.minor_grid);
self
}
}
impl<'a> Script for (Axis, &'a AxisProperties) {
fn script(&self) -> String {
let &(axis, properties) = self;
let axis_ = axis.display();
let mut script = if properties.hidden {
return format!("unset {}tics\n", axis_);
} else {
format!("set {}tics nomirror ", axis_)
};
if let Some(ref tics) = properties.tics {
script.push_str(&format!("({})", tics))
}
script.push('\n');
if let Some(ref label) = properties.label {
script.push_str(&format!("set {}label '{}'\n", axis_, label))
}
if let Some((low, high)) = properties.range {
script.push_str(&format!("set {}range [{}:{}]\n", axis_, low, high))
}
if properties.logarithmic {
script.push_str(&format!("set logscale {}\n", axis_));
}
script.push_str(&(axis, &properties.major_grid).script());
script.push_str(&(axis, &properties.minor_grid).script());
script
}
}
impl ::ScaleFactorTrait for AxisProperties {
fn scale_factor(&self) -> f64 {
self.scale_factor
}
}