This is a migrated thread and some comments may be shown as answers.

Performance issues with multiple DataSeries

1 Answer 113 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Javier
Top achievements
Rank 1
Javier asked on 04 Nov 2011, 02:35 PM

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 { getset; }
        
        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!

1 Answer, 1 is accepted

Sort by
0
Yavor
Telerik team
answered on 09 Nov 2011, 10:44 AM
Hello Javier,

You can try using data bound mode for your scenario. By doing this you will enable data sampling that will improve the performance of your chart. Further optimization steps can be to reduce the number of series, Y-axes and items visible at the same time on the chart. Take a look at Simple filtering example that allows the user to hide some of the series visible on the chart.

Best wishes,
Yavor
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
Chart
Asked by
Javier
Top achievements
Rank 1
Answers by
Yavor
Telerik team
Share this question
or