use axes_common::*;
use datatype::*;
use options::*;
use std::io::Write;
use util::OneWayOwned;
use writer::Writer;
pub struct Axes3D
{
common: AxesCommonData,
z_axis: AxisData,
contour_base: bool,
contour_surface: bool,
contour_auto: AutoOption<u32>,
contour_levels: Option<Vec<f64>>,
contour_style: ContourStyle,
contour_label: AutoOption<String>,
}
impl Axes3D
{
pub(crate) fn new() -> Axes3D
{
Axes3D {
common: AxesCommonData::new(),
z_axis: AxisData::new(ZTickAxis),
contour_base: false,
contour_surface: false,
contour_auto: Auto,
contour_levels: None,
contour_style: Linear,
contour_label: Auto,
}
}
pub fn surface<'l, T: DataType, X: IntoIterator<Item = T>>(
&'l mut self, mat: X, num_rows: usize, num_cols: usize, dimensions: Option<(f64, f64, f64, f64)>, options: &[PlotOption<&str>],
) -> &'l mut Self
{
self.common.elems.push(PlotElement::new_plot_matrix(
Pm3D,
true,
mat,
num_rows,
num_cols,
dimensions,
options.to_one_way_owned(),
));
self
}
pub fn points<
'l,
Tx: DataType,
X: IntoIterator<Item = Tx>,
Ty: DataType,
Y: IntoIterator<Item = Ty>,
Tz: DataType,
Z: IntoIterator<Item = Tz>,
>(
&'l mut self, x: X, y: Y, z: Z, options: &[PlotOption<&str>],
) -> &'l mut Self
{
self.common
.elems
.push(PlotElement::new_plot3(Points, x, y, z, options.to_one_way_owned()));
self
}
pub fn lines<
'l,
Tx: DataType,
X: IntoIterator<Item = Tx>,
Ty: DataType,
Y: IntoIterator<Item = Ty>,
Tz: DataType,
Z: IntoIterator<Item = Tz>,
>(
&'l mut self, x: X, y: Y, z: Z, options: &[PlotOption<&str>],
) -> &'l mut Self
{
self.common
.elems
.push(PlotElement::new_plot3(Lines, x, y, z, options.to_one_way_owned()));
self
}
pub fn lines_points<
'l,
Tx: DataType,
X: IntoIterator<Item = Tx>,
Ty: DataType,
Y: IntoIterator<Item = Ty>,
Tz: DataType,
Z: IntoIterator<Item = Tz>,
>(
&'l mut self, x: X, y: Y, z: Z, options: &[PlotOption<&str>],
) -> &'l mut Self
{
self.common
.elems
.push(PlotElement::new_plot3(LinesPoints, x, y, z, options.to_one_way_owned()));
self
}
pub fn set_view<'l>(&'l mut self, pitch: f64, yaw: f64) -> &'l mut Self
{
writeln!(&mut self.common.commands, "set view {:.12e},{:.12e}", pitch, yaw);
self
}
pub fn set_view_map<'l>(&'l mut self) -> &'l mut Self
{
writeln!(&mut self.common.commands, "set view map");
self
}
pub fn set_z_label<'l>(&'l mut self, text: &str, options: &[LabelOption<&str>]) -> &'l mut Self
{
self.get_common_data_mut().set_label_common(ZLabel, text, options);
self
}
pub fn set_z_ticks<'l>(
&'l mut self, tick_placement: Option<(AutoOption<f64>, u32)>, tick_options: &[TickOption<&str>],
label_options: &[LabelOption<&str>],
) -> &'l mut Self
{
self.z_axis
.set_ticks(tick_placement, tick_options.to_one_way_owned(), label_options.to_one_way_owned());
self
}
pub fn set_z_ticks_custom<'l, T: DataType, TL: IntoIterator<Item = Tick<T>>>(
&'l mut self, ticks: TL, tick_options: &[TickOption<&str>], label_options: &[LabelOption<&str>],
) -> &'l mut Self
{
self.z_axis
.set_ticks_custom(ticks, tick_options.to_one_way_owned(), label_options.to_one_way_owned());
self
}
pub fn set_z_range<'l>(&'l mut self, min: AutoOption<f64>, max: AutoOption<f64>) -> &'l mut Self
{
self.z_axis.set_range(min, max);
self
}
pub fn set_z_reverse<'l>(&'l mut self, reverse: bool) -> &'l mut Self
{
self.z_axis.set_reverse(reverse);
self
}
pub fn set_z_log<'l>(&'l mut self, base: Option<f64>) -> &'l mut Self
{
self.z_axis.set_log(base);
self
}
pub fn set_z_grid<'l>(&'l mut self, show: bool) -> &'l mut Self
{
self.z_axis.set_grid(show);
self
}
pub fn show_contours<'l>(
&'l mut self, base: bool, surface: bool, style: ContourStyle, label: AutoOption<&str>, levels: AutoOption<u32>,
) -> &'l mut Self
{
self.contour_base = base;
self.contour_surface = surface;
self.contour_style = style;
self.contour_auto = levels;
self.contour_levels = None;
self.contour_label = label.map(|l| l.to_string());
self
}
pub fn show_contours_custom<'l, T: DataType, TC: IntoIterator<Item = T>>(
&'l mut self, base: bool, surface: bool, style: ContourStyle, label: AutoOption<&str>, levels: TC,
) -> &'l mut Self
{
self.contour_base = base;
self.contour_surface = surface;
self.contour_style = style;
self.contour_auto = Auto;
self.contour_levels = Some(levels.into_iter().map(|l| l.get()).collect());
self.contour_label = label.map(|l| l.to_string());
self
}
}
impl AxesCommonPrivate for Axes3D
{
fn get_common_data_mut(&mut self) -> &mut AxesCommonData
{
&mut self.common
}
fn get_common_data(&self) -> &AxesCommonData
{
&self.common
}
}
impl AxesCommon for Axes3D {}
pub(crate) trait Axes3DPrivate
{
fn write_out(&self, writer: &mut Writer);
}
impl Axes3DPrivate for Axes3D
{
fn write_out(&self, w: &mut Writer)
{
fn clamp<T: PartialOrd>(val: T, min: T, max: T) -> T
{
if val < min
{
min
}
else if val > max
{
max
}
else
{
val
}
}
if self.common.elems.len() == 0
{
return;
}
if self.contour_base || self.contour_surface
{
write!(w, "set contour ");
write!(
w,
"{}",
match (self.contour_base, self.contour_surface)
{
(true, false) => "base",
(false, true) => "surface",
(true, true) => "both",
_ => unreachable!(),
}
);
write!(w, "\n");
match self.contour_label
{
Auto => writeln!(w, "set clabel"),
Fix(ref s) => if s.len() == 0
{
writeln!(w, "unset clabel")
}
else
{
writeln!(w, r#"set clabel "{}""#, s)
},
};
fn set_cntrparam<F: FnOnce(&mut Writer)>(w: &mut Writer, wr: F)
{
write!(w, "set cntrparam ");
wr(w);
write!(w, "\n");
}
set_cntrparam(w, |w| {
write!(
w,
"{}",
match self.contour_style
{
Linear => "linear ",
Cubic(..) => "cubicspline",
Spline(..) => "bspline",
}
);
});
set_cntrparam(w, |w| {
let pt = match self.contour_style
{
Cubic(pt) => Some(pt),
Spline(pt, _) => Some(pt),
_ => None,
};
pt.map(|pt| {
write!(w, "points {}", clamp(pt, 2, 100));
});
});
set_cntrparam(w, |w| {
let ord = match self.contour_style
{
Spline(_, ord) => Some(ord),
_ => None,
};
ord.map(|ord| {
write!(w, "order {}", clamp(ord, 2, 10));
});
});
set_cntrparam(w, |w| {
write!(w, "levels ");
match self.contour_levels
{
Some(ref ls) =>
{
write!(w, "discrete ");
let mut left = ls.len();
for &l in ls.iter()
{
write!(w, "{:.12e}", l);
if left > 1
{
write!(w, ",");
}
left -= 1;
}
}
None =>
{
match self.contour_auto
{
Auto => write!(w, "auto "),
Fix(f) => write!(w, "{}", f),
};
}
};
});
}
self.common.write_out_commands(w);
self.z_axis.write_out_commands(w);
let mut grid_axes = vec![];
if self.common.x_axis.grid
{
grid_axes.push(self.common.x_axis.axis);
}
if self.common.y_axis.grid
{
grid_axes.push(self.common.y_axis.axis);
}
if self.common.cb_axis.grid
{
grid_axes.push(self.common.cb_axis.axis);
}
if self.z_axis.grid
{
grid_axes.push(self.z_axis.axis);
}
self.common.write_grid_options(w, &grid_axes);
self.common.write_out_elements("splot", w);
}
}