// XY scatter plot.

///|
/// Render a scatter plot of `(x, y)` points as a standalone SVG document
/// string. The y value axis gets nicely rounded gridlines; the x domain is
/// padded slightly so points never sit on the frame. `title`, `width`,
/// `height`, the point `radius` and `theme` are optional.
pub fn scatter_chart(
  data : Array[(Double, Double)],
  errors? : Array[Double] = [],
  x_title? : String = "",
  y_title? : String = "",
  title? : String = "",
  width? : Double = 480.0,
  height? : Double = 320.0,
  radius? : Double = 4.0,
  theme? : Theme = Theme::light(),
) -> String {
  let left = if y_title == "" { 48.0 } else { 64.0 }
  let right = 16.0
  let top = if title == "" { 16.0 } else { 40.0 }
  let bottom = if x_title == "" { 40.0 } else { 56.0 }
  let plot_w = width - left - right
  let plot_h = height - top - bottom
  let xs = data.map(fn(p) { p.0 })
  let ys = data.map(fn(p) { p.1 })
  let (xlo_raw, xhi_raw) = extent(xs)
  let (ylo, yhi) = extent_with_errors(ys, errors)
  let (axis_lo, axis_hi, ticks) = nice_ticks(ylo, yhi, 5)
  // Nicely rounded x ticks; the rounded domain usually already pads the data.
  let (xlo, xhi, x_ticks) = nice_ticks(xlo_raw, xhi_raw, 6)
  let body = StringBuilder::new()
  body.write_string(background_rect(theme, width, height))
  body.write_string(
    y_axis(theme, left, top, plot_w, plot_h, axis_lo, axis_hi, ticks),
  )
  body.write_string(x_axis(theme, left, top, plot_w, plot_h, xlo, xhi, x_ticks))
  let color = theme.color_at(0)
  for i in 0.. 0.0 {
      body.write_string(
        error_bar(
          px,
          scale_linear(y - e, axis_lo, axis_hi, top + plot_h, top),
          scale_linear(y + e, axis_lo, axis_hi, top + plot_h, top),
          8.0,
          color,
        ),
      )
    }
    body.write_string(
      elem("circle", [
        ("cx", num(px)),
        ("cy", num(py)),
        ("r", num(radius)),
        ("fill", color),
        ("fill-opacity", "0.7"),
      ]),
    )
  }
  body.write_string(
    axis_titles(theme, left, top, plot_w, plot_h, x_title, y_title),
  )
  if title != "" {
    body.write_string(
      label(width / 2.0, 24.0, title, size=16, weight="bold", fill=theme.title),
    )
  }
  document(width, height, body.to_string())
}