use crate::axis::plot::Plot2D;
use std::fmt;
#[allow(unused_imports)]
use crate::Picture;
pub mod plot;
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum AxisKey {
Custom(String),
XMode(Scale),
YMode(Scale),
Title(String),
XLabel(String),
YLabel(String),
}
impl fmt::Display for AxisKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AxisKey::Custom(key) => write!(f, "{key}"),
AxisKey::XMode(value) => write!(f, "xmode={value}"),
AxisKey::YMode(value) => write!(f, "ymode={value}"),
AxisKey::Title(value) => write!(f, "title={{{value}}}"),
AxisKey::XLabel(value) => write!(f, "xlabel={{{value}}}"),
AxisKey::YLabel(value) => write!(f, "ylabel={{{value}}}"),
}
}
}
#[derive(Clone, Debug, Default)]
pub struct Axis {
keys: Vec<AxisKey>,
pub plots: Vec<Plot2D>,
}
impl fmt::Display for Axis {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\\begin{{axis}}")?;
if !self.keys.is_empty() {
writeln!(f, "[")?;
for key in self.keys.iter() {
writeln!(f, "\t{key},")?;
}
write!(f, "]")?;
}
writeln!(f)?;
for plot in self.plots.iter() {
writeln!(f, "{plot}")?;
}
write!(f, "\\end{{axis}}")?;
Ok(())
}
}
impl From<Plot2D> for Axis {
fn from(plot: Plot2D) -> Self {
Axis {
keys: Vec::new(),
plots: vec![plot],
}
}
}
impl Axis {
pub fn new() -> Self {
Default::default()
}
pub fn set_title<S: Into<String>>(&mut self, title: S) {
self.add_key(AxisKey::Title(title.into()));
}
pub fn set_x_label<S: Into<String>>(&mut self, label: S) {
self.add_key(AxisKey::XLabel(label.into()));
}
pub fn set_y_label<S: Into<String>>(&mut self, label: S) {
self.add_key(AxisKey::YLabel(label.into()));
}
pub fn add_key(&mut self, key: AxisKey) {
match key {
AxisKey::Custom(_) => (),
_ => {
if let Some(index) = self
.keys
.iter()
.position(|k| std::mem::discriminant(k) == std::mem::discriminant(&key))
{
self.keys.remove(index);
}
}
}
self.keys.push(key);
}
}
#[derive(Clone, Copy, Debug)]
pub enum Scale {
Log,
Normal,
}
impl fmt::Display for Scale {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Scale::Log => write!(f, "log"),
Scale::Normal => write!(f, "normal"),
}
}
}
#[cfg(test)]
mod tests;