use super::axis::Axis;
use super::curve::Curve;
use crate::tsdb::{Aggregation, Sample, SampleMetrics};
#[derive(Clone)]
pub struct Chart {
pub title: Option<String>,
pub x_axis: Axis,
pub y_axis: Axis,
pub grid: bool,
pub curves: Vec<Curve>,
}
impl Default for Chart {
fn default() -> Self {
Chart {
title: None,
x_axis: Axis::default(),
y_axis: Axis::default(),
grid: true,
curves: vec![],
}
}
}
impl Chart {
pub fn set_title(&mut self, title: &str) {
self.title = Some(title.to_string());
}
pub fn set_xlabel(&mut self, label: &str) {
self.x_axis.label = Some(label.to_string());
}
pub fn set_ylabel(&mut self, label: &str) {
self.y_axis.label = Some(label.to_string());
}
pub fn add_curve(&mut self, curve: Curve) {
self.curves.push(curve);
}
pub fn zoom_horizontal(&mut self, amount: f64) {
let domain = self.x_axis.domain();
let step = domain * amount;
let x1 = self.x_axis.begin() - step;
let x2 = self.x_axis.end() + step;
self.x_axis.set_limits(x1, x2);
}
pub fn zoom_vertical(&mut self, amount: f64) {
let domain = self.y_axis.domain();
let step = domain * amount;
let y1 = self.y_axis.begin() - step;
let y2 = self.y_axis.end() + step;
self.y_axis.set_limits(y1, y2);
}
pub fn pan_horizontal(&mut self, amount: f64) {
let domain = self.x_axis.domain();
let step = domain * amount;
let x1 = self.x_axis.begin() + step;
let x2 = self.x_axis.end() + step;
self.x_axis.set_limits(x1, x2);
}
pub fn pan_vertical(&mut self, amount: f64) {
let domain = self.y_axis.domain();
let step = domain * amount;
let y1 = self.y_axis.begin() + step;
let y2 = self.y_axis.end() + step;
self.y_axis.set_limits(y1, y2);
}
pub fn autoscale(&mut self) {
let summaries: Vec<Aggregation<Sample, SampleMetrics>> =
self.curves.iter().filter_map(|c| c.summary()).collect();
if let Some(summary) = Aggregation::from_aggregations(&summaries) {
self.x_axis
.set_limits(summary.timespan.start.amount, summary.timespan.end.amount);
self.y_axis
.set_limits(summary.metrics().min, summary.metrics().max);
}
}
}