In this post, we will look into stream the data over the Oxyplot. In other words, the new data should be always displayed and the old data moves out of screen. These are useful when you want to observe live data, say coming from a sensor. Consider the following screenshot, this is the behavior we would like to emulate.

We will begin by setting the stage - a demo code to generate random data at regular intervals.
public BindableCollection < SensorData > SensorData {
get;
set;
}
private DispatcherTimer ? _timer;
private Random _randomGenerator;
public void StartAcquisition() {
if (_timer is null) {
_timer = new DispatcherTimer {
Interval = TimeSpan.FromMilliseconds(500),
};
_timer.Tick += MockSensorRecievedData;
}
_timer.Start();
NotifyOfPropertyChange(nameof(CanStartAcquisition));
NotifyOfPropertyChange(nameof(CanStopAcquisition));
}
private void MockSensorRecievedData(object ? sender, EventArgs e) {
SensorData.Add(new() {
TimeStamp = DateTime.Now,
Data = _randomGenerator.NextDouble()
});
}
Where SensorData is defined as
public class SensorData {
public DateTime TimeStamp {
get;
set;
}
public double Data {
get;
set;
}
}
We are using a DispatchTimer to schedule data generation at regular intervals. Nothing fancy so far, as we haven't added our Chart control yet. So let us now go ahead and add our Oxyplot Chart control in our View now.
<oxy:PlotView Grid.Column="0" Model="{Binding SensorPlotModel}"></oxy:PlotView>
As seen in the view, the PlotView is bound to SensorPlotModel. We can now go back to our ViewModel and add/configure our PlotModel.
public PlotModel SensorPlotModel {
get;
set;
}
private
const int MaxSecondsToShow = 20;
public void InitializePlotModel() {
SensorPlotModel = new() {
Title = "Demo Live Tracking",
};
SensorPlotModel.Axes.Add(new DateTimeAxis {
Title = "TimeStamp",
Position = AxisPosition.Bottom,
StringFormat = "HH:mm:ss",
IntervalLength = 60,
Minimum = DateTimeAxis.ToDouble(DateTime.Now),
Maximum = DateTimeAxis.ToDouble(DateTime.Now.AddSeconds(MaxSecondsToShow)),
IsPanEnabled = true,
IsZoomEnabled = true,
IntervalType = DateTimeIntervalType.Seconds,
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.Solid,
});
SensorPlotModel.Axes.Add(new LinearAxis {
Title = "Data Value",
Position = AxisPosition.Left,
IsPanEnabled = true,
IsZoomEnabled = true,
Minimum = 0,
Maximum = 1
});
SensorPlotModel.Series.Add(new LineSeries() {
MarkerType = MarkerType.Circle,
});
}
Join the conversation! Your thoughts help the community grow.