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

RadDiagram Performance

9 Answers 428 Views
Diagram
This is a migrated thread and some comments may be shown as answers.
Tulio
Top achievements
Rank 1
Tulio asked on 15 Feb 2019, 10:36 PM

Hi,

 

Trying to see what can I change to improve performance for RadDiagram.

 

1- The goal is to show 2000+ hexagon.

2- Every hexagon has the same size, but it's color content might change. Every hexagon has a binding to a Viewmodel item.

3- Hexagons are grouped inside containers. The containers are pretty much transparent, except for its header.

4- There are no connectors and for now at least, users can't drag/delete/add items.

5- The diagram is contained inside a RadDocking and the docking is inside a regular WPF Tab.

When testing with 300 items there is a 4 second wait after the UI is loaded until the UI can be interacted with.

 

I am wondering, giving my scenario, what can I do to improve performance, giving that after loading the nodes don't change position/size.

 

 

 

9 Answers, 1 is accepted

Sort by
0
Dinko | Tech Support Engineer
Telerik team
answered on 20 Feb 2019, 12:18 PM
Hi Tulio,

You can take a look at the Tips and Tricks help article which describes a few things which you could try to increase the performance. The diagram control supports a UI virtualization which means that it will hide all items that are outside of the viewport. However, even then on load, the diagram will generate the layout slots (the containers) for all items, including those outside the viewport. In a scenario with 2000+ elements, this could be a quite slow operation. However, this comes from the rendering engine of the WPF framework and the diagram can't make much for improving the performance. We can think of a way to improve the virtualization process to avoid generating all containers, but at this point, we can't boost the load time of such a big amount of items.

Regards,
Dinko
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Tulio
Top achievements
Rank 1
answered on 21 Feb 2019, 01:34 AM

Hi Dinko,

 

I did take a look at that and I am already following all the recommendations that apply to us.

"We can think of a way to improve the virtualization process to avoid generating all containers".Is there something we could investigate for now?

 

Thanks!

0
Tulio
Top achievements
Rank 1
answered on 21 Feb 2019, 01:43 AM
Also, giving the static nature of the diagram and the absence of connectors, is there any other improvements we could make?
0
Petar Mladenov
Telerik team
answered on 21 Feb 2019, 02:48 PM
Hello Tulio,

We prepared a sample projects for you to test a scenario similar to yours. 500 shapes into container need about 1.2 to 1.6 seconds to load. Can you please check out the test projects and let us know for a possible differences between them and your scenario. 4 seconds seems a lot to us for for 300 shapes. as my colleague Dinko said, we are aware of performance issues with hundreds of items, however, with details from your side we could eventually identify and log areas for improvement in our Diagram Framework.

The MVVM projects uses ObservableGraphSource to bind the Diagram. We add 1 container shape and 500 shapes. If we add container and shapes separately into diagram the load time is about 1.3 seconds. The downside of this is that shapes are not draggable via container and they are not logical children of the container. However, in your scenario you might not need this - you may use the container only for visual grouping and no dragging. If you add the shapes into the container first, then add the container to the graphsource, the load time is about 1.6 seconds mainly because on load , on every child add container tries tor resize itself to fit the children.

We have also prepared a non-MVVM project in which shapes are directly added to diagram and no graphsource is used. Load time is about 1.2-1.3 seconds and there is no big difference if you add the shapes into diagram vs into container first. We will investigate this difference with MVVM separately.

I hope the projects will give you an idea for the difference in your scenario compared to the test one. Also, we will update you tomorrow with Diagram with Custom Shape. We will try to isolate visual parts of shapes not needed - Connectors Canvas, Editing TextBox. For this purpose - can you please elaborate all UI actions you need for your shapes - dragging, selection, editing, rotating, resizing, do you need text wrapping, do you need borders, strokes, stroke dash arrays. 

Thank you in advance for your cooperation.


Regards,
Petar Mladenov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Tulio
Top achievements
Rank 1
answered on 05 Mar 2019, 11:35 PM

Sorry for taking so long to reply!

 

We are not using any action on the shapes for now. We will draw them once, and they will change colors depending on internal events.

We are using transparent containers that contain a list of hexagons. The containers are displayed using autolayout, and the hexagons inside the containers are manually positioned.

 

We are not using connects, editing, draggin, text wrapping or anything of sorts.

 

Thanks, looking forward to your update.

0
Petar Mladenov
Telerik team
answered on 08 Mar 2019, 06:56 AM
Hello Tulio,

Since you don't need many of the shape's features, you can consider implementing custom shape which has simplified template. I added such shape in a sample project where 1000 hexagon shapes are loaded in Diagram for less than 1 second. I hope it will give you a basic idea of how to proceed on your side. We will soon have such example on SDK but it will be pretty much the same as the one attached here. Please note that the example uses no-xaml binaries which is generally faster than using xaml binaries. 

