ezel 0.0.1

A good plotting library
Documentation
//!
//!
//!
//! Types
//!
//! - number
//! - category axis
//! - date axis
//! - duration axis
//! -
use piet::{RenderContext, Text, TextLayoutBuilder};

use super::labeling::LabelingAlgorithm;

pub const DEFAULT_LABEL_FONT_SIZE: f64 = 16.0;
pub const DEFAULT_LABEL_FONT_FAMILY: &str = "DejaVu Sans";
// const DEFAULT_LABEL_FONT_FAMILY: &str = "Arial";

/// `Axis` does not know how to draw itself.
/// `Cartesian2` or `Cartesian3` has a drawing logic.
#[derive(Default)]
pub struct Axis {
    pub label: Option<String>,
    pub scale: AxisScale,
    pub labeling_algorithm: LabelingAlgorithm,
}

impl Axis {
    pub fn new(label: Option<String>) -> Self {
        Self {
            label,
            ..Default::default()
        }
    }
    /// map the coordinate to the location to draw
    pub fn map(&self, coordinate: f64) -> f64 {
        coordinate
    }

    pub fn build_text_layout<C: RenderContext>(&self, ctx: &mut C) -> Option<C::TextLayout> {
        self.label.as_ref().map(|label| {
            ctx.text()
                .new_text_layout(label.to_string())
                .font(
                    ctx.text()
                        .font_family(DEFAULT_LABEL_FONT_FAMILY)
                        .unwrap_or_default(),
                    DEFAULT_LABEL_FONT_SIZE,
                )
                .build()
                .unwrap()
        })
    }
}

/// A mapping from user coordinates to drawing coordinates
///
/// For example, Log10 maps [10, 100, 1000] to [2, 3, 4] and clipping/zoom maps this to [0, 1, 2].
pub enum AxisScale {
    Identity,
    Ln,
    Log10,
    Exp,
}

impl AxisScale {
    /// x: user coordinate
    pub fn map(&self, x: f64) -> f64 {
        match self {
            Self::Identity => x,
            Self::Ln => x.ln(),
            Self::Log10 => x.log10(),
            Self::Exp => x.exp(),
        }
    }

    pub fn inverse_map(&self, x: f64) -> f64 {
        match self {
            Self::Identity => x,
            Self::Ln => x.exp(),
            Self::Log10 => f64::powf(10.0, x), // y = ln x / ln 10
            Self::Exp => x.ln(),
        }
    }
}

impl Default for AxisScale {
    fn default() -> Self {
        Self::Identity
    }
}

/// `TickLocator` determines major and minor ticks.
pub enum TickLocator {
    Auto,
}

impl TickLocator {
    /// returns a list of tick coordinates
    pub fn locate(&self, _scaled_value: f64) -> Vec<f64> {
        vec![0.0, 5.0, 10.0]
    }
}

impl Default for TickLocator {
    fn default() -> Self {
        Self::Auto
    }
}