Performance Tips and Tricks

When having scenarios with large sets of data, you can experience a lower RadChart performance. Here is a list with some simple changes that can improve the performance in large data scenarios:

  • 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 is able to handle hundred of thousands of data points thanks to its new Virtual Scrolling and Data Sampling mechanisms.

  • Disable animations - disabling animations can also boost the performance.

  • Turn off visibility of PointMarks and Labels for Self-Drawing(Continuous) Series - you will achieve fast series out-of-the-box.

  • Simplify the chart ControlTemplate - If you cannot reduce the number of data points, you will need to simplify the chart ControlTemplate. For example the Bar Template contains masks which can be removed (as their purpose is to beautify the control but this slows down the performance when you have many data points in series). You can extract the templates from your current version of our controls using Expression Blend as shown in our help topic Editing Control Templates in Expression Blend. Note that the ControlTemplate differs in versions older than Q2 2010.

  • 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 by 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 ); 
        } 
    } 
} 
Public Class AddRangeObservableCollection(Of T) 
    Inherits ObservableCollection(Of T) 
    Private suppressOnCollectionChanged As Boolean 
    Public Sub AddRange(items As IEnumerable(Of T)) 
        If items Is Nothing Then 
            Throw New ArgumentNullException("items") 
        End If 
        If items.Any() Then 
            Try 
                Me.suppressOnCollectionChanged = True 
                For Each item As Object In items 
                    Me.Add(item) 
                Next 
            Finally 
                Me.suppressOnCollectionChanged = False 
                Me.OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)) 
            End Try 
        End If 
    End Sub 
    Protected Overloads Overrides Sub OnCollectionChanged(e As NotifyCollectionChangedEventArgs) 
        If Not Me.suppressOnCollectionChanged Then 
            MyBase.OnCollectionChanged(e) 
        End If 
    End Sub 
End Class 

See Also

In this article