use super::{Box, Color, NIL_VALUE};
use crate::Point;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub enum AxisScale {
#[default]
Linear,
Log(f32),
}
#[derive(Clone, PartialEq, Debug, Default, Serialize, Deserialize)]
pub enum Position {
#[default]
Left,
Top,
Right,
Bottom,
Inside,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub enum Align {
Left,
#[default]
Center,
Right,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
pub enum Symbol {
None,
Circle(f32, Option<Color>),
Rect(f32, Option<Color>),
Triangle(f32, Option<Color>),
Diamond(f32, Option<Color>),
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
pub enum SeriesCategory {
Line,
Bar,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub enum MarkLineCategory {
#[default]
Average,
Min,
Max,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub enum MarkPointCategory {
#[default]
Min,
Max,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub struct MarkLine {
pub category: MarkLineCategory,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub struct MarkPoint {
pub category: MarkPointCategory,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)]
pub struct Series {
pub name: String,
pub data: Vec<Option<f32>>,
pub start_index: usize,
pub index: Option<usize>,
pub y_axis_index: usize,
pub label_show: bool,
pub mark_lines: Vec<MarkLine>,
pub mark_points: Vec<MarkPoint>,
pub colors: Option<Vec<Option<Color>>>,
pub category: Option<SeriesCategory>,
pub stroke_dash_array: Option<String>,
pub stack: Option<String>,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
pub struct AnimationConfig {
pub duration: u32,
pub easing: String,
pub delay: u32,
}
impl Default for AnimationConfig {
fn default() -> Self {
AnimationConfig {
duration: 1000,
easing: "ease".to_string(),
delay: 80,
}
}
}
#[derive(Clone, PartialEq, Debug, Default)]
pub struct SeriesLabel {
pub point: Point,
pub text: String,
}
impl Series {
pub fn new(name: String, data: Vec<f32>) -> Self {
Series {
name,
data: data
.into_iter()
.map(|v| if v == NIL_VALUE { None } else { Some(v) })
.collect(),
index: None,
..Default::default()
}
}
pub fn new_nullable(name: String, data: Vec<Option<f32>>) -> Self {
Series {
name,
data,
index: None,
..Default::default()
}
}
pub(crate) fn data_values(&self) -> Vec<f32> {
self.data.iter().map(|v| v.unwrap_or(NIL_VALUE)).collect()
}
}
impl From<(&str, Vec<f32>)> for Series {
fn from(value: (&str, Vec<f32>)) -> Self {
Series::new(value.0.to_string(), value.1)
}
}
impl From<(&str, Vec<Option<f32>>)> for Series {
fn from(value: (&str, Vec<Option<f32>>)) -> Self {
Series::new_nullable(value.0.to_string(), value.1)
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct YAxisConfig {
pub axis_font_size: f32,
pub axis_font_color: Color,
pub axis_font_weight: Option<String>,
pub axis_stroke_color: Color,
pub axis_width: Option<f32>,
pub axis_split_number: usize,
pub axis_name_gap: f32,
pub axis_name_align: Option<Align>,
pub axis_margin: Option<Box>,
pub axis_formatter: Option<String>,
pub axis_min: Option<f32>,
pub axis_max: Option<f32>,
pub axis_scale: AxisScale,
}
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Fill {
Solid(Color),
LinearGradient {
start_color: Color,
end_color: Color,
angle: f32,
},
}
impl Default for Fill {
fn default() -> Self {
Fill::Solid(Color::default())
}
}
impl From<Color> for Fill {
fn from(c: Color) -> Self {
Fill::Solid(c)
}
}
impl Fill {
pub fn is_transparent(&self) -> bool {
matches!(self, Fill::Solid(c) if c.is_transparent())
}
}