use charming::{ Chart, WasmRenderer, component::{Axis, Grid}, element::AxisType, series::Line, theme::Theme }; use sycamore::prelude::*; use crate::AppState; // a realization status indicator #[component] pub fn RealizationStatus() -> View { let state = use_context::(); let realization_status = state.assembly.realization_status; view! { div( id="realization-status", class=realization_status.with( |status| match status { Ok(_) => "", Err(_) => "invalid" } ) ) { div(class="status") div { (realization_status.with( |status| match status { Ok(_) => "Target accuracy achieved".to_string(), Err(message) => message.clone() } )) } } } } // a plot of the loss history from the last realization #[component] pub fn LossHistory() -> View { const CONTAINER_ID: &str = "loss-history"; let state = use_context::(); let renderer = WasmRenderer::new_opt(None, Some(180)).theme(Theme::Walden); on_mount(move || { create_effect(move || { // get the loss history let scaled_loss = state.assembly.descent_history.with( |history| history.scaled_loss.clone() ); let step_cnt = scaled_loss.len(); // initialize the chart axes and series const MIN_INTERVAL: f64 = 0.01; let mut step_axis = Axis::new() .type_(AxisType::Category) .boundary_gap(false); let scaled_loss_axis = Axis::new() .type_(AxisType::Value) .min(0) .min_interval(MIN_INTERVAL); // load the chart data. when there's no history, we load the data // point (0, None) to clear the chart. it would feel more natural to // load empty data vectors, but that turns out not to clear the // chart: it instead leads to previous data being re-used let mut scaled_loss_series = Line::new(); if step_cnt > 0 { step_axis = step_axis.data( (0..step_cnt).map(|step| step.to_string()).collect() ); scaled_loss_series = scaled_loss_series.data(scaled_loss); } else { step_axis = step_axis.data(vec![0.to_string()]); scaled_loss_series = scaled_loss_series.data(vec![None::]); } let chart = Chart::new() .animation(false) .x_axis(step_axis) .y_axis(scaled_loss_axis) .grid(Grid::new().top(20).right(40).bottom(30).left(60)) .series(scaled_loss_series); renderer.render(CONTAINER_ID, &chart).unwrap(); }); }); view! { div(id=CONTAINER_ID) } } #[component] pub fn Diagnostics() -> View { view! { div(id="diagnostics") { RealizationStatus {} LossHistory {} } } }