TL;DR
Migrating a WPF chart to SciChart mostly changes where data lives and how it gets drawn, while the rest of your application stays put. XAML layout, MVVM bindings and view models carry over. Data moves into a DataSeries object, drawing moves to renderable series on a DirectX-accelerated surface, and refresh calls and mouse handlers give way to Append calls and chart modifiers. Done in the wrong order, it turns into a rewrite. This guide follows one sensor dashboard through each shift, then covers deployment, a safe migration order, and common questions.
What Is a WPF Chart?
WPF stands for Windows Presentation Foundation, Microsoft's framework for building Windows desktop applications. A WPF chart is a chart control placed in a window of such an app. It draws data as lines, bars or points and redraws as the data changes.
A WPF chart is a stack of parts, and a migration touches each one differently. The surface is the control that sits in your window and draws everything. Axes define how numbers map to pixels. Series are the lines, bars or points themselves. Data is the collection of values a series reads from. Interaction covers zooming, panning, tooltips and selection. Annotations are the labels and shapes layered on top.
What Goes Wrong When a WPF Chart Outgrows Its Data
Picture a team that ships a WPF desktop app for monitoring vibration sensors on factory equipment. The scenario is hypothetical, but the shape is common. One window shows a line chart per sensor, bound to an ObservableCollection of points in the view model. A DispatcherTimer adds readings and then tells the chart to refresh. Users zoom with the mouse wheel, drag to pan, and hover to read a value.
As the team adds channels and keeps longer history, the chart becomes the part of the app that makes the UI feel heavy. Everything else is fine: the sensor ingestion, the alarm logic, the settings screens. That is the situation the rest of this guide assumes, one chart worth replacing inside an application that is not. The same dashboard threads through every section below, so each change can be judged against something concrete.
In an app like this, the trouble tends to show up in four places:
- Manual refresh: some WPF chart libraries leave the redraw to you. OxyPlot's documentation states that its views do not refresh automatically when the PlotModel changes and tells you to call Invalidate.
- A heavy UI: more channels and longer history make the chart the slowest part of the window, even when ingestion and alarm logic are fine.
- Hand-trimmed history: rolling windows are kept by code that removes old points from the collection by hand.
- Interaction code tied to the old library: zoom, pan and tooltip handling written against the old chart's own types is hard to carry anywhere else.
When the cause is the chart rather than the rest of the app, replacing the chart is worth weighing. The sections below cover how.
What Replacing the Chart Involves
This guide asks a narrower question than a feature-by-feature comparison: when a working WPF chart already exists, what has to change to move it to SciChart, and what can stay exactly as it is? SciChart's WPF vs WinForms vs MAUI Ultimate Comparison Guide covers the choice between frameworks, including MAUI. This guide assumes you are staying on WPF.
In this guide, "migration" covers four things:
-
Data model: how values move from a collection into a
DataSeries. - Update path: how new readings reach the chart, and what happens to manual refresh calls.
- Interaction: how mouse handlers, zooming and annotations map to chart modifiers.
- Deployment: the rendering engine, the graphics fallback and licensing.
The Parts of a WPF Chart and Their SciChart Equivalents
A WPF chart is a stack of parts, and a migration touches each one differently. The surface is the control that sits in your window and draws everything. Axes define how numbers map to pixels. Series are the lines, bars or points themselves. Data is the collection of values a series reads from. Interaction covers zooming, panning, tooltips and selection. Annotations are the labels and shapes layered on top.
SciChart uses the same vocabulary with one difference worth learning early. The control is a SciChartSurface, scales come from NumericAxis objects, and a renderable series such as FastLineRenderableSeries decides how a line looks, as shown in the first-chart tutorial. The numbers themselves live in a separate DataSeries object that the renderable series points to. Zooming and panning come from ChartModifier classes.
Drawing is handled by the Visual Xccelerator Engine, which SciChart's documentation describes as a proprietary C++ graphics engine that targets DirectX on Windows. In plain terms, the rendering work goes to the graphics card when one is available, and the engine falls back to software rendering when it is not.
| Part of the chart | Its job | In SciChart |
|---|---|---|
| Surface | The control that sits in your window and draws everything | SciChartSurface |
| Axes | Define how numbers map to pixels | NumericAxis |
| Series | The lines, bars or points themselves | Renderable series such as FastLineRenderableSeries
|
| Data | The collection of values a series reads from |
DataSeries such as XyDataSeries
|
| Interaction | Zooming, panning, tooltips and selection |
ChartModifier classes |
| Annotations | Labels and shapes layered on top |
TextAnnotation inside SciChartSurface.Annotations
|
What to Write Down Before You Change Any Code
Before writing any SciChart code, write down what the existing chart does. A one-page inventory prevents the most common migration surprise, which is discovering halfway through that a behavior users rely on was never documented. For the sensor dashboard, the inventory covers five things:
- Series types: every line, scatter, band or candlestick the chart draws, checked against the series view models SciChart's MVVM API lists, which include Line, Mountain, Band, XyScatter, Candlestick and HeatMap among others.
- Update path: how new readings reach the chart, how often, and from which thread.
- Interactions: zoom, pan, tooltips, selection, and any custom mouse code someone wrote years ago.
- Annotations and styling: threshold lines, labels, brushes, fonts and templates.
- Deployment: target framework, the machines the app runs on, and how licenses get provisioned.
The update path and the interactions are where most of the effort sits, because both are tied to the old library's own types. The next sections take them in that order, after the data model that makes them possible.
Porting the Chart: Data, Updates and Interaction
The port takes three passes, in this order: the data model, the update path, then interaction.
How SciChart Separates Data From Presentation in WPF
The biggest conceptual change is that every series becomes two objects. A DataSeries, such as XyDataSeries, holds the values. A renderable series view model holds the appearance and points to its data. The MVVM tutorial builds exactly this pairing: an XyDataSeries wrapped by a LineRenderableSeriesViewModel inside an ObservableCollection that the view binds to. Applied to the sensor dashboard, the view model looks like this:
public class SensorViewModel
{
public XyDataSeries<double, double> Vibration { get; } =
new XyDataSeries<double, double> { SeriesName = "Vibration", FifoCapacity = 5000 };
public ObservableCollection<IRenderableSeriesViewModel> RenderableSeries { get; } =
new ObservableCollection<IRenderableSeriesViewModel>();
public SensorViewModel()
{
RenderableSeries.Add(new LineRenderableSeriesViewModel
{
StrokeThickness = 2,
Stroke = Colors.SteelBlue,
DataSeries = Vibration
});
}
}
The view binds the collection with the SeriesBinding markup extension and declares its axes and modifiers explicitly, as the documentation's own examples do:
<s:SciChartSurface RenderableSeries="{s:SeriesBinding RenderableSeries}">
<s:SciChartSurface.XAxis>
<s:NumericAxis AxisTitle="Sample"/>
</s:SciChartSurface.XAxis>
<s:SciChartSurface.YAxis>
<s:NumericAxis AxisTitle="Vibration (mm/s)"/>
</s:SciChartSurface.YAxis>
<s:SciChartSurface.ChartModifier>
<s:ModifierGroup>
<s:MouseWheelZoomModifier/>
<s:ZoomPanModifier/>
<s:ZoomExtentsModifier/>
</s:ModifierGroup>
</s:SciChartSurface.ChartModifier>
</s:SciChartSurface>
The namespace declaration is xmlns:s="http://schemas.abtsoftware.co.uk/scichart", and the package to install from NuGet is named SciChart. The point of the split is that the view model now owns a data object, and appearance is configured separately from it.
How to Replace Manual Refresh Calls With DataSeries Append
In the old dashboard, the timer changed a collection and then asked the chart to redraw. Some WPF chart libraries make that second step explicit. OxyPlot's documentation, for example, states that its views do not refresh automatically when the PlotModel changes and tells you to call Invalidate on the view or the model. In SciChart the equivalent step disappears. The real-time tutorial states that the chart redraws automatically when data changes, so the timer only has to append.
The tutorial's pattern is a DispatcherTimer at render priority, with the changes wrapped in SuspendUpdates, which it says "ensures the chart is frozen while you do updates. This ensures best performance." Adapted to the dashboard, with a batch of readings per tick:
var timer = new DispatcherTimer(DispatcherPriority.Render)
{
Interval = TimeSpan.FromMilliseconds(10)
};
timer.Tick += (s, e) =>
{
using (vm.Vibration.SuspendUpdates())
{
// xValues and yValues are equal-length lists of new readings
vm.Vibration.Append(xValues, yValues);
}
};
timer.Start();
The DataSeries reference documents an Append overload that takes lists of X and Y values and throws if the counts differ. If readings arrive on background threads, collect them and append from the timer, as the tutorial does, rather than appending from the sensor thread.
Rolling windows get their own mechanism. Setting FifoCapacity on the DataSeries, as the view model above does, makes the series discard its oldest point once the capacity is exceeded. The tutorial calls this "the most memory efficient way to achieve scrolling," which replaces the code that trims the old collection by hand.
How to Move Mouse Handlers and Annotations to SciChart
Interaction is the second place where the old library's types leak into your code. In SciChart, the ChartModifier API handles zooming, panning, tooltips, legends and selection through classes derived from ChartModifierBase, so most hand-written mouse logic has a built-in replacement. For the dashboard, the mapping is short:
- Wheel zoom becomes MouseWheelZoomModifier.
- Drag to pan becomes ZoomPanModifier, and rubber-band zoom is RubberBandXyZoomModifier.
- Double-click to reset becomes ZoomExtentsModifier.
- Hover to read a value becomes RolloverModifier, CursorModifier or ToolTipModifier, depending on whether you want a vertical line, a crosshair or a nearest-series tooltip.
Modifiers combine through ModifierGroup, which attaches several of them to one surface and passes mouse events to each. Two details save debugging time. If you later add a second axis with a custom ID, the modifiers that target a specific axis need their XAxisId and YAxisId set to match. And for any custom behavior your old chart had, start by reading how the built-in modifiers derive from ChartModifierBase, since the documentation says all of them derive from that class.
Annotations follow the same declarative pattern. In the documentation's first-chart example, a TextAnnotation sits inside SciChartSurface.Annotations and is positioned with its X1 and Y1 properties, which suits the dashboard's threshold labels. Series styling needs no separate step, because the Stroke and StrokeThickness properties on the renderable series view model, shown earlier, carry the line's appearance.
What Stays the Same in Your WPF Application
Most of the application is untouched. The window, the layout, the DataContext wiring and the view models stay as they are, and so does everything upstream of the chart: sensor ingestion, business rules and persistence. SciChart supports MVVM directly, and its MVVM API documentation puts it plainly: "Anything you can achieve in code or XAML you can achieve in MVVM." Adding, changing or removing a series view model in a bound collection changes what the chart shows.
One item does not carry over automatically, and it is worth checking first. SciChart WPF v9 targets .NET Framework 4.6.2 and .NET 6 or later, and the v9 breaking-changes notes state that .NET Core 3.1 is no longer supported. An application still on that target needs a framework upgrade before any chart work begins.
What the DirectX Rendering Engine Means for Deployment
DirectX is Microsoft's set of graphics APIs for Windows, and it lets software hand drawing work to the graphics card.
The deployment line in the inventory is where SciChart differs most from a pure-WPF chart, so it deserves its own pass. The Visual Xccelerator Engine is the default renderer for SciChartSurface, and the engine documentation says it requires a DirectX 9c capable graphics card with at least 256 MB of VRAM, with DirectX 11 preferred. When hardware acceleration is not available, SciChart falls back to software rendering automatically, because the DowngradeWithoutException property defaults to true. SciChart's system requirements FAQ adds that 2D charts have software fallbacks and that a DirectX 11 or later GPU is recommended but not necessary. 3D charts do require a DirectX 9c capable card.
For the sensor dashboard, the practical step is to run the migrated chart on the lowest-spec machine in the field, such as a plant-floor PC with integrated graphics, and confirm the fallback behaves acceptably there.
Licensing is the other deployment change. According to SciChart's WPF licensing page, the product is licensed per developer with royalty-free redistribution rights for your applications. Trial licenses are machine-specific, and without a runtime key an application works only on the developer's PC. The docs say to set the key once, before any SciChartSurface is shown, in the App constructor or at application startup:
public partial class App : Application
{
public App()
{
// Set once, before any SciChartSurface is shown
SciChartSurface.SetRuntimeLicenseKey("YOUR_KEYCODE");
}
}
That page lists no prices, so budget conversations go through the SciChart store or sales rather than the documentation.
The Safest Order to Migrate a WPF Chart
A chart migration goes smoothly when each step can be tested before the next begins. For the sensor dashboard, the order that follows keeps the old chart working until the new one has earned its place:
- Upgrade the project to a supported target framework, since SciChart WPF v9 needs .NET Framework 4.6.2 or .NET 6 and later.
- Install the SciChart NuGet package and set the runtime license key at startup.
- Port a single series: a DataSeries, a renderable series view model, SeriesBinding in the view, and explicit axes.
- Move the update path to Append inside SuspendUpdates, with FifoCapacity for rolling windows.
- Replace the mouse handling with chart modifiers, then port annotations and styling.
- Compare both charts on the same recorded data, test on the lowest-spec target machine, and only then remove the old library.
Keeping both charts side by side through step 6 turns the final cutover into a comparison instead of a leap. It also gives reviewers something concrete to sign off on.
How to Verify the Migrated Chart
Verification mirrors the inventory you wrote at the start. Run the old and new charts side by side and check each item on it:
- Data: feed both charts the same recorded dataset, at your real update rate.
- Appearance: compare axis ranges, tick formatting, colours, annotations and every interaction on the inventory list.
- Hardware: run the migrated chart on your lowest-spec target machine, such as a plant-floor PC with integrated graphics, and confirm the software fallback behaves acceptably there.
- Licensing: run it on a machine other than the developer's, with the runtime key set at startup.
- Sign-off: keep the old chart in the project until reviewers approve the comparison.
Decision Framework
Profile before you commit. Find out whether the time goes to data volume, update frequency or UI-thread work, and try cheaper fixes such as a lower refresh rate before changing libraries. Migration earns its cost when the chart itself is the bottleneck and the requirements keep growing. Find the row below that matches your situation.
| Your situation | What to do first | Why |
|---|---|---|
| The chart is the bottleneck and requirements keep growing | Migrate, in the order above | The chart itself is the limit, so tuning elsewhere will not move it. |
| Time goes to data volume, update frequency or UI-thread work elsewhere | Profile and tune first | Cheaper fixes such as a lower refresh rate may be enough before changing libraries. |
| The app targets .NET Core 3.1 | Upgrade the framework first | SciChart WPF v9 targets .NET Framework 4.6.2 and .NET 6 or later, and .NET Core 3.1 is no longer supported. |
| Readings arrive in bursts or on background threads | Collect them, then Append from a timer inside SuspendUpdates
|
This follows the real-time tutorial instead of appending from the sensor thread. |
| The app deploys to machines with weak or no GPU | Test the software fallback on the lowest-spec machine | 2D charts have software fallbacks, and a DirectX 11 or later GPU is recommended but not necessary. |
| The old chart has custom mouse code | Read how the built-in modifiers derive from ChartModifierBase before rewriting it |
The documentation says all built-in modifiers derive from that class. |
Conclusion
The application around a chart barely changes in this kind of migration. XAML layout, DataContext wiring and view models carry over, while three things move: data goes into a DataSeries, refresh calls become Append calls inside SuspendUpdates, and hand-written mouse code gives way to chart modifiers. Deployment adds two checks, a graphics fallback test and a runtime license key.
Start with one chart and one series. Get a surface on screen using SciChart's WPF getting-started page, which covers account setup and the trial, then apply the real-time tutorial pattern to your own data feed.
FAQs
Do I need to rewrite my view models to adopt SciChart?
Not from scratch. Existing bindings, commands and data models stay, and the chart-facing part of each view model gains a DataSeries plus a collection of renderable series view models. Properties that only fed the old chart's collection can usually be removed once the new series is live.
Does SciChart WPF need a dedicated GPU?
No. SciChart's system requirements FAQ says 2D charts have software rendering fallbacks, and a DirectX 11 or later GPU is recommended but not necessary. 3D charts do require a DirectX 9c capable video card.
Which .NET versions does SciChart WPF support?
Version 9 targets .NET Framework 4.6.2 and .NET 6 or later. .NET Core 3.1 is no longer supported in that version, so applications on it need to upgrade first.
How is a deployed SciChart WPF application licensed?
Licensing is per developer with royalty-free redistribution rights for your applications. To run on machines other than the developer's, the application needs the runtime key, set once at startup with SciChartSurface.SetRuntimeLicenseKey.
How do I know a chart is worth migrating instead of tuning?
Profile first. Find out whether the time goes to data volume, update frequency or UI thread work, and try cheaper fixes such as reducing refresh rate before changing libraries. Migration earns its cost when the chart itself is the bottleneck and the requirements keep growing.
How should I check visual parity after a migration?
Feed both charts the same recorded dataset and compare them side by side. Check axis ranges, tick formatting, colors, annotations and every interaction on your inventory list, then keep the old chart in the project until reviewers sign off.



Top comments (0)