use std::io::Write;
use xml::writer::{EventWriter, XmlEvent};
use crate::chart::tag_percent::TagPercent;
use crate::chart::ColorIter;
#[cfg(doc)]
use crate::chart::PieChart;
use crate::emit_xml;
use crate::Result;
pub struct Legend<'a> {
font_size: f32,
colors: ColorIter<'a>
}
impl<'a> Legend<'a> {
pub fn new(font_size: f32, colors: ColorIter<'a>) -> Self { Self { font_size, colors } }
pub fn font_size(&self) -> f32 { self.font_size }
fn color<W: Write>(&self, w: &mut EventWriter<W>, clr: &str) -> Result<()> {
let size = format!("{}", self.font_size());
emit_xml!(w, svg, height: &size, width: &size => {
emit_xml!(w, rect, height: &size, width: &size, fill: clr)
})
}
fn write_line<W: Write>(&self, w: &mut EventWriter<W>, clr: &str, label: &str) -> Result<()> {
emit_xml!(w, tr => {
emit_xml!(w, td => {
self.color(w, clr)?;
emit_xml!(w, span; label)
})
})
}
pub fn write<'b, W, Iter>(&self, w: &mut EventWriter<W>, percents: Iter) -> Result<()>
where
Iter: Iterator<Item = &'b TagPercent>,
W: Write
{
emit_xml!(w, table, class: "legend", style: &format!("font-size: {}px", self.font_size()) => {
for (p, clr) in percents.zip(self.colors.clone()) {
self.write_line(w, clr, &p.display_label())?;
}
Ok(())
})
}
}
#[cfg(test)]
mod tests {
use spectral::prelude::*;
use xml::writer::EmitterConfig;
use super::*;
#[test]
fn test_new() {
let legend = Legend::new(12.0, ColorIter::default());
assert_that!(legend.font_size()).is_equal_to(&12.0);
}
#[test]
fn test_fmt_line() {
let colors = ["blue", "green"];
let legend = Legend::new(14.0, ColorIter::new(&colors));
let tags = [
TagPercent::new("Foo", 30.0).unwrap(),
TagPercent::new("Bar", 70.0).unwrap()
];
let mut actual: Vec<u8> = Vec::new();
let mut w = EmitterConfig::new()
.perform_indent(true)
.write_document_declaration(false)
.create_writer(&mut actual);
let expected = r#"<table class="legend" style="font-size: 14px">
<tr>
<td>
<svg height="14" width="14">
<rect height="14" width="14" fill="blue" />
</svg>
<span>30% - Foo</span>
</td>
</tr>
<tr>
<td>
<svg height="14" width="14">
<rect height="14" width="14" fill="green" />
</svg>
<span>70% - Bar</span>
</td>
</tr>
</table>"#;
assert_that!(legend.write(&mut w, tags.iter())).is_ok();
assert_that!(String::from_utf8(actual).unwrap()).is_equal_to(expected.to_string())
}
}