Tips and Tricks

RadDiagram API allows you to tweak your application for optimal performance. You should be familiar with the following performance and optimization tips:

Increase performance

  • Automation Peers: The automation peers can be turned off if they are not used. This can be done using the global AutomationMode property of the AutomationManager. You can check the UI Automation Support article on how to set the AutomationMode property to Disabled.

  • Virtualization: The virtualization of the RadDiagram is turned off by default. To turn it on the telerik:DiagramSurface.IsVirtualizing attached property needs to be set to True. The UI Virtualization of the RadDiagram will collapse all shapes which are outside of the diagram Viewport. More information can be found in the Virtualization help article.

  • Align and Snap: To optimize the dragging behavior, the aligning and snapping mechanism can be turned off. To disable them you can set the IsSnapToGridEnabled and IsSnapToItemsEnabled properties of the RadDiagram control to False.

  • Information adorner: The information adorner is constantly updated on drag. If it is not needed you can remove it. To disable it the IsInformationAdornerVisible property of the RadDiagram can be set to False.

  • Pan and Zoom animations: In case you don't need the animations while zooming or panning you can disable them. In order to turn them off, you can set the IsPanAnimationEnabled and IsZoomAnimationEnabled attached properties to False.

  • RadDiagramThumbnail: The RadDiagramThumbnail mechanism represent the current ViewPort of the RadDiagram. The Thumbnail is updated on every pan, zoom, position changed operation etc. In a case with a large number of items in the ViewPort, this could lead to a slow performance. In such scenarios, you can try avoiding using the RadDiagramThumbnail.

  • Disable Thumbnail from refreshing: By default RadDiagramThumbnail is refreshed on every UI operation performed into the RadDiagram. You can disable its auto refreshing mechanism and manually refresh it only when necessary. You can do that via the IsAutoRefreshEnabled property and the RefreshThumbnail() method.

  • Number of shapes in ViewPort: Work with a small number of shapes in the ViewPort. The smaller the number of shapes in the Viewport the faster diagram will be.

  • Clear the Diagram Cache: When an item (node) is removed from GraphSource, its corresponding UI container (RadDiagramShape) is stored in collection of 'recycled' shapes for future use. This aims to speed up the diagram performance in extensive undo-redo and container generation operations (loadin process). However, in a scenario where large number of Add/Remove operation are performed, the therecycled collection store in memory every operation which could lead to a possible memory issues. What can be done here is to manually clear this collection at some moment by calling the ClearCache() method.

Example 1: Clear the RadDiagram Cache

(this.xDiagram.ContainerGenerator as GenericContainerGenerator<Telerik.Windows.Controls.Diagrams.RadDiagramItem>).ClearCache(); 
  • Disable the segmentation service: It is reponsible for continually dividing the RadDiagram into segments in order to more easily retrieve "nearby" shapes for certain operations. Disabling this service should be considered and tested on a "per application" basis as it could increase the overall performance, but slow down specific scenarios such as creating a connection and snapping.

Example 2: Disabling the SegmentationService

public MainWindow() 
{ 
    InitializeComponent(); 
 
 
    this.xDiagram.ServiceLocator.Register<ISegmentationService>(new CustomSegmentationService(this.xDiagram)); 
} 
 
public class CustomSegmentationService : SegmentationService 
{ 
    public CustomSegmentationService(IGraphInternal graph) : base(graph) 
    { 
    } 
 
    public override bool IsSegmentationEnabled => false; 
} 

Optimize Layout

  • Layout and LayoutAsync: Choosing which method should be used depends on your custom scenario and requirements. A good practice is to first evaluate how the Layout() method works and then to move to the LayoutAsync() if needed. Generally speaking, the Layout() method should be faster because LayoutAsync() waits for LayoutUpdated events. Still, it depends on the concrete scenario.

  • Shapes Width and Height: To improve layout time, it is important the shapes ploted on the diagram to be with equal width and height. Layouting the diagram with different size of the shapes could lead to slower performance.

  • Suspend Connection Update: For better performance it is better to suspend the connection update before calling the Layout() method.

Example 3: Suspend connection update

this.xDiagram.Connections.ForEach(x => RadDiagramConnection.SetIsAutoUpdateSuppressed((RadDiagramConnection)x, true));  
this.xDiagram.Layout(LayoutType.Tree, settings); 
this.xDiagram.Connections.ForEach(x => RadDiagramConnection.SetIsAutoUpdateSuppressed((RadDiagramConnection)x, false)); 
this.xDiagram.Connections.ForEach(x => x.Update()); 
  • Simplify Shapes Template: In a scenario with a large number of shapes you can try to simplify the template of the shapes as much as possible. This way you can increase the initial load time. You can check the Create Custom Shape help article which desribes how you can create a custom shape. Example 2 demonstrate possible template.

Example 4: Simplify Shapes Template

<Style TargetType="{x:Type telerik:RadDiagramShape}"> 
    <Setter Property="Template"> 
        <Setter.Value> 
            <ControlTemplate TargetType="telerik:RadDiagramShape"> 
                <Grid Background="Orange"> 
                    <ContentPresenter Margin="{TemplateBinding Padding}" 
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> 
                </Grid> 
            </ControlTemplate> 
        </Setter.Value> 
    </Setter> 
</Style> 
  • Routing: The routing functionality of the diagram provides several algorithms (OrgTreeRouter, AStarRouter, InflatedRectRouter) which can be used to reduce the crossing of the connection. In some cases, one can be much faster than others. You can test your scenario with all of them and used the one which works best for your case.

Optimize Copy Paste

  • Disable Selection: Copying and pasting hundreds of shapes could lead to performance issues. This is because thousands of visual elements are added in a Canvas (every shape has borders, resizing / rotation thumbs, many other visuals in its control template). What you can do to optimize the process is to disable the selection behavior of the paste shapes. In order to do that you can create a custom class which derives from RadDiagram control and override the Paste() method. Then you can create a dummy boolean value which RadDiagram are going to use to handle the selection of the control in its PreviewSelectionChanged event handler.

Example 5: Suppress selection while pasting

public class CustomDiagram : RadDiagram 
{ 
    internal bool IsPasteInPrrogress { get; set; } 
    public override void Paste() 
    { 
       this.IsPasteInPrrogress = true; 
       base.Paste(); 
       this.IsPasteInPrrogress = false; 
    } 
} 
 
private void diagram_PreviewSelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
   if (this.diagram.IsPasteInPrrogress == true) 
   { 
       e.Handled = true; 
   } 
} 

Dynamic GraphSource Change

To use the diagram in a scenario with dynamic change of the graph source, you need to set the GraphSource property of the control in code behind. This allows you to make dynamic changes to the graph source. If you layout the diagram after the GraphSource change, you need to ensure that, e.g., layout roots are set correctly.

Example 6: Suppress selection while pasting

MainViewModel viewModel; 
public MainWindow() 
{ 
    InitializeComponent(); 
    this.viewModel = new MainViewModel(); 
    this.diagram.GraphSource = this.viewModel.GraphSource; 
} 
private void LayoutButtonClicked(object sender, RoutedEventArgs e) 
{          
    this.diagram.GraphSource = null; 
    this.diagram.GraphSource = this.viewModel.GraphSource; 
 
    // In a case you are using Diagram Layout 
    this.SetLayoutRoots(); // custom method to set again the roots 
    this.diagram.LayoutAsync(LayoutType.Tree, settings); 
} 

See Also

In this article