ChartView class Pro

A chart as a ready-made view: grid.MainView = new ChartView(model).

Each view builds its own ChartDefinition; there is deliberately no constructor taking one. The definition drives a grid through its callbacks, so two views sharing one would scroll each other on zoom.

public sealed class ChartView : ArionView
Namespace
ArionUI.Charts
Package
ArionUI.Charts · dotnet add package ArionUI.Charts --prerelease
Inherits
ArionView

Constructors

ChartView

public ChartView(ChartModel model);

Parameters

model

Categories, series and the precomputed scale.

Properties

Definition

public ChartDefinition Definition { get; }

The presentation: step width, time axis, navigator, series colours. Changes take effect via ChartView.Refresh.

Model

public ChartModel Model { get; }

The model this chart shows.

RecommendedFrozenColumns

public override int? RecommendedFrozenColumns { get; }

The Y axis stays frozen on the left while the plot scrolls; the host applies this when attaching.

Source

public override IItemsSource Source { get; }

The item source the engine virtualizes (top of this view's projection stack — e.g. a grouping over a sort/filter over the data).

Template

public override ITemplate Template { get; }

The drawing model the renderer uses for this view.

Methods

Append

public void Append(int seriesIndex, ReadOnlySpan<double> values);

Appends to a streaming series (see StreamingChartSeries) in place: the category axis and layout stay exactly as they are (a streaming model is built with a fixed point count up front), so this needs only a redraw, not the relayout ChartView.Update triggers for a genuinely new model.

MarkCategory

public void MarkCategory(int? category, bool bringIntoView = true);

Pins the crosshair to a category (the selected row of a coupled grid), or takes it away with null. The plot repaints itself, and scrolls the category into view when the chart is wider than its window.

Parameters

category

The category, or null for no mark.

bringIntoView

False for a mark that merely follows its data (a streaming FIFO moving it along): scrolling on every tick would take the plot out of the user's hands.

OnAttached

protected override void OnAttached();

OnDetached

protected override void OnDetached();

Removes only this view's own callbacks. The host attaches the new view before detaching the old one, so blindly nulling the callbacks could silence a view that shares the definition.

Refresh

public void Refresh();

Relayouts and redraws after a change to ChartView.Definition. An explicit call rather than automatic per-property relayout, so several changes cost one relayout.

TickGpuLayer

public bool TickGpuLayer();

One frame tick of a LIVE GPU layer (spec 5a, rule 1): marks the plot row dirty and asks for a repaint - the same path ChartView.Append uses for new samples.

Why it is needed at all: the host keeps a persistent scroll buffer and shifts it instead of redrawing. A cell that changes on its OWN (an animation) produces no dirty row, so the frame would be a no-op re-present and scrolling would drag a frozen picture of the cell along. A layer that reports IGpuLayer.IsLive false costs nothing here.

Caller: whoever drives the animation (the scene's frame tick). Not called from inside the draw, which would ask for a frame from within a frame.

Returns

True when a repaint was requested.

Update

public void Update(ChartModel model);

Shows another model in the same view: zoom, scroll and the host stay, the plot relayouts. This is the live path — build a new model, hand it in.

Events

CategoryClicked

public event Action<ChartClick>? CategoryClicked;

Raised by a click in the plot - a press and release that did not span a zoom band - with the category under the press and what its height means on each axis that is drawn (see ChartClick: with two axes one number cannot tell which series was meant). The chart itself does nothing with it; a scene that couples the chart to a grid selects the matching row here.