use crate::transaction::Transaction;
pub fn build(transaction: &[Transaction]) {
let width = 50 * transaction.len() as isize;
let height = 600;
let (top, right, bottom, left) = (90, 40, 50, 60);
let smallest_amount = transaction.iter().fold(0.0, |state, op| {
if op.amount() < state {
op.amount()
} else {
state
}
});
let biggest_amount = transaction.iter().fold(0.0, |state, op| {
if op.amount() > state {
op.amount()
} else {
state
}
});
let mut data = Vec::<(String, f32)>::default();
for op in transaction {
match data.last_mut() {
Some((date, amount)) if *date == op.date().to_string() => {
*amount += op.amount() as f32;
}
_ => {
data.push((op.date().to_string(), op.amount() as f32));
}
}
}
let x = charts::ScaleBand::new()
.set_domain(data.iter().map(|(date, _)| date.clone()).collect())
.set_range(vec![0, width - left - right]);
let y = charts::ScaleLinear::new()
.set_domain(vec![smallest_amount as f32, biggest_amount as f32])
.set_range(vec![height - top - bottom, 0]);
let line_view = charts::LineSeriesView::new()
.set_x_scale(&x)
.set_y_scale(&y)
.set_marker_type(charts::MarkerType::Circle)
.set_label_position(charts::PointLabelPosition::N)
.load_data(&data.iter().map(|(x, y)| (x.clone(), *y)).collect())
.unwrap();
charts::Chart::new()
.set_width(width)
.set_height(height)
.set_margins(top, right, bottom, left)
.add_title(String::from("Expenses"))
.add_view(&line_view)
.add_axis_bottom(&x)
.add_axis_left(&y)
.add_left_axis_label("amount")
.add_bottom_axis_label("Date")
.save("line-chart.svg")
.unwrap();
}