use super::{vector_to_array, AsVector, GraphMaker};
use std::fmt::Write;
pub struct Curve {
label: String, line_alpha: f64, line_color: String, line_style: String, line_width: f64, marker_color: String, marker_every: usize, marker_void: bool, marker_line_color: String, marker_line_width: f64, marker_size: f64, marker_style: String, buffer: String, }
impl Curve {
pub fn new() -> Self {
Curve {
label: String::new(),
line_alpha: 0.0,
line_color: String::new(),
line_style: String::new(),
line_width: 0.0,
marker_color: String::new(),
marker_every: 0,
marker_void: false,
marker_line_color: String::new(),
marker_line_width: 0.0,
marker_size: 0.0,
marker_style: String::new(),
buffer: String::new(),
}
}
pub fn draw<'a, T, U>(&mut self, x: &'a T, y: &'a T)
where
T: AsVector<'a, U>,
U: 'a + std::fmt::Display,
{
vector_to_array(&mut self.buffer, "x", x);
vector_to_array(&mut self.buffer, "y", y);
let opt = self.options();
write!(&mut self.buffer, "plt.plot(x,y{})\n", &opt).unwrap();
}
pub fn set_label(&mut self, label: &str) -> &mut Self {
self.label = String::from(label);
self
}
pub fn set_line_alpha(&mut self, alpha: f64) -> &mut Self {
self.line_alpha = alpha;
self
}
pub fn set_line_color(&mut self, color: &str) -> &mut Self {
self.line_color = String::from(color);
self
}
pub fn set_line_style(&mut self, style: &str) -> &mut Self {
self.line_style = String::from(style);
self
}
pub fn set_line_width(&mut self, width: f64) -> &mut Self {
self.line_width = width;
self
}
pub fn set_marker_color(&mut self, color: &str) -> &mut Self {
self.marker_color = String::from(color);
self
}
pub fn set_marker_every(&mut self, every: usize) -> &mut Self {
self.marker_every = every;
self
}
pub fn set_marker_void(&mut self, flag: bool) -> &mut Self {
self.marker_void = flag;
self
}
pub fn set_marker_line_color(&mut self, color: &str) -> &mut Self {
self.marker_line_color = String::from(color);
self
}
pub fn set_marker_line_width(&mut self, width: f64) -> &mut Self {
self.marker_line_width = width;
self
}
pub fn set_marker_size(&mut self, size: f64) -> &mut Self {
self.marker_size = size;
self
}
pub fn set_marker_style(&mut self, style: &str) -> &mut Self {
self.marker_style = String::from(style);
self
}
fn options(&self) -> String {
let line_color = if self.marker_void && self.line_color == "" {
"red"
} else {
&self.line_color
};
let mut opt = String::new();
if self.label != "" {
write!(&mut opt, ",label='{}'", self.label).unwrap();
}
if self.line_alpha > 0.0 {
write!(&mut opt, ",alpha={}", self.line_alpha).unwrap();
}
if line_color != "" {
write!(&mut opt, ",color='{}'", line_color).unwrap();
}
if self.line_style != "" {
write!(&mut opt, ",linestyle='{}'", self.line_style).unwrap();
}
if self.line_width > 0.0 {
write!(&mut opt, ",linewidth={}", self.line_width).unwrap();
}
if !self.marker_void && self.marker_color != "" {
write!(&mut opt, ",markerfacecolor='{}'", self.marker_color).unwrap();
}
if self.marker_every > 0 {
write!(&mut opt, ",markevery={}", self.marker_every).unwrap();
}
if self.marker_void {
write!(&mut opt, ",markerfacecolor='none'").unwrap();
}
if self.marker_line_color != "" {
write!(&mut opt, ",markeredgecolor='{}'", self.marker_line_color).unwrap();
}
if self.marker_line_width > 0.0 {
write!(&mut opt, ",markeredgewidth={}", self.marker_line_width).unwrap();
}
if self.marker_size > 0.0 {
write!(&mut opt, ",markersize={}", self.marker_size).unwrap();
}
if self.marker_style != "" {
write!(&mut opt, ",marker='{}'", self.marker_style).unwrap();
}
opt
}
}
impl GraphMaker for Curve {
fn get_buffer<'a>(&'a self) -> &'a String {
&self.buffer
}
}
#[cfg(test)]
mod tests {
use super::Curve;
use russell_lab::Vector;
#[test]
fn new_works() {
let curve = Curve::new();
assert_eq!(curve.label.len(), 0);
assert_eq!(curve.line_alpha, 0.0);
assert_eq!(curve.line_color.len(), 0);
assert_eq!(curve.line_style.len(), 0);
assert_eq!(curve.line_width, 0.0);
assert_eq!(curve.marker_color.len(), 0);
assert_eq!(curve.marker_every, 0);
assert_eq!(curve.marker_void, false);
assert_eq!(curve.marker_line_color.len(), 0);
assert_eq!(curve.marker_line_width, 0.0);
assert_eq!(curve.marker_size, 0.0);
assert_eq!(curve.marker_style.len(), 0);
assert_eq!(curve.buffer.len(), 0);
}
#[test]
fn options_works() {
let mut curve = Curve::new();
curve
.set_label("my-curve")
.set_line_alpha(0.7)
.set_line_color("#b33434")
.set_line_style("-")
.set_line_width(3.0)
.set_marker_color("#4c4deb")
.set_marker_every(2)
.set_marker_void(false)
.set_marker_line_color("blue")
.set_marker_line_width(1.5)
.set_marker_size(8.0)
.set_marker_style("o");
let options = curve.options();
assert_eq!(
options,
",label='my-curve'\
,alpha=0.7\
,color='#b33434'\
,linestyle='-'\
,linewidth=3\
,markerfacecolor='#4c4deb'\
,markevery=2\
,markeredgecolor='blue'\
,markeredgewidth=1.5\
,markersize=8\
,marker='o'"
);
}
#[test]
fn draw_works() {
let x = &[1.0, 2.0, 3.0, 4.0, 5.0];
let y = &[1.0, 4.0, 9.0, 16.0, 25.0];
let mut curve = Curve::new();
curve.set_label("the-curve");
curve.draw(x, y);
let b: &str = "x=np.array([1,2,3,4,5,],dtype=float)\n\
y=np.array([1,4,9,16,25,],dtype=float)\n\
plt.plot(x,y,label='the-curve')\n";
assert_eq!(curve.buffer, b);
}
#[test]
fn draw_with_vector_works() {
let x = Vector::from(&[1.0, 2.0, 3.0, 4.0, 5.0]);
let y = Vector::from(&[1.0, 4.0, 9.0, 16.0, 25.0]);
let mut curve = Curve::new();
curve.set_label("the-curve");
curve.draw(&x, &y);
let b: &str = "x=np.array([1,2,3,4,5,],dtype=float)\n\
y=np.array([1,4,9,16,25,],dtype=float)\n\
plt.plot(x,y,label='the-curve')\n";
assert_eq!(curve.buffer, b);
}
}