Category / Section
How to create a real time Chart (SfChart) using MVVM in WPF
2 mins read
This article describes how to create a real time chart in WPF. The following code example illustrates how to update the ItemsSource bound to chart series in real time use case.
[XAML]
<chart:SfChart x:Name="Chart" Margin="0,20,20,0" AreaBorderThickness="0,1,1,1"> <chart:SfChart.DataContext> <local:DataGenerator/> </chart:SfChart.DataContext> <chart:SfChart.PrimaryAxis> <chart:DateTimeAxis LabelFormat="hh:mm:ss"> <chart:ChartAxis.Header> <TextBlock Margin="10" Text="Time" FontSize="16" FontFamily="SegoeUI"/> </chart:ChartAxis.Header> </chart:DateTimeAxis> </chart:SfChart.PrimaryAxis> <chart:SfChart.SecondaryAxis> <chart:NumericalAxis Minimum="1000" Maximum="1006" Interval="1" > <chart:ChartAxis.Header> <TextBlock Margin="10" Text="Value" FontSize="16" FontFamily="SegoeUI"/> </chart:ChartAxis.Header> </chart:NumericalAxis> </chart:SfChart.SecondaryAxis> <chart:FastLineBitmapSeries EnableAntiAliasing="False" Label="First" XBindingPath="Date" YBindingPath="Value" LegendIcon="SeriesType" StrokeThickness="1" ItemsSource="{Binding DynamicData}"/> <chart:FastLineBitmapSeries EnableAntiAliasing="False" Label="Second" XBindingPath="Date" YBindingPath="Value1" LegendIcon="SeriesType" StrokeThickness="1" ItemsSource="{Binding DynamicData}"/> <chart:FastLineBitmapSeries EnableAntiAliasing="False" Label="Third" XBindingPath="Date" YBindingPath="Value2" LegendIcon="SeriesType" StrokeThickness="1" ItemsSource="{Binding DynamicData}"/> </chart:SfChart>
[C#]
public class Data { public Data(DateTime date, double value, double value1, double value2) { Date = date; Value = value; Value1 = value1; Value2 = value2; } public DateTime Date { get; set; } public double Value { get; set; } public double Value1 { get; set; } public double Value2 { get; set; } }
[C#]
public class DataGenerator { private Random randomNumber; private ObservableCollection<Data> data = new ObservableCollection<Data>(); public int dataCount = 50000; private int rate = 5; int index = 0; DispatcherTimer timer; public ObservableCollection<Data> DynamicData { get; set; } public DataGenerator() { randomNumber = new Random(); DynamicData = new ObservableCollection<Data>(); data = GenerateData(); LoadData(); timer = new DispatcherTimer(); timer.Tick += timer_Tick; timer.Interval = new TimeSpan(0, 0, 0, 0, 50); timer.Start(); } public void AddData() { for (int i = 0; i < rate; i++) { index++; if (index < 100) { DynamicData.Add(this.data[index]); } else if (index > 100) { DynamicData.RemoveAt(0); DynamicData.Add(this.data[(index % (this.data.Count - 1))]); } } } public void LoadData() { for (int i = 0; i < 10; i++) { index++; if (index < data.Count) { DynamicData.Add(this.data[index]); } } } public ObservableCollection<Data> GenerateData() { ObservableCollection<Data> generatedData = new ObservableCollection<Data>(); DateTime date = new DateTime(2009, 1, 1); double value = 1000; double value1 = 1001; double value2 = 1002; for (int i = 0; i < this.dataCount; i++) { generatedData.Add(new Data(date, value, value1, value2)); date = date.Add(TimeSpan.FromSeconds(5)); if ((randomNumber.NextDouble() + value2) < 1004.85) { double random = randomNumber.NextDouble(); value += random; value1 += random; value2 += random; } else { double random = randomNumber.NextDouble(); value -= random; value1 -= random; value2 -= random; } } return generatedData; } private void timer_Tick(object sender, EventArgs e) { AddData(); } }
Output
Download the complete sample here.
See Also
How to bind a simple collection to Chart (SfChart) in WPF
Tips to improve the performance of Chart in WPF
What are the available types of Chart