| use std::cmp::{Ordering, PartialOrd}; |
| use std::iter::IntoIterator; |
| use std::ops::Range; |
| |
| use num_traits::{One, Zero}; |
| |
| /// Build a range that fits the data |
| /// |
| /// - `iter`: the iterator over the data |
| /// - **returns** The resulting range |
| /// |
| /// ```rust |
| /// use plotters::data::fitting_range; |
| /// |
| /// let data = [4, 14, -2, 2, 5]; |
| /// let range = fitting_range(&data); |
| /// assert_eq!(range, std::ops::Range { start: -2, end: 14 }); |
| /// ``` |
| pub fn fitting_range<'a, T: 'a, I: IntoIterator<Item = &'a T>>(iter: I) -> Range<T> |
| where |
| T: Zero + One + PartialOrd + Clone, |
| { |
| let (mut lb, mut ub) = (None, None); |
| |
| for value in iter.into_iter() { |
| if let Some(Ordering::Greater) = lb |
| .as_ref() |
| .map_or(Some(Ordering::Greater), |lbv: &T| lbv.partial_cmp(value)) |
| { |
| lb = Some(value.clone()); |
| } |
| |
| if let Some(Ordering::Less) = ub |
| .as_ref() |
| .map_or(Some(Ordering::Less), |ubv: &T| ubv.partial_cmp(value)) |
| { |
| ub = Some(value.clone()); |
| } |
| } |
| |
| lb.unwrap_or_else(Zero::zero)..ub.unwrap_or_else(One::one) |
| } |