Skip to content

Viewport Control

The ViewportControl trait controls the chart viewport — canvas resize, visible bar range, scroll position, and pane layout — on any chart view. Both ChartView and ChartView implement this trait.

Import

rust
use navi_chart::{ChartView, ChartView, ViewportControl};

Usage

rust
use navi_chart::ViewportControl;

/// Scroll to the most recent bar (rightmost position).
fn scroll_to_latest<C>(cv: &C)
where
    C: ViewportControl,
{
    let last = cv.total_bars().saturating_sub(1);
    cv.scroll_to_bar(last);
}

/// Highlight a bar on hover (e.g., from a strategy tester row click).
fn highlight_bar<C>(cv: &C, bar_index: Option<usize>)
where
    C: ViewportControl,
{
    cv.set_highlighted_bar(bar_index);
}

Method Reference

MethodDescription
on_resize(size)Notify the chart that the canvas has been resized. size carries width and height in logical/CSS pixels. Call whenever the host window or container changes dimensions.
pane_ratios()Return the current height ratios for all panes. The first element is the main pane; subsequent elements are sub-panes in order. Values sum to approximately 1.0.
set_pane_ratios(ratios)Set the pane height ratios. The length must equal the total number of panes (main + all sub-panes created by loaded scripts). Values must sum to 1.0.
scroll_to_bar(index)Scroll the viewport so that bar index is visible. Bar index is 0-based from the oldest bar in the dataset.
set_scroll_offset(offset)Set the fractional bar index of the left viewport edge directly. 0.0 shows the oldest bars; increasing values scroll right toward newer bars.
set_viewport(offset, visible_bars)Set both the scroll offset and the number of visible bars (zoom level) in a single call. Equivalent to calling set_scroll_offset and then adjusting zoom.
scroll_offset()Return the current fractional bar index of the left viewport edge.
visible_bars()Return the number of bars currently visible at the current zoom level.
total_bars()Return the total number of bars in the dataset.
set_highlighted_bar(index)Highlight a specific bar (e.g. to mark a strategy trade). Pass Some(index) to highlight, None to clear. The highlighted bar renders with a distinct background.
time_to_bar_index(time_ms)Return the index of the most-recent bar whose time is ≤ time_ms. Returns None if time_ms precedes all bars.
bar_index_to_time(idx)Return the timestamp (ms) of the bar at idx, or None if the index is out of range.

Pane Layout

Sub-panes are created automatically when scripts call indicator(overlay=false). Use set_pane_ratios to control their relative heights:

rust
// Main pane takes 60%, two sub-panes share the remaining 40%
cv.set_pane_ratios(vec![0.6, 0.2, 0.2]);

// Read back the current ratios
let ratios = cv.pane_ratios();
println!("Pane count: {}", ratios.len());

The ratios slice must have the same length as the current number of panes. If scripts have not yet loaded, the chart has only one pane (the main pane) and set_pane_ratios(vec![1.0]) is the only valid call.

Bar Index

Bar indices are 0-based from the oldest bar in the dataset:

  • 0 — oldest (leftmost) bar
  • total_bars() - 1 — most recent (rightmost) bar

visible_bars() returns the number of bars currently visible, which changes as the user zooms in or out. total_bars() is the fixed size of the loaded dataset.

Scroll to Latest

rust
use navi_chart::ViewportControl;

fn scroll_to_latest<C>(cv: &C)
where
    C: ViewportControl,
{
    let last = cv.total_bars().saturating_sub(1);
    cv.scroll_to_bar(last);
}

Call this after loading new data or restoring a snapshot to ensure the most recent bars are visible.

Highlight Bar on Hover

A common pattern in strategy testers: clicking a trade row scrolls the chart to that bar and highlights it:

rust
use navi_chart::{ViewportControl, ChartSettings};

fn jump_to_trade<C>(cv: &C, bar_index: usize)
where
    C: ViewportControl,
{
    cv.scroll_to_bar(bar_index);
    cv.set_highlighted_bar(Some(bar_index));
}

fn clear_highlight<C>(cv: &C)
where
    C: ViewportControl,
{
    cv.set_highlighted_bar(None);
}

Saving and Restoring Viewport State

rust
use navi_chart::ViewportControl;

struct ViewportSnapshot {
    scroll_offset: f64,
    visible_bars: f64,
    pane_ratios: Vec<f64>,
}

fn save_viewport<C>(cv: &C) -> ViewportSnapshot
where
    C: ViewportControl,
{
    ViewportSnapshot {
        scroll_offset: cv.scroll_offset(),
        visible_bars: cv.visible_bars(),
        pane_ratios: cv.pane_ratios(),
    }
}

fn restore_viewport<C>(cv: &C, snap: ViewportSnapshot)
where
    C: ViewportControl,
{
    cv.set_viewport(snap.scroll_offset, snap.visible_bars);
    cv.set_pane_ratios(snap.pane_ratios);
}

Released under the MIT License.