Skip to content

feat: add public current_viewport() getter + ViewportInfo#20

Open
mmavka wants to merge 1 commit intodonkeyteethUX:mainfrom
mmavka:upstream-pr/current-viewport
Open

feat: add public current_viewport() getter + ViewportInfo#20
mmavka wants to merge 1 commit intodonkeyteethUX:mainfrom
mmavka:upstream-pr/current-viewport

Conversation

@mmavka
Copy link
Copy Markdown

@mmavka mmavka commented Apr 14, 2026

Motivation

Applications embedding PlotWidget often need to read the current viewport
programmatically to coordinate external behavior: fetching a data range from
a backend, syncing a secondary view or minimap, serializing session state,
building viewport-aware tooltips, or computing pixel-to-data projections
outside the widget's own event loop.

Today, the only way to observe viewport changes is to subscribe to
PlotUiMessage::RenderUpdate and read the x_ticks / y_ticks arrays —
which is indirect (tick positions approximate the viewport rather than
describe it exactly), fragile (the payload struct is #[doc(hidden)]),
and costly (consumers allocate a full tick vec per change). Reading on-demand
currently isn't possible at all: the relevant camera/bounds state is cached
inside PlotWidget.camera_bounds but is crate-private.

This PR exposes a direct, on-demand getter that returns the current data-space
ranges plus the plot area's pixel rectangle as a single Copy struct.

What this PR does

  • Adds PlotWidget::current_viewport() -> Option<ViewportInfo>.
  • Adds a new public struct ViewportInfo { x_min, x_max, y_min, y_max, plot_area: Rectangle }.
  • Re-exports ViewportInfo from the crate root.
  • Reads from the existing cached camera_bounds state — no new state, no new
    syncing logic, no shader/renderer changes.
  • Inverts plot-space values back to data-space through the existing
    AxisScale::plot_to_data so the returned ranges are meaningful even with
    AxisScale::Log.
  • Returns None if the widget hasn't been rendered yet (camera_bounds is
    lazily populated during the first shader update).

API additions

/// Current viewport state of a `PlotWidget`.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct ViewportInfo {
    pub x_min: f64,
    pub x_max: f64,
    pub y_min: f64,
    pub y_max: f64,
    pub plot_area: Rectangle,
}

impl PlotWidget {
    pub fn current_viewport(&self) -> Option<ViewportInfo> { /* ... */ }
}

Non-breaking

  • No existing public API is changed.
  • No behavioral changes to rendering, events, or picking.
  • 59 insertions, 1 deletion (lib.rs re-export line).
  • No new dependencies, no new unsafe, no new panics.

Example use case

use iced_plot::{PlotWidget, ViewportInfo};

fn on_tick(plot: &PlotWidget) -> Option<&'static str> {
    let vp = plot.current_viewport()?;
    // E.g.: tell a streaming backend to send the data bucket for the
    // currently-visible x range, at the right resolution for the plot width.
    let width_px = vp.plot_area.width as f64;
    request_lod(vp.x_min, vp.x_max, width_px);
    Some("requested")
}

Alternatives considered

  • Subscribing to PlotUiMessage::RenderUpdate and reading tick positions.
    Works, but approximate (tick values under-estimate the viewport edges),
    ties consumers to a #[doc(hidden)] payload struct, and doesn't support
    on-demand reads.
  • Exposing Camera directly. Tighter binding to internal representation
    (e.g. render_offset is an implementation detail for high-precision
    rendering, not a concept the API consumer should see). The ViewportInfo
    shape keeps the surface minimal and stable.
  • A ViewportChanged message variant. Nice additional signal but
    orthogonal to on-demand reads. Could follow as a separate PR if useful.

Related

None.

Adds PlotWidget::current_viewport() returning the current data-space
x/y ranges plus the plot-area pixel rectangle as a new public
ViewportInfo struct.

Reads from the widget's cached camera_bounds state which is already
synced on every pan/zoom/resize via the internal RenderUpdate flow.
For non-linear axis scales (Log), plot-space values are inverted back
to data-space before return.

Enables downstream code to coordinate external behavior with the plot
viewport (e.g. fetching a data range from a backend, syncing a
secondary view, serializing session state) without having to subscribe
to PlotUiMessage::RenderUpdate and parse tick positions out of its
doc-hidden payload.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant