use super::{generate_list_quoted, vector_to_array, AsVector, GraphMaker};
use num_traits::Num;
use std::fmt::Write;
pub struct Barplot {
label: String, colors: Vec<String>, width: f64, bottom: Vec<f64>, with_text: Option<String>, horizontal: bool, errors: Vec<f64>, extra: String, buffer: String, }
impl Barplot {
pub fn new() -> Self {
Barplot {
label: String::new(),
colors: Vec::new(),
width: 0.0,
bottom: Vec::new(),
with_text: None,
horizontal: false,
errors: Vec::new(),
extra: 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 + Num,
{
vector_to_array(&mut self.buffer, "x", x);
vector_to_array(&mut self.buffer, "y", y);
let opt = self.options();
if self.colors.len() > 0 {
generate_list_quoted(&mut self.buffer, "colors", self.colors.as_slice());
}
if self.bottom.len() > 0 {
vector_to_array(&mut self.buffer, "bottom", &self.bottom);
}
if self.errors.len() > 0 {
vector_to_array(&mut self.buffer, "err", &self.errors);
}
if self.horizontal {
write!(&mut self.buffer, "p=plt.barh(x,y{})\n", &opt).unwrap();
} else {
write!(&mut self.buffer, "p=plt.bar(x,y{})\n", &opt).unwrap();
}
if let Some(t) = &self.with_text {
write!(&mut self.buffer, "plt.gca().bar_label(p,label_type='{}')\n", t).unwrap();
}
}
pub fn draw_with_str<'a, T, U>(&mut self, x: &[&str], y: &'a T)
where
T: AsVector<'a, U>,
U: 'a + std::fmt::Display + Num,
{
generate_list_quoted(&mut self.buffer, "x", x);
vector_to_array(&mut self.buffer, "y", y);
let opt = self.options();
if self.colors.len() > 0 {
generate_list_quoted(&mut self.buffer, "colors", self.colors.as_slice());
}
if self.bottom.len() > 0 {
vector_to_array(&mut self.buffer, "bottom", &self.bottom);
}
if self.errors.len() > 0 {
vector_to_array(&mut self.buffer, "err", &self.errors);
}
if self.horizontal {
write!(&mut self.buffer, "p=plt.barh(x,y{})\n", &opt).unwrap();
} else {
write!(&mut self.buffer, "p=plt.bar(x,y{})\n", &opt).unwrap();
}
if let Some(t) = &self.with_text {
write!(&mut self.buffer, "plt.gca().bar_label(p,label_type='{}')\n", t).unwrap();
}
}
pub fn set_label(&mut self, label: &str) -> &mut Self {
self.label = String::from(label);
self
}
pub fn set_colors(&mut self, colors: &[&str]) -> &mut Self {
self.colors = colors.iter().map(|color| color.to_string()).collect();
self
}
pub fn set_width(&mut self, width: f64) -> &mut Self {
self.width = width;
self
}
pub fn set_bottom(&mut self, bottom: &[f64]) -> &mut Self {
self.bottom = Vec::from(bottom);
self
}
pub fn set_with_text(&mut self, position: &str) -> &mut Self {
if position == "" {
self.with_text = None
} else {
self.with_text = Some(position.to_string());
}
self
}
pub fn set_horizontal(&mut self, flag: bool) -> &mut Self {
self.horizontal = flag;
self
}
pub fn set_errors(&mut self, errors: &[f64]) -> &mut Self {
self.errors = errors.to_vec();
self
}
pub fn set_extra(&mut self, extra: &str) -> &mut Self {
self.extra = extra.to_string();
self
}
fn options(&self) -> String {
let mut opt = String::new();
if self.label != "" {
write!(&mut opt, ",label=r'{}'", self.label).unwrap();
}
if self.colors.len() > 0 {
write!(&mut opt, ",color=colors").unwrap();
}
if self.width > 0.0 {
write!(&mut opt, ",width={}", self.width).unwrap();
}
if self.bottom.len() > 0 {
write!(&mut opt, ",bottom=bottom").unwrap();
}
if self.errors.len() > 0 {
if self.horizontal {
write!(&mut opt, ",xerr=err").unwrap();
} else {
write!(&mut opt, ",yerr=err").unwrap();
}
}
if self.extra != "" {
write!(&mut opt, ",{}", self.extra).unwrap();
}
opt
}
}
impl GraphMaker for Barplot {
fn get_buffer<'a>(&'a self) -> &'a String {
&self.buffer
}
fn clear_buffer(&mut self) {
self.buffer.clear();
}
}
#[cfg(test)]
mod tests {
use super::Barplot;
use crate::GraphMaker;
#[test]
fn new_works() {
let barplot = Barplot::new();
assert_eq!(barplot.label.len(), 0);
assert_eq!(barplot.colors.len(), 0);
assert_eq!(barplot.width, 0.0);
assert_eq!(barplot.bottom.len(), 0);
assert_eq!(barplot.with_text, None);
assert_eq!(barplot.buffer.len(), 0);
}
#[test]
fn draw_works_1() {
let xx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let yy = [5, 4, 3, 2, 1, 0, 1, 2, 3, 4];
let mut bar = Barplot::new();
bar.draw(&xx, &yy);
let b: &str = "x=np.array([0,1,2,3,4,5,6,7,8,9,])\n\
y=np.array([5,4,3,2,1,0,1,2,3,4,])\n\
p=plt.bar(x,y)\n";
assert_eq!(bar.buffer, b);
bar.clear_buffer();
assert_eq!(bar.buffer, "");
}
#[test]
fn draw_works_2() {
let xx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let yy = [5, 4, 3, 2, 1, 0, 1, 2, 3, 4];
let mut bar = Barplot::new();
bar.set_label("LABEL")
.set_colors(&vec!["red", "green"])
.set_width(10.0)
.set_bottom(&[1.0, 2.0, 3.0])
.set_with_text("center")
.set_extra("edgecolor='black'")
.draw(&xx, &yy);
let b: &str = "x=np.array([0,1,2,3,4,5,6,7,8,9,])\n\
y=np.array([5,4,3,2,1,0,1,2,3,4,])\n\
colors=['red','green',]\n\
bottom=np.array([1,2,3,])\n\
p=plt.bar(x,y\
,label=r'LABEL'\
,color=colors\
,width=10\
,bottom=bottom\
,edgecolor='black')\n\
plt.gca().bar_label(p,label_type='center')\n";
assert_eq!(bar.buffer, b);
bar.clear_buffer();
bar.set_with_text("");
assert_eq!(bar.buffer, "");
}
#[test]
fn draw_with_str_works_1() {
let xx = ["one", "two", "three"];
let yy = [1, 2, 3];
let mut bar = Barplot::new();
bar.draw_with_str(&xx, &yy);
let b: &str = "x=['one','two','three',]\n\
y=np.array([1,2,3,])\n\
p=plt.bar(x,y)\n";
assert_eq!(bar.buffer, b);
}
#[test]
fn draw_with_str_works_2() {
let xx = ["one", "two", "three"];
let yy = [1, 2, 3];
let mut bar = Barplot::new();
bar.set_label("LABEL")
.set_colors(&vec!["red", "green"])
.set_width(10.0)
.set_bottom(&[1.0, 2.0, 3.0])
.set_with_text("center")
.set_extra("edgecolor='black'")
.draw_with_str(&xx, &yy);
let b: &str = "x=['one','two','three',]\n\
y=np.array([1,2,3,])\n\
colors=['red','green',]\n\
bottom=np.array([1,2,3,])\n\
p=plt.bar(x,y\
,label=r'LABEL'\
,color=colors\
,width=10\
,bottom=bottom\
,edgecolor='black')\n\
plt.gca().bar_label(p,label_type='center')\n";
assert_eq!(bar.buffer, b);
}
}