plotters_unsable/coord/
datetime.rs

1/// The datetime coordinates
2use chrono::{Date, DateTime, Duration, TimeZone};
3use std::ops::Range;
4
5use super::Ranged;
6
7/// The ranged coordinate for date
8pub struct RangedDate<Z: TimeZone>(Date<Z>, Date<Z>);
9
10/// The ranged coordinate for the date and time
11pub struct RangedDateTime<Z: TimeZone>(DateTime<Z>, DateTime<Z>);
12
13impl<Z: TimeZone> From<Range<Date<Z>>> for RangedDate<Z> {
14    fn from(range: Range<Date<Z>>) -> Self {
15        Self(range.start, range.end)
16    }
17}
18
19impl<Z: TimeZone> Ranged for RangedDate<Z> {
20    type ValueType = Date<Z>;
21
22    fn range(&self) -> Range<Date<Z>> {
23        self.0.clone()..self.1.clone()
24    }
25
26    fn map(&self, value: &Self::ValueType, limit: (i32, i32)) -> i32 {
27        let total_days = (self.1.clone() - self.0.clone()).num_days() as f64;
28        let value_days = (value.clone() - self.0.clone()).num_days() as f64;
29
30        (f64::from(limit.1 - limit.0) * value_days / total_days) as i32 + limit.0
31    }
32
33    fn key_points(&self, max_points: usize) -> Vec<Self::ValueType> {
34        let mut ret = vec![];
35
36        let total_days = (self.1.clone() - self.0.clone()).num_days();
37        let total_weeks = (self.1.clone() - self.0.clone()).num_weeks();
38
39        if total_days > 0 && total_days as usize <= max_points {
40            for day_idx in 0..=total_days {
41                ret.push(self.0.clone() + Duration::days(day_idx));
42            }
43            return ret;
44        }
45
46        if total_weeks > 0 && total_weeks as usize <= max_points {
47            for day_idx in 0..=total_weeks {
48                ret.push(self.0.clone() + Duration::weeks(day_idx));
49            }
50            return ret;
51        }
52
53        ret
54    }
55}
56
57impl<Z: TimeZone> super::AsRangedCoord for Range<Date<Z>> {
58    type CoordDescType = RangedDate<Z>;
59    type Value = Date<Z>;
60}