ZoomExtents in MVVM — ZoomExtentsWhenReady
In MVVM applications, Series ViewModels and their data are typically created in a constructor or initialization method — before the SciChartSurface has attached the view models to actual RenderableSeries. Calling SciChartSurface.ZoomExtents() at this point would have no effect, because the view may have not yet established WPF bindings to ViewModels.
Since v9.0, SciChart provides extension methods on IRenderableSeriesViewModel that solve this timing problem. They defer the ZoomExtents operation until all specified series are attached to a Surface and ready for manipulation, then trigger ZoomExtents automatically.
Basic Usage — Fire and Forget
The simplest approach is ZoomExtentsWhenReady(), a fire-and-forget extension method. Call it on the Series ViewModels collection after data is assigned. The chart will zoom to fit all data as soon as the surface is ready.
| Using ZoomExtentsWhenReady() |
Copy Code |
|---|---|
using SciChart.Charting.Common.Extensions; public class ChartViewModel { public ObservableCollection<IRenderableSeriesViewModel> RenderableSeries { get; } = new ObservableCollection<IRenderableSeriesViewModel>(); public ChartViewModel() { var ds = new XyDataSeries<double, double>(); for (int i = 0; i < 100; i++) ds.Append(i, Math.Sin(i * 0.1)); RenderableSeries.Add(new LineRenderableSeriesViewModel { DataSeries = ds, Stroke = Colors.CornflowerBlue }); // Deferred ZoomExtents — fires once the surface is ready RenderableSeries.ZoomExtentsWhenReady(); } } | |
This is the recommended approach for most scenarios.
Single Series Overload
The extension method also works on a single IRenderableSeriesViewModel. This is convenient when you have one primary series and want to zoom to its data range:
| Applying ZoomExtentsWhenReady() to a single Series |
Copy Code |
|---|---|
var lineSeries = new LineRenderableSeriesViewModel { DataSeries = dataSeries, Stroke = Colors.CornflowerBlue }; RenderableSeries.Add(lineSeries); // Wait for this specific series to be ready, then ZoomExtents lineSeries.ZoomExtentsWhenReady(); | |
Async Overload with Timeout
For scenarios where you need to know whether ZoomExtents succeeded (e.g., integration tests or conditional logic), use the async overload ZoomExtentsWhenReadyAsync(). It returns true if ZoomExtents was executed, or false if it timed out or was a duplicate request.
| Applying Async ZoomExtents with Timeout |
Copy Code |
|---|---|
// Wait up to 10 seconds for the chart to be ready bool success = await RenderableSeries.ZoomExtentsWhenReadyAsync( rangeMode: RangeMode.ZoomToFit, operationTimeoutMs: 10000); if (!success) { Debug.WriteLine("ZoomExtents timed out — chart may not be attached yet."); } | |
The default timeout is 5000 ms. If the ViewModels are not attached to a Surface within this period, the request is silently discarded and the method returns false.
RangeMode Parameter
Both overloads accept an optional RangeMode parameter that controls how the extents are calculated:
- RangeMode.ZoomToFit (default) — zooms all axes to fit the full data range of all visible series.
- RangeMode.ZoomToFitX — zooms only the X axis to fit the data; Y axes remain unchanged.
- RangeMode.ZoomToFitY — zooms only the Y axis to fit the data; X axes remain unchanged.
| ZoomExtents only in the Y-direction |
Copy Code |
|---|---|
// Zoom only the Y axis to fit data (keep current X range)
RenderableSeries.ZoomExtentsWhenReady(RangeMode.ZoomToFitY); | |
Behavioral Notes
- Thread safety: the extension methods are safe to call from any thread. The actual ZoomExtents operation executes on the Dispatcher thread.
- Idempotent: calling ZoomExtentsWhenReady multiple times on the same collection is safe — duplicates are detected and discarded.
- No code-behind required: because the methods are extension methods on IRenderableSeriesViewModel, they can be called entirely from ViewModels. No reference to the SciChartSurface is needed.
- Interaction with Axis Sync: if the chart has synchronized axes (RangeSyncGroupId), the ZoomExtents operation respects the same suppression and RangeSyncSourceOnZoomExtents rules as a manual ZoomExtents call.
API Summary
| Main usages |
Copy Code |
|---|---|
// Extension methods on IRenderableSeriesViewModel / IEnumerable<IRenderableSeriesViewModel> // Namespace: SciChart.Charting.Common.Extensions // Fire-and-forget — single series viewModel.ZoomExtentsWhenReady(RangeMode rangeMode = RangeMode.ZoomToFit); // Fire-and-forget — collection of series viewModels.ZoomExtentsWhenReady(RangeMode rangeMode = RangeMode.ZoomToFit); // Async — single series (returns true on success, false on timeout/duplicate) await viewModel.ZoomExtentsWhenReadyAsync( RangeMode rangeMode = RangeMode.ZoomToFit, int operationTimeoutMs = 5000); // Async — collection of series await viewModels.ZoomExtentsWhenReadyAsync( RangeMode rangeMode = RangeMode.ZoomToFit, int operationTimeoutMs = 5000); | |