Built for Enlumi, whose name comes from Esperanto, meaning to enlighten.
zgui-plot provides backend-neutral 2D plotting primitives, retained Zgui chart components, SVG/PNG export, and optional docking workspace controls.
The crate lives in the Quick-Flash/zgui-plot repository. Zgui temporarily pins a public commit from Quick-Flash/zgui, branch text-multiclick-selection, pending upstream merge. Consumers must use the same Zgui revision recorded in Cargo.toml. Zgui currently documents Git installation and is not published on crates.io, so this dependency blocks publishing zgui-plot to crates.io.
While developing in a workspace, use this path from workspace root:
zgui-plot = { path = "../zgui-plot", features = ["workspace", "raster"] }For consumers outside this workspace, use the public Git source:
zgui-plot = { git = "https://github.com/Quick-Flash/zgui-plot", features = ["workspace", "raster"] }The zgui-plot package imports as zgui_plot. Use default-features = false to keep Zgui, docking controls, and raster export out of backend-neutral applications.
With workspace, zgui_series::SeriesPlot adds compact editable legends,
per-plot legend collapse/expand (heading and line settings stay accessible),
Ctrl/Shift multi-selection, fixed-layout appearance settings, disabled color
controls for multiple selections, hidden-line hover previews, legend reorder,
cross-pane drag feedback, and snapped linked pointers/readouts.
SeriesPane::new(id, lines) owns durable presentation over
Signal<Vec<SeriesLine>>; line IDs are stable numeric IDs, while source metadata
stays in consumer. LegendHost supplies visible panes, hit testing, and acceptance
callbacks. SeriesActions supplies select/remove/move callbacks and optional extra
action label/help/callback; Enlumi uses this hook for Add filters. Keep this
state under a durable owner, outside transient dialogs. The controls install their
own stylesheet; applications still install surface/time-series sheets and a
zgui-ui ThemeProvider.
PlotTabs accepts optional on_rename: UnsyncCallback<(u64, String)>. When
provided, double-clicking a tab title or pressing F2 edits it in place. Enter or
focus loss commits; Escape cancels. Empty title lets consumer restore default.
TimeSeriesPlot::line_drawing maps ordinary string series IDs to
line_draw::LineDraw { connection, markers }. Connection supports Linear,
Pre, and Post. Standard time plots now use bounded background preparation,
including column reduction before step expansion/markers, one worker per plot,
compatible completion publishing during continuous pans, and a viewport of cached
data on either side. Full samples remain available for hover and filtering.
Snapshots use the same prepared canvas, preserving interpolation and markers.
show_legend, show_pointer, and show_cursor_values provide explicit composition
controls; consumers no longer need CSS selectors against internal child order.
Backend-neutral helpers are line_draw::prepare, series_samples::{viewport, pan_viewport, Accuracy}, and palette::{DEFAULT_PALETTE, next_color}. Palette
allocation takes destination and global colors, so each application chooses its
reuse scope. SeriesPane::copy_appearance preserves styles/visibility and resolves
destination color clashes before membership transfer; consumer performs transfer
and source cleanup explicitly.
Workspace helpers include WorkspaceGeometry::fitted for viewport-sized docks,
Layout::equalize for balanced rows/columns, and PlotLinksMenu with independent
checkboxes plus All. Group docking and pane-local guides remain available.
Line settings support solid, dashed, dotted, dash-dot, and markers-only rendering. Patterns and sample markers can be edited for multiple selected lines; choosing line type None enables markers. Pattern preparation runs on background workers with bounded geometry and exports through the same retained scene.
| Feature | Provides |
|---|---|
| Default / none | Geometry, ranges, interaction controller, histogram, docking tree and assignment model |
zgui |
Retained series renderer, interactive surfaces, legends, linked bounds/pointer, SVG snapshots |
raster |
PNG rendering from SVG |
workspace |
zgui plus zgui-ui docking tabs, pane host, splitters, settings and signal drag/drop |
For native UI consumers, disable default features and enable workspace and optional raster on the dependency entry. Use the public Git source above for external consumers. Zgui must resolve to same revision as zgui-plot.
Use same Zgui revision as this crate. Install zgui_workspace::stylesheet() and zgui_surface::stylesheet() alongside application styles, inside a zgui-ui theme.
Application owns data and pane records. Library owns docking geometry and interaction:
- Create
RwSignal<workspace::layout::Layout>and optional maximized pane ID. - Create
zgui_workspace::DockPane::new(id)for each stable, unique pane ID. Create pane signals under durable workspace owner, not temporary menu/tab owners. - Expose pane records through
Signal<Vec<DockPane>>; constructDockState::new(layout, panes)andWorkspaceGeometry::new(layout, maximized). - Render
WorkspaceCanvas, keyedWorkspacePanechildren, andPlotTabsinside each pane'splot-stripheader.WorkspaceCanvassupplies splitters;WorkspacePanesupplies selection, placement, visibility, and docking overlays. - Supply reactive tab titles and add/select/close callbacks. Callbacks update application records and shared layout; renderer/data stay independent of docking.
Layout supports splits, close, swap, tab activation, tab grouping/reordering, edge docking, and resize. Divider IDs remain unique when moving plots across surviving splits. Hidden tabs retain caller-owned configuration; only active tabs appear.
PlotMenu renders kind, duplicate, split, reorder, maximize/restore, and axis swap controls. PlotCommands supplies application factories and selection hooks; pane data remains caller-owned.
SeriesSource accepts reactive ID, label, count, selected state, shared SeriesDrag, and callbacks. Pointer capture, drag threshold, Escape/cancel, and release live in library. Application resolves drop target and applies assignment. workspace::drop_axis and PlotConfig::assign preserve existing single-axis assignment behavior. Future ULog tool can use its own multiple-series configuration with same drag source.
PlotSettings registers children in caller-provided local settings host (RwSignal<Option<Rc<ChildrenFn>>, LocalStorage>). PlotSettingsButton renders registered settings plus caller-supplied controls. LinkControls edits independent X/Y/pointer options; provide zgui_link::PlotLinks as local context around PlotSurface to bind links.
time_series::SeriesData prepares sorted f64 samples once. X must be finite and nondecreasing; nonfinite Y breaks line. Origin-relative f32 renderer buffers preserve small timestamp differences around large epoch values. Original f64 samples remain available for hover and consumer record lookup.
Build TimeSeries with stable ID, display label, and prepared data; collect into TimeSeriesSet::new. Duplicate/empty IDs return errors before keyed UI rows mount. Repeated labels are allowed. Each series may have its own sample rate and gaps; no resampling required.
Render zgui_time_series::TimeSeriesPlot with Signal<TimeSeriesSet> and caller-owned TimeSeriesState. Install zgui_time_series::stylesheet() plus surface stylesheet. Component supplies multiple retained lines, stable ID colors, legend toggles, outlined inside-axis numbers, nearest-sample hover, pan/zoom/box zoom, reset, optional axis formatting, linked interactions, and optional snapshot registry. All visible lines share one Y axis; use matching units.
TimeSeriesState defaults to per-column LOD and auto fit. Pan/zoom/manual bounds suspend auto fit; fit_to resumes it. set_view validates bounds. duplicate copies view options into independent signals. Pan/zoom updates canvas transform without rebuilding prepared vertices. Consumer can switch state.lod to Lod::Exact.
zgui_workspace::TimeSeriesSettings supplies auto-fit, LOD, fit, and numeric bounds controls. state.hover reports series ID, original sample index, and f64 coordinates; this is hover information, not linked record selection.
Standalone two-panel consumer demo, including different sample rates, gaps, repeated labels, epoch timestamps, shared X/pointer, and independent Y:
cargo run --release -p zgui-plot --example time_series --features workspacezgui_plot::ScatterPlot and HistogramPlot share DataPlot with time plots. PlotState owns ranges, visibility, LOD, hover, emphasis, styles, annotations, and histogram options. TimeSeriesState remains compatibility alias. All kinds share pan/zoom/reset, linked interactions, tick formatting, and snapshot registration.
Prepare ScatterSeries from arbitrary-order XY samples, then validate IDs with ScatterSet::new. Buffers retain origin-relative coordinates; prepared X index narrows hover searches while preserving original sample indices. Invalid XY samples are omitted from rendering/hover. Prepare HistogramSeries from numeric values, then build HistogramSet. Nonfinite values are filtered; sorting and moments happen during preparation. Visible groups use common bins and stacked bars. CDF/CCDF use per-column binary searches over prepared groups; normal fit uses cached moments.
SeriesStyle controls RGBA color, width, marker shape, and radius. PlotState.styles maps stable IDs to overrides; missing IDs use default palette. SeriesControls supplies visibility and style widgets, with live legend colors and hover emphasis. DataPlotSettings combines shared numeric bounds, annotations toggle, series controls, and histogram bin/CDF/CCDF/normal-fit settings.
PlotAnnotation supplies X/Y thresholds, bands, rectangular regions, and fit lines. Consumer supplies values, labels, colors, widths, and dash choice. Paths and painting live in zgui_plot::annotations; screen and SVG use same layers. Annotation eligibility and meaning belong to consumer.
zgui_plot::theme owns shared tick/legend CSS and export descriptions. view_state::ViewState<T> supplies persistent per-kind viewport/settings/source identity for custom adapters. Consumers can combine these APIs with shared scatter submission and histogram backdrop layers while keeping domain-specific grouping, dates, thresholds, diagnostics, and specialized UI in application code.
Standalone consumer demo:
cargo run --release -p zgui-plot --example data_plots --features workspace,rasterSettings expose shared controls. Export button writes plot-exports/data-plots.svg and, with raster, PNG. PNG/file work runs on blocking worker.
Register each rendered plot's snapshot with zgui_svg::register_snapshot. Registry cleanup respects replacement callbacks. Pass pane IDs, fallback node bounds, and snapshot sources as WorkspaceSnapshot entries to capture_workspace with layout, maximized ID, and background color.
Capture uses measured positions, active tabs only, and current ranges. Empty panes receive placeholders. Maximized capture includes maximized pane only. SVG composition isolates gradient IDs; raster renders resulting SVG to PNG. Application chooses paths and background work policy.
- ULog ingestion, topic/instance/field discovery, timestamp conversion, and signal metadata belong in consumer.
- Domain-specific filters, dates, groups, thresholds, and correlation actions remain in the consuming application.
- Generic time/scatter/histogram plots, state, styling, annotations, settings, and exports live in this library. Consumers retain application-specific data and UI decisions.
- Linked record selection remains TODO. Current links share bounds and data coordinates, not sample/flight identity.
- Workspace serialization/persistence remains TODO.
Existing renderer demo:
cargo run --release -p zgui-plot --example waves --features zguiLicensed under either MIT or BSD 3-Clause, at your option. See LICENSE-MIT and LICENSE-BSD-3-Clause.
Time, scatter, and histogram plots share full-height Y grab band inside the
left edge. Upper half adjusts Y maximum; lower half adjusts Y minimum.
Bottom X band adjusts the nearer X bound. Wheel over an axis zooms only that axis
around the value under the pointer; the other axis stays unchanged.
Shift still selects a zoom box;
Escape cancels a drag. Axis double-click fits only that axis; data-area
double-click fits both. Manual fits are one-shot and disable continuous auto-fit.
PlotState::fit_to and fit_data still explicitly enable continuous auto-fit.
With workspace, these plots include a right-click menu for Fit X axis,
Fit Y axis, and Fit both axes. The menu uses the active zgui-ui theme.
Pure zgui builds retain dragging and axis double-click without pulling in
zgui-ui. Custom surfaces can compose zgui_workspace::PlotFitMenu directly.
PlotState::fit_axes(&PlotData, Axes) and fit_axis(&PlotData, Axis) preserve
unselected axes and ignore hidden series; empty or entirely hidden data leaves
the view unchanged. PlotSurface::on_fit_axis exposes axis-aware double-click
to custom consumers; omitting it retains full-reset fallback. HitZones exposes
y_axis_width; y_min_handle = false uses the whole bottom band for X bounds.
Right-clicking a legend entry does not toggle it.