// Numeric scaling helpers shared by the XY charts (line, scatter).

///|
/// The minimum and maximum of a list of values. An empty list yields `(0, 1)`
/// so callers can scale and divide without special-casing emptiness.
fn extent(values : Array[Double]) -> (Double, Double) {
  if values.length() == 0 {
    return (0.0, 1.0)
  }
  let mut lo = values[0]
  let mut hi = values[0]
  for v in values {
    if v < lo {
      lo = v
    }
    if v > hi {
      hi = v
    }
  }
  (lo, hi)
}

///|
/// Linearly map `v` from the domain `[d0, d1]` onto the range `[r0, r1]`.
/// A degenerate domain (`d0 == d1`) maps to the midpoint of the range.
fn scale_linear(
  v : Double,
  d0 : Double,
  d1 : Double,
  r0 : Double,
  r1 : Double,
) -> Double {
  if d0 == d1 {
    (r0 + r1) / 2.0
  } else {
    r0 + (v - d0) / (d1 - d0) * (r1 - r0)
  }
}