use super::funejson::Value; use super::math_round_float::round_float; /// The rectangle left for data once the margins are taken off the chart. /// /// # Panics /// Panics on a negative margin or margins that leave no room. pub fn plot_area(width: f64, height: f64, margins: &Margins) -> PlotArea { let (top, right, bottom, left) = (margins.top, margins.right, margins.bottom, margins.left); if !(top >= 0.0 && right >= 0.0 && bottom >= 0.0 && left >= 0.0) { panic!("margins must not be negative"); } let w = width - left - right; let h = height - top - bottom; // A zero or negative plot would draw nothing, or draw everything flipped. if !(w > 0.0 && h > 0.0) { panic!("margins leave no room to plot: {} x {} less margins is {} x {}", width, height, w, h); } PlotArea { x: round_float(left, 2), y: round_float(top, 2), width: round_float(w, 2), height: round_float(h, 2) } } pub fn plot_area_to_value(p: &PlotArea) -> Value { Value::obj(vec![ ("x", Value::Float(p.x)), ("y", Value::Float(p.y)), ("width", Value::Float(p.width)), ("height", Value::Float(p.height)), ]) } pub fn margins_from_value(v: &Value) -> Margins { Margins { top: v.get("top").as_f64(), right: v.get("right").as_f64(), bottom: v.get("bottom").as_f64(), left: v.get("left").as_f64(), } } pub fn fune_vector(args: &[Value]) -> Value { plot_area_to_value(&plot_area(args[0].as_f64(), args[1].as_f64(), &margins_from_value(&args[2]))) }