Let me know if you have any further questions.

Regards,
Petar Mladenov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Tulio
Top achievements
Rank 1
answered on 08 Mar 2019, 11:07 PM

Hi Petar,

 

Thanks a lot for the example. It works great using code-behind,but in order to have it working with xaml, I had to do a couple modifications to the project, which increase the time a bit. Is there something I could do for that?

 

Modifications i had to do

Custom Diagram:

public class CustomDiagram: Telerik.Windows.Controls.RadDiagram
    {
        private Geometry geometryShape =  Telerik.Windows.Controls.Diagrams.ShapeFactory.GetShapeGeometry(
            Telerik.Windows.Controls.Diagrams.CommonShapeType.HexagonShape);
        protected override bool IsItemItsOwnShapeContainerOverride(object item)
        {
            return item is CustomShape;
        }
 
        protected override Telerik.Windows.Diagrams.Core.IContainerShape GetShapeContainerForItemOverride(Telerik.Windows.Diagrams.Core.IContainerItem item)
        {
            return base.GetShapeContainerForItemOverride(item);
        }
 
        protected override Telerik.Windows.Diagrams.Core.IShape GetShapeContainerForItemOverride(object item)
        {
            if (item is Data data)
            {
                var shape = new CustomShape()
                {
                    Geometry= geometryShape,
                    Height = data.Height,
                    Width = data.Width,
                    Position = data.Position,
                    Content= data.Content
                };
                return shape;
            }
     
            return null;
        }
}

 

Xaml changes:

<Grid>
    <Grid.Resources>
        <Style TargetType="local:CustomShape" BasedOn="{StaticResource RadDiagramShapeStyle}"/>
    </Grid.Resources>
    <TextBlock VerticalAlignment="Top" HorizontalAlignment="Center" x:Name="infoBox" FontWeight="Bold" />
    <TextBlock x:Name="info2" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="20" FontWeight="Bold"/>
    <local:CustomDiagram  Margin="10 50 10 10" x:Name="diagram1" IsSnapToGridEnabled="False" IsSnapToItemsEnabled="False"
                                  GraphSource="{Binding Nodes}"
                                  Style="{StaticResource RadDiagramStyle}">
 
    </local:CustomDiagram>  
</Grid>

 

 

Adding nodes to VM:

private void LoadNodes()
       {
           int count = 0;
           for (int j = 0; j < 40; j++)
           {
               for (int i = 0; i < 50; i++)
               {
                   Data data = new Data()
                   {
                       Width = 40,
                       Height = 35,
                       Position = new Point(j * 60, i * 35),
                       Content = i,
                   };
                   m_viewModel.Nodes.AddNode(data);
                   count++;
               }
           }
           for (int k = 0; k < 40; k++)
           {
               for (int p = 0; p < 50; p++)
               {
                   Data data = new Data()
                   {
                       Width = 40,
                       Height = 35,
                       Position = new Point(30 + k * 60, 17 + p * 35),
                       Content = p,
                   };
                   m_viewModel.Nodes.AddNode(data);
                   count++;
               }
           }
           this.info2.Text = "Items: " + count;
       }

 

PS: I am also using no-xaml binaries.

0
Martin Ivanov
Telerik team
answered on 13 Mar 2019, 05:14 PM
Hello Tulio,

I've tested your code with Peter's solution, and indeed the performance is a bit slower. On my side less than a second (~600-800ms). This is expected since you include an additional level of abstraction which executes some more logic in the diagram and the WPF framework.

I've looked for a way to improve the performance in this case, and I was able to get the loading time down to ~3.3 sec, instead of the ~3.7 sec, which was my original loading time. This was done by overriding the AddNode() of the graph source class.
public override void AddNode(Data node)
{
    this.InternalItems.Add(node);
}

If you don't need to show content (like text) inside the hexagons, you can remove also the ContentPresenter and the parent Grids from the ControlTemplate of the CustomShape. This will leave only a single Path (for the geometry) in it. The loading time decreases with ~1 sec on my side after doing this. 
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="local:CustomShape">
            <Path x:Name="Geometry" Fill="{TemplateBinding Background}"                                     
                  Stretch="Fill" StrokeThickness="1" Stroke="#000000" 
                  Data="{TemplateBinding Geometry}"/>
        </ControlTemplate>
    </Setter.Value>
</Setter>

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Tulio
Top achievements
Rank 1
answered on 19 Mar 2019, 02:02 AM

That is fantastic.

 

I've also added events pre/post updating nodes to disable notification (which also helped improve the performance as well).

 

We will do another round of performance testing this week! Thanks!

Tags
Diagram
Asked by
Tulio
Top achievements
Rank 1
Answers by
Dinko | Tech Support Engineer
Telerik team
Tulio
Top achievements
Rank 1
Petar Mladenov
Telerik team
Martin Ivanov
Telerik team
Share this question
or