use super::{generate_list, GraphMaker};
use std::fmt::Write;
pub struct Legend {
fontsize: f64, handle_len: f64, num_col: usize, location: String, outside: bool, show_frame: bool, x_coords: Vec<f64>, extra: String, buffer: String, }
impl Legend {
pub fn new() -> Self {
Legend {
fontsize: 0.0,
handle_len: 3.0,
num_col: 1,
location: "best".to_string(),
outside: false,
show_frame: true,
x_coords: vec![0.0, 1.02, 1.0, 0.102],
extra: String::new(),
buffer: String::new(),
}
}
pub fn draw(&mut self) {
let opt = self.options();
if self.outside {
generate_list(&mut self.buffer, "coo", self.x_coords.as_slice());
}
write!(&mut self.buffer, "h,l=plt.gca().get_legend_handles_labels()\n").unwrap();
write!(&mut self.buffer, "if len(h)>0 and len(l)>0:\n").unwrap();
write!(&mut self.buffer, " leg=plt.legend({})\n", &opt).unwrap();
write!(&mut self.buffer, " add_to_ea(leg)\n").unwrap();
if !self.show_frame {
write!(&mut self.buffer, " leg.get_frame().set_linewidth(0.0)\n").unwrap();
}
}
pub fn set_fontsize(&mut self, fontsize: f64) -> &mut Self {
self.fontsize = fontsize;
self
}
pub fn set_handle_len(&mut self, length: f64) -> &mut Self {
self.handle_len = length;
self
}
pub fn set_num_col(&mut self, num_columns: usize) -> &mut Self {
self.num_col = num_columns;
self
}
pub fn set_location(&mut self, location: &str) -> &mut Self {
self.location = String::from(location);
self
}
pub fn set_outside(&mut self, flag: bool) -> &mut Self {
self.outside = flag;
self
}
pub fn set_show_frame(&mut self, flag: bool) -> &mut Self {
self.show_frame = flag;
self
}
pub fn set_x_coords(&mut self, coords: &[f64]) -> &mut Self {
self.x_coords = coords.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();
let mut comma = "";
if self.handle_len > 0.0 {
write!(&mut opt, "handlelength={}", self.handle_len).unwrap();
comma = ",";
}
if self.fontsize > 0.0 {
write!(&mut opt, "{}prop={{'size':{}}}", comma, self.fontsize).unwrap();
comma = ",";
}
if self.num_col > 0 {
write!(&mut opt, "{}ncol={}", comma, self.num_col).unwrap();
comma = ",";
}
if self.outside {
write!(
&mut opt,
"{}loc=3,bbox_to_anchor=coo,mode='expand',borderaxespad=0.0,columnspacing=1,handletextpad=0.05",
comma
)
.unwrap();
} else {
if self.location != "" {
write!(&mut opt, "{}loc='{}'", comma, self.location).unwrap();
}
}
if self.extra != "" {
write!(&mut opt, ",{}", self.extra).unwrap();
}
opt
}
}
impl GraphMaker for Legend {
fn get_buffer<'a>(&'a self) -> &'a String {
&self.buffer
}
fn clear_buffer(&mut self) {
self.buffer.clear();
}
}
#[cfg(test)]
mod tests {
use super::Legend;
use crate::GraphMaker;
#[test]
fn new_works() {
let legend = Legend::new();
assert_eq!(legend.fontsize, 0.0);
assert_eq!(legend.handle_len, 3.0);
assert_eq!(legend.num_col, 1);
assert_eq!(legend.location, "best".to_string());
assert_eq!(legend.outside, false);
assert_eq!(legend.show_frame, true);
assert_eq!(legend.x_coords, vec![0.0, 1.02, 1.0, 0.102]);
assert_eq!(legend.buffer.len(), 0);
}
#[test]
fn options_works() {
let mut legend = Legend::new();
legend.set_handle_len(6.0);
let opt = legend.options();
assert_eq!(opt, "handlelength=6,ncol=1,loc='best'");
}
#[test]
fn draw_works() {
let mut legend = Legend::new();
legend.draw();
let b: &str = "h,l=plt.gca().get_legend_handles_labels()\n\
if len(h)>0 and len(l)>0:\n\
\x20\x20\x20\x20leg=plt.legend(handlelength=3,ncol=1,loc='best')\n\
\x20\x20\x20\x20add_to_ea(leg)\n";
assert_eq!(legend.buffer, b);
legend.clear_buffer();
assert_eq!(legend.buffer, "");
}
}