Drag and Scroll performance issues

4 posts, 0 answers
  1. Federico
    Federico avatar
    3 posts
    Member since:
    Jan 2017

    Posted 24 Jan Link to this post

    We are having a lot of performance issues while using RadDiagram.
    We have a main window that uses Diagram as a UserControl, in the first diagram the problems start when the number of shapes is above 20 as you can see in the video i attached. However in the second diagram the performance is even worse since whith just 12 shapes the scroll movement is terrible.
    I'm going to provide you as much information as i can, so we are using 2 textblocks and a textbox in our node template all of them use bindings to get the text, at first we thought about binding perfomance problems but it is still happening with regular text.
    Our shapes templates dont have a large visual tree, they are just a border with a few textblocks a button and background colors.
    We are using the last binary version from telerik and our class model is organized like this.
    • CustomDiagram inherits from RadDiagram
    • CustomShape inherits from RadDiagramShape
    • CustomConnection inherits from RadDiagramConnection
    However our own implementation of your controls is just a few methods or properties not a really huge overhaul.
    Is there any reason why a diagram whith just 42 shapes is working that bad?
    Below you can see examples of our code.
    <DataTemplate x:Key="Shape1">
            <Border BorderThickness="2" Height="120" Width="200" CornerRadius="4" SnapsToDevicePixels="True">
                <Border.Effect>
                    <DropShadowEffect BlurRadius="5" ShadowDepth="1" Direction="270" Color="#CCCCCC"/>
                </Border.Effect>
                <Border.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
                        <GradientStop Color="#D31027" Offset="0" />
                        <GradientStop Color="#EA384D" Offset="0.0" />
                    </LinearGradientBrush>
                </Border.Background>

                <Grid>
                    <StackPanel Orientation="Vertical">
                        <TextBlock Text="aa" FontFamily="Segoe UI Semilight" FontSize="30" Margin="4,5,6,-10" Foreground="White"></TextBlock>
                        <TextBlock Text="aa" FontFamily="Segoe UI Semilight" 

    Margin="5.3,5,6,5" FontSize="15">
                            <TextBlock.Foreground>
                                <SolidColorBrush Color="White" Opacity="0.5"/>
                            </TextBlock.Foreground>
                        </TextBlock>
                    </StackPanel>
                    <Button x:Name="product" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Style="{DynamicResource MetroCircleButtonStyle}" Panel.ZIndex="99" Background="#333333" Foreground="White" BorderBrush="#2E2E2E" Height="45" Width="45" Margin="146,61,5,10">
                        <Button.Content>
                            <iconPacks:PackIconModern Kind="Edit" />
                        </Button.Content>
                        <Button.Effect>
                            <DropShadowEffect BlurRadius="5" ShadowDepth="1" Direction="270" Color="#CCCCCC"/>
                        </Button.Effect>
                    </Button>
                    <Border Background="White" CornerRadius="0,0,3,3" Margin="0,86,0,0">
                    </Border>
                </Grid>
            </Border>
        </DataTemplate>
                             
            <Style TargetType="ModelShape:CustomShape">
            <Setter Property="Background" Value="Transparent"></Setter>
            <Setter Property="BorderBrush" Value="Transparent"></Setter>
            <Setter Property="IsEditable" Value="False"></Setter>
            <Setter Property="IsResizingEnabled" Value="False"></Setter>
            <Setter Property="IsRotationEnabled" Value="False"></Setter>
            <Setter Property="ContentTemplate" Value="{DynamicResource Shape1}"></Setter>
        </Style>

    We are also using your propertygrid control that loads the customshape properties everytime you click on it, we now know that everytime you click it it will update all of them on the property grid causing perfomance issues, its true that after disabling the property grid the performance is a little bit better but still not as good as expected.
    this is how we iterate through every shape property and only showing the ones we want
    private void CustomAutogeneratingProperty(object sender, AutoGeneratingPropertyDefinitionEventArgs e)
            {
                (e.PropertyDefinition.Binding as Binding).ValidatesOnDataErrors = true;

                (e.PropertyDefinition.Binding as Binding).NotifyOnValidationError = true;
                (e.PropertyDefinition.Binding as Binding).ValidatesOnExceptions = true;

                foreach (var prop in typeof(RadDiagramShape).
                    GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance).
                    Where(prop =>
                        (prop.Name.Equals(e.PropertyDefinition.AutoGeneratedPath))
                        || ((sender as CustomPropertyGrid).Item.GetType().Name.Equals(typeof(RadDiagramConnection).Name))))
                {
                    e.PropertyDefinition.Visibility = Visibility.Hidden;
                }
            }
    but as i said its still working awful.
    We had problems using containers so we are just using shapes instead.
    Our theory is that everytime you move a shape the diagram reloads all the properties, all of the bindings and maybe the ContentTemplate or maybe are issues about the draggin service not working well.
    We searched for information
    We are hoping you can help us in this scenario.
    If you need more information just let me know.

    PS: Our laptops have 16 Gb of ram and a nvidia gforce 750m there shouldnt be a problem with performance.

    https://www.dropbox.com/s/irw9ie0mlfqzb6n/as.mp4?dl=0

    https://www.dropbox.com/s/827orf58vxmbil2/PerformanceError.mp4?dl=0

  2. Shawn
    Shawn avatar
    48 posts
    Member since:
    Jul 2012

    Posted 26 Jan in reply to Federico Link to this post

    Federico,

    Just some quick observations:

    • Don't use the DropShadowEffect on your shapes/buttons. It tends to be a costly effect which directly impacts performance.
    • Avoid creating your LinearGradientBrush in your DataTemplate. Pull them out as a separate Style then reference it as a StaticResource
    • You should try and avoid setting all the styles in your DataTemplate, especially if they are not going to change. Create them as Resouces and reference them statically.
    • You are referencing DynamicResources in your template instead of using StaticResources. StaticResources are created once upon the XAML initialization whwere as the DynamicResources are created and resolved every time the control needs the resource.
    • For us, we found it was better to create Styles with ControlTemplates rather than using DataTemplates. You will need to then include a StyleSelector and ShapeSelector for the diagram. 
    • Make sure you are not performing operations on your OnPositionChanged for each shape. Those would be triggered constantly as you move the shape. If you are doing this, implement a timer to update only after the shape hasn't moved for an amount of time (500ms works for us)

    The RadDiagram is actually fairly fast but you have to use it properly. Our implementation of RadDiagram allows for 100's of shapes/containers and 500+ connections with acceptable performance. The attached image has 300 shapes and 460 connections. 

    Shawn

  3. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2980 posts

    Posted 27 Jan Link to this post

    Hello Federico,

    When shape is moved, the property which re-calculates is "Bounds", does it appear in your PropertyGrid ?
    We generally encourage you to profile your application which some kind of performance profiler (for example JustTrace) - it will give you better picture of expensive / low performing methods in application or in the diagram component. Also we would love to see an isolation of you scenario that we can investigate locally and suggest a possible performance improvements.

    Regards,
    Petar Mladenov
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  4. Federico
    Federico avatar
    3 posts
    Member since:
    Jan 2017

    Posted 27 Jan Link to this post

    Hello Shawn and Peter,

    We are going to follow all your tips and profile the application with JustTrace, after that we are going to give you the results.

    Thank you so much.

Back to Top