use crate::time_series::{TimeSeries, Style};
use crate::plotable::Plotable;
use plotlib::repr::Plot;
use plotlib::view::{View, ContinuousView};
#[derive(Clone)]
pub struct Season {
series: TimeSeries,
length: usize,
season: Option<usize>,
data: Option<Vec<(f64, f64)>>,
}
impl Season {
pub fn new(series: &TimeSeries, length: usize) -> Self {
Self {
series: series.clone(),
length,
season: None,
data: None,
}
}
pub fn set_season(mut self, u: usize) -> Self {
self.season = Some(u);
self.update_data();
self
}
fn update_data(&mut self) {
let mut v = Vec::new();
let data = self.series.get_data();
if let Some(season) = self.season {
let low = self.length * (season - 1);
let mut high = low + self.length;
if high > data.len() { high = data.len();
}
let mut x = 1;
for i in low..high {
let (_, y) = data[i];
v.push((x as f64, y));
x += 1;
}
self.data = Some(v);
} else {
panic!("Can't generate season data without a set season");
}
}
pub fn as_time_series(&self) -> TimeSeries {
TimeSeries::new(self.get_range())
}
pub fn get_range(&self) -> Vec<f64> {
if self.data.is_none() {
panic!("can't get domain from empty season");
}
let mut v = Vec::new();
for i in 0..self.data.as_ref().unwrap().len() {
v.push(self.data.as_ref().unwrap()[i].1); }
v
}
pub fn get_data(&self) -> Vec<(f64, f64)> {
if let Some(data) = &self.data {
data.clone()
} else {
panic!("Season data empty");
}
}
pub fn style(&self) -> Style {
self.series.style()
}
fn style_mut(&mut self) -> &mut Style {
&mut self.series.style
}
pub fn set_style(mut self, style: Style) -> Self {
self.series.style = style;
self
}
}
impl Plotable for Season {
fn plot(&self) -> Box<dyn View> {
let plot = self.as_plot();
Box::new(ContinuousView::new()
.add(plot))
}
fn as_plot(&self) -> Plot {
Plot::new(self.get_data())
.point_style(self.style().point)
.line_style(self.style().line)
}
}