#![allow(unused_variables)]
#![allow(unused_imports)]
#![allow(clippy::needless_lifetimes)]
use super::StyleOptions;
use crate::DEFAULT_FONT_FAMILY;
use animate::{CanvasContext, Point, TextStyle, TextWeight};
use dataflow::*;
use std::{
f64::consts::PI,
fmt,
ops::{Add, Mul, Sub},
};
pub fn rad2deg(angle: f64) -> f64 {
angle * 180.0 / PI
}
pub fn deg2rad(angle: f64) -> f64 {
angle * PI / 180.0
}
pub fn is_in_range(value: f64, min: f64, max: f64) -> bool {
value >= min && value <= max
}
pub fn polar2cartesian(center: &Point<f64>, radius: f64, angle: f64) -> Point<f64> {
let x = center.x + radius * (angle).cos();
let y = center.y + radius * (angle).sin();
Point::new(x, y)
}
pub fn round2places(value: f64, places: usize) -> f64 {
let p = f64::powf(10.0, places as f64);
let value = value * p;
value.round() / p
}
pub fn hex2rgba(hex_color: &str, alpha: f64) -> String {
unimplemented!();
}
pub fn hyphenate(s: &str) -> String {
unimplemented!();
}
pub fn find_max_value<'a, M, D>(stream: &DataStream<M, D>) -> D
where
M: fmt::Display,
D: fmt::Display + Copy + Into<f64> + Ord + Default,
{
let mut result: Option<D> = None;
for channel in stream.meta.iter() {
let channel_index = channel.tag as u64;
for frame in stream.frames.iter() {
if let Some(value) = frame.data.get(channel_index) {
match result {
Some(max_value) => {
if *value > max_value {
result = Some(*value);
}
}
None => result = Some(*value),
}
}
}
}
result.unwrap_or_default()
}
pub fn find_min_value<'a, M, D>(stream: &DataStream<M, D>) -> D
where
M: fmt::Display,
D: fmt::Display + Copy + Into<f64> + Ord + Default,
{
let mut result: Option<D> = None;
for channel in stream.meta.iter() {
let channel_index = channel.tag as u64;
for frame in stream.frames.iter() {
if let Some(value) = frame.data.get(channel_index) {
match result {
Some(min_value) => {
if *value < min_value {
error!("ASSIGN MIN VALUE {}", value);
result = Some(*value);
}
}
None => result = Some(*value),
}
}
}
}
result.unwrap_or_default()
}
pub fn calculate_interval(range: f64, target_steps: usize, min_interval: Option<f64>) -> f64 {
let interval = range / target_steps as f64;
let mag = interval.log10().floor();
let mut mag_pow = f64::powf(10.0, mag);
if let Some(min_interval) = min_interval {
mag_pow = mag_pow.max(min_interval);
}
let mut msd = (interval / mag_pow).round();
if msd > 5. {
msd = 10.;
} else if msd > 2. {
msd = 5.;
} else if msd == 0. {
msd = 1.;
}
msd * mag_pow
}
pub fn calculate_max_text_width<C>(ctx: &C, style: &StyleOptions, texts: &[String]) -> f64
where
C: CanvasContext,
{
let mut result = 0.0;
let fontfamily = match &style.fontfamily {
Some(val) => val.as_str(),
None => DEFAULT_FONT_FAMILY,
};
ctx.set_font(
fontfamily,
style.fontstyle.unwrap_or(TextStyle::Normal),
TextWeight::Normal,
style.fontsize.unwrap_or(12.),
);
for text in texts.iter() {
let width = ctx.measure_text(text).width;
if result < width {
result = width
}
}
result
}
pub fn calculate_control_points(
p1: Point<f64>,
p2: Point<f64>,
p3: Point<f64>,
t: f64,
) -> (Point<f64>, Point<f64>) {
let d21 = p2.distance_to(p1);
let d23 = p2.distance_to(p3);
let fa = t * d21 / (d21 + d23);
let fb = t * d23 / (d21 + d23);
let v13 = p3 - p1;
let cp1 = p2 - v13 * fa;
let cp2 = p2 + v13 * fb;
(cp1, cp2)
}
pub fn get_decimal_places(value: f64) -> usize {
if value.fract() == 0. {
return 0;
}
let tmp = format!("{}", value);
let split: Vec<&str> = tmp.split('.').collect();
split.get(1).unwrap().len()
}