How to increase RadChart performance with thousands of Data Points?

17 posts, 1 answers
  1. Brian Allen
    Brian Allen avatar
    3 posts
    Member since:
    Jun 2009

    Posted 01 Feb 2010 Link to this post

    Hello, All.

    We are using RadChart version 2009.3.1322.35.

    The chart is declared in XAML and databound to an ObservableCollection of DataPoints.  The collection contains 9000 data points, which makes the chart take 1 minute to display.

    How can we improve the performance of the chart to accomodate thousands of data points?

    Best regards,
    Brian

    Note: we have already set ChartArea EnableAnimations to false.
  2. Answer
    Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 02 Feb 2010 Link to this post

    Hello Brian Allen,

    Here is a list of some simple changes that can improve the performance in large data scenarios like this one:

    • Use fewer data points -- typical performance guidance for Silverlight and WPF recommends capping the total number of UI elements in the low- to mid-hundreds. Given that each of the chart item instances instantiates around 3-5 UI elements, trying to render a chart with 1000 data points can start to bog the system down quite fast. Note that the Q1 2010 edition of RadChart will be able to handle hundred of thousands of data points thanks to its new Virtual Scrolling and Data Sampling mechanisms that are currently being developed.
    • Disable animations -- you have already done that.
    • Simplify the chart item control template -- e.g. the Line item template contains by default item label as well as point mark visual that can be removed (as they are relatively insignificant when rendering thousands of records); with lots of points the sheer number of UI elements simply bogs the system down as discussed above so if you cannot reduce the data points, you will need to simplify the chart item control template (note that simply changing their Visibility will not do the trick, they should be physically removed from the template).
    • Specify fixed axis range manually -- if your data changes a lot but you know the ranges over which it will vary, you can disable the Axis auto-range algorithm and specify the Axis range manually -- this will probably lower the processing time a bit.
    • Add the points more efficiently (ObservableCollection scenario) -- the control is built around a model where any changes to the data are automatically shown on the screen. This is accomplished by detecting classes that implement the INotifyPropertyChanged interface and collections that implement the INotifyCollectionChanged interface and registering to find out about changes as they occur. However, this system can be counterproductive in one scenario: starting with an empty collection and adding a bunch of data points all at once. By default, each new data point generates a change notification which prompts RadChart to re-analyze the data, re-compute the axis properties, re-layout the visuals, etc. It would be more efficient to add all the points at once and then send a single notification to the control that its data has changed. Unfortunately, the otherwise handy ObservableCollection class doesn't offer a good way of doing this but it is pretty easy to add:
    public class AddRangeObservableCollection<T> : ObservableCollection<T>
    {
        private bool suppressOnCollectionChanged;
     
        public void AddRange(IEnumerable<T> items)
        {
            if (items == null)
            {
                throw new ArgumentNullException("items");
            }
            if (items.Any())
            {
                try
                {
                    this.suppressOnCollectionChanged = true;
                    foreach (var item in items)
                    {
                        this.Add(item);
                    }
                }
                finally
                {
                    this.suppressOnCollectionChanged = false;
                    this.OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                }
            }
        }
     
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            if (!this.suppressOnCollectionChanged)
            {
                base.OnCollectionChanged(e);
            }
        }
    }


    Hope this helps.


    Sincerely yours,
    Manuel
    the Telerik team

    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
    Follow the status of features or bugs in PITS and vote for them to affect their priority.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Brian Allen
    Brian Allen avatar
    3 posts
    Member since:
    Jun 2009

    Posted 05 Feb 2010 Link to this post

    Hello, Manuel.

    Thank you very much for your fast and thorough response.

    We have come up with short-term and long-term solutions:

    In the short-term, we are plotting fewer points (under 500 points) and the RadChart [using default properties] performance is perfectly acceptable.

    In the long-term, we must plot up to 10,000 points.  So we are trying out your suggestions.  So far I've implemented your "Add the points more efficiently" recommendation and that has helped, but not enough.  My next steps are to implement your "Simplify the chart item control template" and "Specify fixed axis range manually".

    We are grateful for your fast, courteous and informative support.

    Best regards,
    Brian
  5. Ryan Overton
    Ryan Overton avatar
    12 posts
    Member since:
    Oct 2009

    Posted 01 Mar 2010 Link to this post

    Hello,
    I am currently using the beta version of Q1 2010, and love the scroll/zoom feature, but I am having a problem when plotting multiple lines. The performance appears to decrease quite a bit. I currently have 6 lines to display and have approx 1800 points per line. In the near future, I will have to ramp up the number of data points per line to approx. 86400 data points.  I have disabled all animations. Our current solution is to reduce the number of data points per line and that seems to speed up the process a little bit, but I would rather not have to do that if at all possible. Any suggestions?

    Thanks,
    Ryan Overton
  6. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 05 Mar 2010 Link to this post

    Hi Ryan,

    Generally, when populating the chart control with large number of data points you can achieve the best rendering performance if you enable the "Fast Line" mode of the Line series (i.e. set LineSeriesDefinition.ShowItemLabels, ShowPointMarks, and ShowToolTips properties to false -- this should grant you decent performance for 6 x 1800 items series even with the sampling mechanism disabled (RadChart.SamplingSettings.SamplingThreshold = 0).

    However, if you would like to display 6 x 90,000 items in RadChart, you will need to enable the new sampling as well (the sampling mechanism basically works much like SQL Server grouping and is able to downsample millions of records to the SamplingThreshold value -- i.e. with the default SamplingThreshold = 200, any number of records bound to a series is downsampled to 200 actual data points).

    Find attached a sample application as well.


    Regards,
    Manuel
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  7. Saravana Kumar
    Saravana Kumar avatar
    21 posts
    Member since:
    Jul 2006

    Posted 10 Jul 2010 Link to this post

    Hi Manuel,

    The sampling and performance of RadChart's ability to show thousands of data points in an intelligent way is great. The biggest problem for me is how to transfer this data from the server to client. In a real world scenario, this data is going to reside in a persistent store like database and a WCF service will help getting it.

    All the example's I've seen so far works with random data generation on the client side. How can I efficiently bring such a large volume of data from a WCF service.

    I believe the sampling only occurs on the client side after you have bound all the datapoints, series mapping to the chart.

    Many Thanks in Advance.

    Saravana. 
  8. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 14 Jul 2010 Link to this post

    Hi Saravana Kumar,

    Generally Silverlight is a client-side technology therefore all of the control logic (e.g. the built-in chart sampling and aggregation) can be executed only on the client-side. Basically if you would like to use the chart sampling feature, you will need to send all data through a WCF service and this will not be very efficient; alternatively you can try to group / aggregate your data on the SQL SERVER level (i.e. in this scenario you will not use chart sampling feature) and pass to the client only the actual data to display (versus sending all data).

    Here are some nice materials on WCF RIA to get you started:


    Greetings,
    Freddie
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  9. Steven Hillaert
    Steven Hillaert avatar
    18 posts
    Member since:
    May 2010

    Posted 26 Aug 2010 Link to this post

    Hi,

    Does the sampling also work when you create the DataSeries yourself (without SeriesMapping)?


    Thanks,
    Steven Hillaert
  10. Giuseppe
    Admin
    Giuseppe avatar
    2363 posts

    Posted 26 Aug 2010 Link to this post

    Hi Steven Hillaert,

    Data Sampling is only supported in databound scenarios.


    Regards,
    Freddie
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  11. Dirk Black
    Dirk Black avatar
    6 posts
    Member since:
    Nov 2009

    Posted 27 Aug 2010 Link to this post

    We are also utilizing thousand of data points.  But instead of starting with an empty collection and adding thousands of datapoints (we have the collection populated and bind once, which works fine), we need to update all the datapoints at the same time.

    Again, by default, each datapoint update generates a change notification and the RadChart re-analyses the data (which takes long, varying on the number of datapoints)
    We're trying to update the information more efficiently, similar to the example of adding points more efficiently:

    //observable collection implementation
    public class CustomObservableCollection<T> : ObservableCollection<T>
    {
              
        public void UpdateData()
        {   
                //manually force chart to update
                base.OnCollectionChanged( new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
        }
              
    }
      
      
    //data structure, INotifyPropertyChangedis also not implemented in the viewmodel.
    //Therefore no change reflects an update; we have control through CustomObservableCollection.UpdateData() to force and update
    //For the viewmodel, accessing the PointColor property (which is mapped in the xaml) calculates the value
    public class MyData 
    {
        public double XValue { get; set; }
        public double YValue { get; set; }
         
    }
      
      
    //multiple series implementation: collection of collection.
    private CustomObservableCollection<CustomObservableCollection<MyDataViewModel>> chartData = new CustomObservableCollection<CustomObservableCollection<MyDataViewModel>>();
      
    //Data binding once series-mappings have been completed, this takes about a second regardless of the volume of information
    public void BindData(BatchUpdateObservableCollection<BatchUpdateObservableCollection<MyDataViewModel>> pchartData)
    {
        chartData = pchartData;
        RadChartMain.ItemsSource = this.chartData;
    }
      
    //update code
    public void UpdateChart()
    {
        for (int series = 0; series < chartData.Count; series++)
        {                
            for (int datapoint = 0; datapoint < chartData[series].Count; datapoint++)
            {
                Random rnd = new Random(DateTime.Now.Second + series + datapoint);
                chartData[series][datapoint].MyData.YValue = rnd.Next(0, 100);
            }                
        }
          
        //call once to force the update
        chartData.UpdateData();
          
    }


    While this functions (update messages are now not sent automatically and we can force the RadChart to refresh once all the points are updated), the update process still takes the same time.  In comparason, the initial binding takes only a second.

    Is there something missing in our implementation causing the RadChart to re-analyze the data datapoint by datapoint?

  12. Vladimir Milev
    Admin
    Vladimir Milev avatar
    1061 posts

    Posted 01 Sep 2010 Link to this post

    Hi Dirk Black,

    While it is not explicitly clear what exactly what happens from the code pasted my advice to you would be to simply rebind the chart when you have large amount of changes to your data. However, if you are using an ObservableCollection as the data source and you update the data source collection this will cause RadChart to update itself on each change.

    The best way to batch update the chart would be to use a non ObservableCollection as source (or if you need to use such a collection, refrain from updating that instance) and simply generate a new updated collection and set the chart control ItemsSource to the new collection effectively swapping it with the old one.

    All the best,
    Vladimir Milev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  13. James
    James avatar
    1 posts
    Member since:
    Jan 2011

    Posted 17 Jan 2011 Link to this post

    We are using the RadChart (Q3 2010) control to display 5 data series, each with around 10000 points. The collection bound to the ItemsSource is an array of arrays. Once bound, the data does not change. Each series is made up of a smooth line, but with some outliers. It is essential that the outliers are visible, so we must use SamplingFunction.KeepExtremes. This has the effect of producing stepping artefacts in smooth sections of the series, so we must increase the SamplingThreshold to at least 2000 to compensate. All animations are disabled, as is showing item labels, tooltips and pointmarks; axes are given fixed ranges.

    We are finding that scrolling and zooming operations are very slow, taking around 5 seconds for a single scroll. Profiling the application while scrolling shows that the chart's Rebind() method is called on scrolling, which is taking up all of the time. Is there a way around this behaviour?
  14. Vladimir Milev
    Admin
    Vladimir Milev avatar
    1061 posts

    Posted 20 Jan 2011 Link to this post

    Hi Brian Allen,

    We are currently looking into this issue as described in your support ticket. We will have some information to you soon.

    All the best,
    Vladimir Milev
    the Telerik team
    Let us know about your Windows Phone 7 application built with RadControls and we will help you promote it. Learn more>>
  15. Jordan
    Jordan avatar
    3 posts
    Member since:
    May 2011

    Posted 29 Sep 2011 Link to this post

    Hi Manuel,

    In your answer you say to simplify the control template and take out the point & labels of the line series. I am having trouble extracting the Line template from Expression Blend. Can you please describe how to get the Line Control Template out in Expression Blend. The Bar one comes out easy enough, but not the Line (or Area).
  16. Bartholomeo Rocca
    Bartholomeo Rocca avatar
    247 posts
    Member since:
    May 2006

    Posted 04 Oct 2011 Link to this post

    Hello Jordan,

    With more recent versions of the control it is not necessary to manually simplify the control template in Blend. If you set all of the SeriesDefinition.ShowItemLabels, SeriesDefinition.ShowPointMarks, and SeriesDefinition.ShowItemToolTips properties to false, the labels and pointmarks will not be generated at all (and thus they will not be rendered as well).


    Greetings,
    Bart.
  17. शिल्पा
    शिल्पा avatar
    1 posts
    Member since:
    Feb 2016

    Posted 03 Feb in reply to Giuseppe Link to this post

    I have issue of rendering graph. if more than 8000 data points are coming then application getting hang for few sec. Can you please guide me on same?
  18. Martin
    Admin
    Martin avatar
    1099 posts

    Posted 05 Feb Link to this post

    Hi,

    You can take a look at the RadChart's Performance Tips and Tricks help article. However, I want to note that RadChart is the old charting component from the UI for WPF suite. The new RadChartView resolves many of the issues and limitations of RadChart. Also, it has better implementation and improved performance. Moreover, it is quite easy to set up and very flexible when it comes to customization. You can read more about the differences between the charts in the RadChart vs. RadChartView help article.

    I recommend you to check the new charting components and see if they work for you. Also, you can see the 5 Easy Steps Towards a Fast Chart blog post.

    Regards,
    Martin
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for WPF is Visual Studio 2017 Ready