Hi!
My english is not as good as I would like but I expect to be clear.
We have been testing testing telerik charts with Telerik 2011.2.920.35. We have detected performance issues when working with many data series in live time.
Our worst scenario in one RadChart is:
- Datetime XAxis
- 15 Line series (we prefer Spline series but its performance ir really poor)
- 15 YAxis
- 60 Scatter series (each line serie needs 4 scatter serie to represent related data). Number of DataPoints depends on data
- Annotations (Number depends on data)
- Custom tooltip for each datapoint of each data serie
- Show data of 1 hour (but can be more)
- First load of 15 lines * 1 hour * 60 minutes * 6 periods of 10 seconds produces 5400 datapoints
- Data refresh each 10 seconds
We have made a simple test project and we have seen performance issues (just resizing the window you can see the problem):
- Spline series locks the application
- Adding scatter series makes the application go slower
- Adding line series makes the application go slower
We have detect that you can not use AddRange to DataSerie twice. The first time it runs ok but the second time it doesn’t render the serie as it should.
We have seen Performance Tips and Tricks for RadChart (http://www.telerik.com/help/silverlight/radchart-performance-tips-and-tricks.html) but they are not enough for our scenario.
We have seen that in Q3 beta you have been working on Charts (http://blogs.telerik.com/blogs/posts/11-10-21/telerik-xaml-controls-q3-2011-beta-introduces-new-and-empowered-chartingkit.aspx). We haven’t been able to test it yet. Are this problems solved?
Is our scenario requirements more than Telerik RadChart can support?
Our test code is:
MainWindow.xaml
<Window x:Class="TestDataSeries.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Charting"
xmlns:Charting="clr-namespace:Telerik.Windows.Controls.Charting;assembly=Telerik.Windows.Controls.Charting" Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<telerik:RadChart x:Name="VariableChart"
AxisElementBrush="White" AxisForeground="White" Foreground="White"
Background="Black">
<telerik:RadChart.DefaultView>
<Charting:ChartDefaultView>
<Charting:ChartDefaultView.ChartArea>
<Charting:ChartArea Background="Black">
</Charting:ChartArea>
</Charting:ChartDefaultView.ChartArea>
</Charting:ChartDefaultView>
</telerik:RadChart.DefaultView>
</telerik:RadChart>
<Button Content="New Line serie" Click="CreateNewLine" Grid.Row="1"></Button>
<Button Content="New Spliline serie" Click="CreateNewSpliline" Grid.Row="2"></Button>
<Button Content="New Scatter serie" Click="CreateNewScatter" Grid.Row="3"></Button>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using Telerik.Windows.Controls.Charting;
namespace TestDataSeries
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private Random _random = new Random();
private DateTime _beginDate;
public MainWindow()
{
InitializeComponent();
_beginDate = DateTime.Now.AddHours(-1);
SetUpRadChart();
SetUpXAxis();
SetUpTimer();
}
public DispatcherTimer Timer { get; set; }
private void SetUpRadChart()
{
VariableChart.DefaultView.ChartTitle.Visibility = Visibility.Collapsed;
VariableChart.DefaultView.ChartLegend.Visibility = Visibility.Collapsed;
VariableChart.DefaultView.ChartArea.IsNoDataMessageEnabled = false;
VariableChart.DefaultView.ChartArea.NoDataString = "No data";
VariableChart.DefaultView.ChartArea.EnableAnimations = false;
VariableChart.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.None;
VariableChart.DefaultView.ChartArea.ZoomScrollSettingsY.ScrollMode = ScrollMode.None;
VariableChart.DefaultView.ChartArea.AxisY.Visibility = Visibility.Collapsed;
VariableChart.DefaultView.ChartArea.AxisY.StripLinesVisibility = Visibility.Collapsed;
}
private void SetUpTimer()
{
Timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(10) };
Timer.Tick += Timer1Tick;
}
private void Timer1Tick(object sender, EventArgs e)
{
foreach (var dataSerie in VariableChart.DefaultView.ChartArea.DataSeries)
{
//var pointList = new ObservableCollection<DataPoint>();
//pointList.Add(new DataPoint(DateTime.Now.ToOADate(), _random.NextDouble()));
//This code doesn't run as expected!!!!!!!!!!!!!!! It appears to be the same as dataSerie.Add but it is not
//dataSerie.AddRange(pointList);
dataSerie.Add(new DataPoint(DateTime.Now.ToOADate(), _random.NextDouble()));
}
}
private void SetUpXAxis()
{
VariableChart.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "#VAL{yyyy-MM-dd HH:mm:ss}";
VariableChart.DefaultView.ChartArea.AxisX.LabelRotationAngle = 270;
VariableChart.DefaultView.ChartArea.AxisX.Title = "Time";
VariableChart.DefaultView.ChartArea.AxisX.LayoutMode = AxisLayoutMode.Normal;
VariableChart.DefaultView.ChartArea.AxisX.AutoRange = true;
VariableChart.DefaultView.ChartArea.AxisX.IsDateTime = true;
}
private void CreateNewLine(object sender, RoutedEventArgs e)
{
CreateDataSerie();
if (VariableChart.DefaultView.ChartArea.DataSeries != null && VariableChart.DefaultView.ChartArea.DataSeries.Count == 1)
Timer.Start();
}
public void CreateDataSerie()
{
DataSeries dataSerie = new DataSeries();
dataSerie.Definition = new LineSeriesDefinition();
(dataSerie.Definition as LineSeriesDefinition).ShowPointMarks = false;
(dataSerie.Definition as LineSeriesDefinition).Appearance.PointMark.Shape = MarkerShape.Circle;
(dataSerie.Definition as LineSeriesDefinition).Appearance.PointMark.Fill = Brushes.Orange;
(dataSerie.Definition as LineSeriesDefinition).ShowItemLabels = false;
(dataSerie.Definition as LineSeriesDefinition).ShowItemToolTips = false;
var pointList = new ObservableCollection<DataPoint>();
var timerange = (DateTime.Now - _beginDate).TotalSeconds;
var periods = timerange/10;
for (int i = 0; i < periods; i++)
{
pointList.Add(new DataPoint(_beginDate.AddSeconds(i * 10).ToOADate(), _random.NextDouble()));
}
dataSerie.AddRange(pointList);
VariableChart.DefaultView.ChartArea.DataSeries.Add(dataSerie);
}
private void CreateNewScatter(object sender, RoutedEventArgs e)
{
CreateScatterDataSerie();
}
public void CreateScatterDataSerie()
{
DataSeries dataSerie = new DataSeries();
dataSerie.Definition = new ScatterSeriesDefinition();
(dataSerie.Definition as ScatterSeriesDefinition).Appearance.PointMark.Shape = MarkerShape.Circle;
(dataSerie.Definition as ScatterSeriesDefinition).Appearance.PointMark.Fill = Brushes.Orange;
(dataSerie.Definition as ScatterSeriesDefinition).ShowItemLabels = false;
(dataSerie.Definition as ScatterSeriesDefinition).ShowItemToolTips = false;
var pointList = new ObservableCollection<DataPoint>();
var timerange = (DateTime.Now - _beginDate).TotalSeconds;
var periods = timerange / 10;
for (int i = 0; i < periods; i++)
{
pointList.Add(new DataPoint(_beginDate.AddSeconds(i * 10).ToOADate(), _random.NextDouble()));
}
dataSerie.AddRange(pointList);
VariableChart.DefaultView.ChartArea.DataSeries.Add(dataSerie);
}
private void CreateNewSpliline(object sender, RoutedEventArgs e)
{
CreateSplineDataSerie();
}
public void CreateSplineDataSerie()
{
DataSeries dataSerie = new DataSeries();
dataSerie.Definition = new SplineSeriesDefinition();
(dataSerie.Definition as SplineSeriesDefinition).ShowPointMarks = false;
(dataSerie.Definition as SplineSeriesDefinition).Appearance.PointMark.Shape = MarkerShape.Circle;
(dataSerie.Definition as SplineSeriesDefinition).Appearance.PointMark.Fill = Brushes.Orange;
(dataSerie.Definition as SplineSeriesDefinition).ShowItemLabels = false;
(dataSerie.Definition as SplineSeriesDefinition).ShowItemToolTips = false;
var pointList = new ObservableCollection<DataPoint>();
var timerange = (DateTime.Now - _beginDate).TotalSeconds;
var periods = timerange / 10;
for (int i = 0; i < periods; i++)
{
pointList.Add(new DataPoint(_beginDate.AddSeconds(i * 10).ToOADate(), _random.NextDouble()));
}
dataSerie.AddRange(pointList);
VariableChart.DefaultView.ChartArea.DataSeries.Add(dataSerie);
}
}
}
Thank you!