use kuva::backend::svg::SvgBackend;
use kuva::plot::{BarPlot, Heatmap, LinePlot, ScatterPlot};
use kuva::render::layout::Layout;
use kuva::render::plots::Plot;
use kuva::render::render::render_multiple;
const OUT: &str = "docs/src/assets/bw_mode";
fn main() {
std::fs::create_dir_all(OUT).expect("could not create docs/src/assets/bw_mode");
comparison();
patterns();
lines();
markers();
colormap();
println!("BW mode SVGs written to {OUT}/");
}
fn grouped_bar() -> BarPlot {
BarPlot::new()
.with_group(
"Q1",
vec![(18.0, "steelblue"), (12.0, "crimson"), (9.0, "seagreen")],
)
.with_group(
"Q2",
vec![(22.0, "steelblue"), (17.0, "crimson"), (14.0, "seagreen")],
)
.with_group(
"Q3",
vec![(19.0, "steelblue"), (21.0, "crimson"), (11.0, "seagreen")],
)
.with_group(
"Q4",
vec![(25.0, "steelblue"), (15.0, "crimson"), (18.0, "seagreen")],
)
.with_legend(vec!["Product A", "Product B", "Product C"])
.with_stacked()
}
fn comparison() {
let plots = vec![Plot::Bar(grouped_bar())];
let layout = Layout::auto_from_plots(&plots)
.with_title("Color mode")
.with_y_label("Sales (units)");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/comparison_color.svg"), svg).unwrap();
let plots = vec![Plot::Bar(grouped_bar())];
let layout = Layout::auto_from_plots(&plots)
.with_bw_mode()
.with_title("BW mode")
.with_y_label("Sales (units)");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/comparison_bw.svg"), svg).unwrap();
}
fn patterns() {
let plot = BarPlot::new()
.with_group(
"North",
vec![
(14.0, "steelblue"),
(9.0, "crimson"),
(11.0, "seagreen"),
(7.0, "goldenrod"),
(5.0, "purple"),
],
)
.with_group(
"South",
vec![
(18.0, "steelblue"),
(12.0, "crimson"),
(8.0, "seagreen"),
(10.0, "goldenrod"),
(6.0, "purple"),
],
)
.with_group(
"East",
vec![
(11.0, "steelblue"),
(15.0, "crimson"),
(13.0, "seagreen"),
(9.0, "goldenrod"),
(8.0, "purple"),
],
)
.with_legend(vec![
"Widgets",
"Gadgets",
"Gizmos",
"Doohickeys",
"Thingamajigs",
])
.with_stacked();
let plots = vec![Plot::Bar(plot)];
let layout = Layout::auto_from_plots(&plots)
.with_bw_mode()
.with_title("Discrete series — pattern + grey cycling")
.with_y_label("Units");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/patterns.svg"), svg).unwrap();
}
fn lines() {
let series: Vec<(&str, Vec<(f64, f64)>)> = vec![
(
"Control",
vec![(0.0, 2.0), (1.0, 2.4), (2.0, 2.1), (3.0, 2.8), (4.0, 3.0)],
),
(
"Low dose",
vec![(0.0, 2.0), (1.0, 3.1), (2.0, 3.6), (3.0, 4.0), (4.0, 4.5)],
),
(
"Medium dose",
vec![(0.0, 2.0), (1.0, 3.8), (2.0, 4.9), (3.0, 5.8), (4.0, 6.5)],
),
(
"High dose",
vec![(0.0, 2.0), (1.0, 4.5), (2.0, 6.2), (3.0, 7.6), (4.0, 8.7)],
),
];
let plots: Vec<Plot> = series
.into_iter()
.map(|(name, data)| {
Plot::Line(
LinePlot::new()
.with_data(data)
.with_color("steelblue")
.with_legend(name),
)
})
.collect();
let layout = Layout::auto_from_plots(&plots)
.with_bw_mode()
.with_title("Lines — dash-style cycling")
.with_x_label("Time (days)")
.with_y_label("Response");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/lines.svg"), svg).unwrap();
}
fn markers() {
let groups: Vec<(&str, Vec<(f64, f64)>)> = vec![
("A", vec![(1.0, 2.0), (1.4, 2.6), (1.8, 2.2), (2.1, 2.9)]),
("B", vec![(2.0, 4.5), (2.4, 5.0), (2.8, 4.7), (3.1, 5.3)]),
("C", vec![(3.0, 1.5), (3.4, 1.9), (3.8, 1.6), (4.1, 2.1)]),
("D", vec![(4.0, 6.0), (4.4, 6.4), (4.8, 6.1), (5.1, 6.7)]),
("E", vec![(5.0, 3.5), (5.4, 3.9), (5.8, 3.6), (6.1, 4.1)]),
];
let plots: Vec<Plot> = groups
.into_iter()
.map(|(name, data)| {
Plot::Scatter(
ScatterPlot::new()
.with_data(data)
.with_color("crimson")
.with_size(6.0)
.with_legend(name),
)
})
.collect();
let layout = Layout::auto_from_plots(&plots)
.with_bw_mode()
.with_title("Scatter — marker-shape cycling")
.with_x_label("X")
.with_y_label("Y");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/markers.svg"), svg).unwrap();
}
fn colormap() {
let data = vec![
vec![0.8, 0.3, 0.9, 0.2, 0.6],
vec![0.4, 0.7, 0.1, 0.8, 0.3],
vec![0.5, 0.9, 0.4, 0.6, 0.1],
vec![0.2, 0.5, 0.8, 0.3, 0.7],
];
let heatmap = Heatmap::new().with_data(data);
let plots = vec![Plot::Heatmap(heatmap)];
let layout = Layout::auto_from_plots(&plots)
.with_bw_mode()
.with_title("Continuous colormap — forced to grayscale");
let svg = SvgBackend.render_scene(&render_multiple(plots, layout));
std::fs::write(format!("{OUT}/colormap.svg"), svg).unwrap();
}