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

Chart ZoomScroll Performance Issue

9 Answers 143 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Shawn
Top achievements
Rank 1
Shawn asked on 31 Jan 2012, 10:51 PM
Hello,

I'm using a RadChart databound to an ObservableCollection that display three simultaneous lines. The ObservableCollection has points added to it at a rate of approximately 30 per second. This works great except for when I enable the ZoomScroll on the chart.

When the ZoomScroll (I've only tested the x-axis) is enabled, the application slows and becomes almost unresponsive. However as the application runs and the RadChart gains more and more points the application becomes more responsive.

I want to know if I'm doing something wrong or if there is some way to fix this issue.

I have mocked up an app that demonstrates this issue successfully. When you start the app the RadToggleButtons on the left hand side are practically unresponsive but you can get them to work with excessive clicking and a little luck. If you let it run for a while the buttons slowly become more responsive.

Here is the code:
XAML:
<UserControl x:Class="ZoomScrollTestApp.MainPage"
    mc:Ignorable="d"
    xmlns:ZoomScrollTestApp="clr-namespace:ZoomScrollTestApp"
    d:DesignHeight="300" d:DesignWidth="400">
 
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
 
        <Grid Visibility="Visible" Grid.Column="1">
            <Border x:Name="brdAcceleration">
                <telerik:RadChart x:Name="chartAcceleration" Tag="Acceleration" Margin="-5 2 0 0" >
                    <telerik:RadChart.DefaultView>
                        <telerik:ChartDefaultView ChartLegendPosition="Top">
                            <telerik:ChartDefaultView.ChartArea>
                                <telerik:ChartArea LegendName="legendAcceleration" EnableAnimations="False">
                                    <telerik:ChartArea.AxisX>
                                        <telerik:AxisX IsDateTime="True" DefaultLabelFormat="#VAL{HH:mm:ss}" AutoRange="True"/>
                                    </telerik:ChartArea.AxisX>
                                    <telerik:ChartArea.AxisY>
                                        <telerik:AxisY AutoRange="True" />
                                    </telerik:ChartArea.AxisY>
                                    <!--Remove Me!-->
                                    <telerik:ChartArea.ZoomScrollSettingsX>
                                        <telerik:ZoomScrollSettings ScrollMode="ScrollAndZoom" MinZoomRange=".005" />
                                    </telerik:ChartArea.ZoomScrollSettingsX>
                                </telerik:ChartArea>
                            </telerik:ChartDefaultView.ChartArea>
 
                            <telerik:ChartDefaultView.ChartLegend>
                                <telerik:ChartLegend x:Name="legendAcceleration" Header="Acceleration Test Chart" />
                            </telerik:ChartDefaultView.ChartLegend>
                            <telerik:ChartDefaultView.ChartTitle>
                                <telerik:ChartTitle />
                            </telerik:ChartDefaultView.ChartTitle>
                        </telerik:ChartDefaultView>
                    </telerik:RadChart.DefaultView>
 
                    <telerik:RadChart.SeriesMappings>
                        <telerik:SeriesMapping x:Name="seriesAccelerationX" LegendLabel="X">
                            <telerik:SeriesMapping.SeriesDefinition>
                                <telerik:LineSeriesDefinition ShowItemLabels="False" ShowPointMarks="False"/>
                            </telerik:SeriesMapping.SeriesDefinition>
                            <telerik:ItemMapping FieldName="X" DataPointMember="YValue"/>
                            <telerik:ItemMapping FieldName="Date" DataPointMember="XValue"/>
                        </telerik:SeriesMapping>
                        <telerik:SeriesMapping x:Name="seriesAccelerationY" LegendLabel="Y">
                            <telerik:SeriesMapping.SeriesDefinition>
                                <telerik:LineSeriesDefinition ShowItemLabels="False" ShowPointMarks="False" />
                            </telerik:SeriesMapping.SeriesDefinition>
                            <telerik:ItemMapping FieldName="Y" DataPointMember="YValue"/>
                            <telerik:ItemMapping FieldName="Date" DataPointMember="XValue"/>
                        </telerik:SeriesMapping>
                        <telerik:SeriesMapping x:Name="seriesAccelerationZ" LegendLabel="Z">
                            <telerik:SeriesMapping.SeriesDefinition>
                                <telerik:LineSeriesDefinition ShowItemLabels="False" ShowPointMarks="False" />
                            </telerik:SeriesMapping.SeriesDefinition>
                            <telerik:ItemMapping FieldName="Z" DataPointMember="YValue"/>
                            <telerik:ItemMapping FieldName="Date" DataPointMember="XValue"/>
                        </telerik:SeriesMapping>
                    </telerik:RadChart.SeriesMappings>
                </telerik:RadChart>
            </Border>
        </Grid>
    <Border BorderThickness="1" BorderBrush="#22000000" Background="#66FFFFFF" Grid.Column="0" CornerRadius="6" VerticalAlignment="Top">
        <StackPanel x:Name="spButtons" Orientation="Vertical" Margin="5">
                <telerik:RadRadioButton x:Name="btn1" Content="btn1" Margin="0 5" IsChecked="True" />
                <telerik:RadRadioButton x:Name="btn2" Content="btn2" />
                <telerik:RadRadioButton x:Name="btn3" Content="btn3" Margin="0 5" />
                <telerik:RadRadioButton x:Name="btn4" Content="btn4" />
        </StackPanel>
    </Border>
    </Grid>
</UserControl>

Code Behind:
using System;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Collections.ObjectModel;
 
namespace ZoomScrollTestApp
{
    public partial class MainPage : UserControl
    {
        DispatcherTimer timer = new DispatcherTimer();
        private ObservableCollection<AccelerationChartValue> AccelChartPoints = new ObservableCollection<AccelerationChartValue>();
 
        private double[] SineBuffer = new double[200];
        private double[] SquareBuffer = new double[200];
        private double[] SawBuffer = new double[200];
 
        public MainPage()
        {
            InitializeComponent();
            this.chartAcceleration.ItemsSource = AccelChartPoints;
 
            GenerateSine();
            GenerateSquare();
            GenerateSawtooth();
 
            timer.Interval = TimeSpan.FromMilliseconds(33); // Approx 30 additions per second
            timer.Tick += new EventHandler(AddPoint);
            this.timer.Start();
        }
 
        private void GenerateSine()
        {
            int NumSamples = 200;
            double Frequency = 2;
            double SampleRate = 50;
 
            int SamplesPerWave = (int)(SampleRate / Frequency);
            double RadPerSample = (Math.PI * 2) / (double)SamplesPerWave;
            double SinVal = 0;
 
            for (int i = 0; i < NumSamples; i++)
            {
                SinVal = Math.Sin(RadPerSample * (double)(i % SamplesPerWave));
                SineBuffer[i] = (Math.Floor(SinVal * 127) + 128);
            }
        }
 
        private void GenerateSquare()
        {
            int NumSamples = 200;
            double Frequency = 2;
            double SampleRate = 50;
 
            int SamplesPerWave = (int)(SampleRate / (Frequency * 2));
 
            int Value = 127;
            int Counter = 0;
            for (int i = 0; i < NumSamples; i++)
            {
                if (Counter >= SamplesPerWave)
                {
                    Counter = 0;
                    Value *= -1;
                }
                SquareBuffer[i] = Value + 127;
                Counter++;
            }
        }
 
        private void GenerateSawtooth()
        {
            int NumSamples = 200;
            double Frequency = 2;
            double SampleRate = 50;
 
            int SamplesPerWave = (int)(SampleRate / Frequency);
 
            int Value = 0;
            int Counter = 0;
            double Delta = 255.0 / (double)SamplesPerWave;
            for (int i = 0; i < NumSamples; i++)
            {
                if (Counter >= SamplesPerWave)
                {
                    Counter = 0;
                    Value = 0;
                }
                else
                {
                    Value += (int)Math.Round(Delta, 0);
                    if (Value > 255)
                    {
                        Value = 255;
                    }
                }
                SawBuffer[i] = Value;
                Counter++;
            }
        }
 
        private void AddPoint(object sender, EventArgs args)
        {
            AccelChartPoints.Add(new AccelerationChartValue() { Date = DateTime.Now, X = SineBuffer[AccelChartPoints.Count % 200], Y = SquareBuffer[AccelChartPoints.Count % 200], Z = SawBuffer[AccelChartPoints.Count % 200] });
        }
    }
}


AccelerationChartValue.cs:
using System;
 
namespace ZoomScrollTestApp
{
    public class AccelerationChartValue
    {
        public double X { get; set; }
        public double Y { get; set; }
        public double Z { get; set; }
 
        public DateTime Date { get; set; }
    }
}

Thanks in advance for you help,
Shawn

9 Answers, 1 is accepted

Sort by
0
Nikolay
Telerik team
answered on 03 Feb 2012, 10:04 AM
Hello Shawn,

There are a number of performance tips in this help topic, one of the main being setting manual axes ranges wherever possible in such scenarios, instead of using the autorange.

In case you are still in the process of selecting the most suitable component, we would highly recommend using our new RadChartView control for live data scenarios like yours, as it is specifically optimized with performance in mind and would handle large data much faster than RadChart. You can find an example of a live data scenario in our demo.

Regards,
Nikolay
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Shawn
Top achievements
Rank 1
answered on 09 Feb 2012, 05:14 PM
Nikolay,

Thanks for your response. If I were to change to the RadChartView control for the live data would I preserve the ability to zoom in on a selected data range as I do now? This is necessary for my project.

Shawn
0
Nikolay
Telerik team
answered on 13 Feb 2012, 08:20 AM
Hello Shawn,

Yes, RadChartView supports zooming and scrolling using the ChartPanAndZoomBehavior class. You can find more information on the feature in this help topic.

All the best,
Nikolay
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Shawn
Top achievements
Rank 1
answered on 14 Feb 2012, 09:30 PM
Hello again Nikolay,
Thank you again for your explanation. I have been able to get it working much better with the RadChartView but I ran into an issue. With the RadChart I was able to get and set the RangeEnd, RangeStart, SliderSelectionEnd, and SliderSelectionStart from the ZoomScrollSettings. Is there any way to get and set the equivalent values for the RadChartView?

Thanks,
Shawn
0
Nikolay
Telerik team
answered on 17 Feb 2012, 10:18 AM
Hi Shawn,

The respective properties are RadCartesianChart.Zoom and RadCartesianChart.PanOffset. Here is a sample snippet that demonstrates this : 
<telerik:RadCartesianChart x:Name="RadChart1" Width="800" Height="600" Zoom="10,1" PanOffset="-1000,0"/>

The offset should be provided in negative absolute values. In the above snippet the chart would be offset horizontally at 1000px with a horizontal Zoom level of 10, while not being zoomed vertically. 

Kind regards,
Nikolay
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Shawn
Top achievements
Rank 1
answered on 23 Feb 2012, 06:11 PM
Nikolay,
Thanks again for your help.

I have another question: I noticed the scroll bar for the RadChartView isn't as pretty as the scroll bar for the RadChart and its functionality is as good either. What I mean is often times when trying to scroll or widen the view the scroll bar loses focus and I end up zooming in on the graph using the selection range. Is there any way to fix this?
0
Nikolay
Telerik team
answered on 28 Feb 2012, 11:11 AM
Hi Shawn,

The scroll bar for both chart controls is exactly the same as functionality, it's only the styling that is different - it's more metro for RadChartView. Could you, please, elaborate a bit more on the focusing issue you've encountered as we're not aware of such a problem. We would appreciate any feedback and/or a sample application which demonstrates the issue so that we can test locally.

Greetings,
Nikolay
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
Shawn
Top achievements
Rank 1
answered on 29 Feb 2012, 08:36 PM
Using the project code I gave previously if you replace the "chartAcceleration" with this code snippet:

<chart:RadCartesianChart x:Name="cartChartAccel" Grid.Column="1" >
    <chartView:LineSeries CategoryBinding="Date" ValueBinding="X" Stroke="Blue" StrokeThickness="2"/>
    <chartView:LineSeries CategoryBinding="Date" ValueBinding="Y" Stroke="Green" StrokeThickness="2"/>
    <chartView:LineSeries CategoryBinding="Date" ValueBinding="Z" Stroke="Red" StrokeThickness="2"/>
    
    <chart:RadCartesianChart.Behaviors>
        <telerik:ChartPanAndZoomBehavior x:Name="AccelChartZoom" ZoomMode="Horizontal" PanMode="Horizontal"/>
    </chart:RadCartesianChart.Behaviors>
     
    <chart:RadCartesianChart.HorizontalAxis>
        <chartView:DateTimeContinuousAxis MajorStepUnit="Hour"
                                        LabelInterval="5"
                                        LabelFormat="HH:mm:ss.f" FontFamily="Segoe UI"
                                        PlotMode="OnTicks" />
    </chart:RadCartesianChart.HorizontalAxis>
 
    <chart:RadCartesianChart.VerticalAxis>
        <chartView:LinearAxis FontFamily="Segoe UI" />
    </chart:RadCartesianChart.VerticalAxis>
    <chart:RadCartesianChart.Grid>
        <chartView:CartesianChartGrid MajorLinesVisibility="Y" MajorYLineDashArray="3,4" />
    </chart:RadCartesianChart.Grid>
</chart:RadCartesianChart>
and replace "this.chartAcceleration.ItemsSource = AccelChartPoints;" with the following snippet in the MainPage constructor:

cartChartAccel.Series[0].ItemsSource = this.AccelChartPoints;
cartChartAccel.Series[1].ItemsSource = this.AccelChartPoints;
cartChartAccel.Series[2].ItemsSource = this.AccelChartPoints;

Wait for about 30 seconds. and try to use the scroll bar in various ways. When I do this i experience some serious issues with scrolling and zooming.
0
Ves
Telerik team
answered on 05 Mar 2012, 03:11 PM
Hi Shawn,

Thank you for the additional details. I can confirm that we were able to reproduce the problem. I have logged it in our public issue tracking system -- link -- so you can track it and vote for it. I have updated your Telerik points.

Best regards,
Ves
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Tags
Chart
Asked by
Shawn
Top achievements
Rank 1
Answers by
Nikolay
Telerik team
Shawn
Top achievements
Rank 1
Ves
Telerik team
Share this question
or