use hephaestus::color::{rgb8, Color};
use hephaestus::composition::{beside, Patch};
use hephaestus::document::{unsupported_items, write_composition, WriteOptions};
use hephaestus::plot::chrome::axis::{Axis, AxisPlacement};
use hephaestus::plot::theme::Theme;
use hephaestus::plot::{scale, LineGeom, Plot, PlotComposition, PointGeom};
use hephaestus::scales::chrome::AxisSide;
use hephaestus::scales::value::Value;
fn main() {
let comp = || beside(Patch::new("scatter"), Patch::new("trend"));
let bands = ["low", "mid", "high"];
let mut xs: Vec<f64> = Vec::new();
let mut ys: Vec<f64> = Vec::new();
let mut groups: Vec<&str> = Vec::new();
for (k, band) in bands.iter().enumerate() {
for i in 0..60 {
let x = f64::from(i) * 0.53;
xs.push(x);
ys.push(45.0 + (8.0 + 4.0 * k as f64) * (x * 0.25 + k as f64 * 0.9).sin() + 0.5 * x);
groups.push(band);
}
}
let mut scatter = Plot::new(&comp(), "scatter")
.bind("x", "t")
.bind("y", "value")
.bind("fill", "band")
.title("Observations")
.caption("one mark per reading");
scatter.add_geom(
PointGeom::builder()
.set("x", xs.clone())
.set("y", ys.clone())
.set("fill", groups.clone())
.set("size", 5.0_f64)
.build(),
);
scatter.add_axis(Axis::rail("t", AxisPlacement::Cartesian(AxisSide::Bottom)).title("hours"));
scatter
.add_axis(Axis::rail("value", AxisPlacement::Cartesian(AxisSide::Left)).title("reading"));
let mut trend = Plot::new(&comp(), "trend")
.bind("x", "t")
.bind("y", "value")
.title("Trend")
.caption("laid out per size by document_load");
trend.add_geom(
LineGeom::builder()
.keys(groups)
.set("x", xs)
.set("y", ys)
.set("stroke", rgb8(70, 90, 160))
.set("linewidth", 1.75_f64)
.set("linetype", Value::Linetype(hephaestus::linetype::dashed()))
.build(),
);
trend.add_axis(Axis::rail("t", AxisPlacement::Cartesian(AxisSide::Bottom)).title("hours"));
let view = PlotComposition::new(&comp())
.theme(Theme::minimal())
.with_plot(scatter)
.with_plot(trend)
.add_scale("t", scale::continuous(0.0..=32.0))
.add_scale("value", scale::continuous(30.0..=80.0))
.add_scale(
"band",
scale::discrete(["low", "mid", "high"].map(Value::from)).range_colors(vec![
rgb8(80, 130, 210),
rgb8(90, 175, 120),
rgb8(215, 95, 85),
]),
);
for issue in view.validate() {
eprintln!("validate: {issue:?}");
}
let problems = unsupported_items(&view);
if !problems.is_empty() {
for p in &problems {
eprintln!("warning: {p}");
}
}
let opts = WriteOptions::new()
.background(Color::WHITE)
.size_hint(900.0, 420.0)
.dpi_hint(96.0);
let bytes = write_composition(&view, &opts).expect("this plot is writable");
let path = "examples/document.hplot";
std::fs::write(path, &bytes).expect("write the document");
println!("wrote {path} ({} bytes)", bytes.len());
println!("now run: cargo run --example document_load --features document-read,png");
}