Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Performance loading + using diagram (Read 4577 times)
marie
Full Member
***
Offline



Posts: 147
Joined: Nov 11th, 2008
Performance loading + using diagram
Feb 6th, 2009 at 4:52pm
Print Post  
Hi Stoyan,

I have performance issues with my bigger diagrams.

My biggest has "only" 310 tableNodes, 40 containerNodes and many links.

A) Loading diagram from data (not using LoadFromXml at all):
-1- Adding ShapesNodes takes forever (minutes Sad). If I disable that, it makes a big difference. Each of my table has two shapesnodes attached. One of them changes when I click on it. The other one never changes, but might have to be hidden (the first one is used to fold my tableNode i.e. showing only the caption).
-1a- Can I manually paint the tableNodes?
-1b- Can I reuse the same ShapeNode or is there a way to make diagram.Factory.CreateShapeNode faster?
-2- RouteAllLinks is another bottle neck. I call it only once at the end of my loading, but it is taking a long time. How can I optimize it?
-3- this.diagram.add(myTableNode) is the 3rd bottleNeck. Is there any way to make it faster?
-4- You talked in other posts about not including the diagram in a view at loading time. The loading can occur after another diagram has been drawn (I then clear everything before adding my new elements). Can I unattach my diagram from its view and add it back after loading is done? Would it help? I don't need any painting done during the load. Only the final result matters.
-5- I am adding my nodes & links at the same time. Would it make a big difference to add all nodes first than rescan everything to add my links?

B) Every action done takes time. By example, selecting, moving or resizing a node is long. Folding a container took me 420secons (running profiler so it should be at least twice faster usually). It spent half the time calling DiagramNode.Resize and the other half calling Diagram.RouteAllLinks). How can I make my UI much faster?

C) How much speed gain could I expect? Now it can take up to 10 minutes loading that diagram (and I've got a good computer) and 15 seconds to 5 minutes doing a simple action after loading.

D) Any other ideas/suggestions?

Sorry for the many questions...

Thanks a lot!
Marie
« Last Edit: Feb 17th, 2009 at 5:15pm by marie »  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Performance loading + using diagram
Reply #1 - Feb 8th, 2009 at 9:56am
Print Post  
Hi Marie,

1) Have any auto-routed links been already created at the time you add shape nodes? In such case, adding a node could trigger the routing function for many links. As a rule of thumb, always create all diagram nodes before creating any auto-routed links. Additionally, for better performance later while the user is working interactively with the diagram, set Obstacle = false for the attached shape nodes. Obstacle nodes take some time to process when routing, even if they are placed inside larger obstacle nodes, such as your tables. If you are using undo/redo. enable it only after you finish loading the diagram. Otherwise, you might have thousands of undo/redo records created unnecessarily.

1a) Yes, you could set CustomDraw = Additional and draw some images from the DrawNode event handler, instead of using attached shape nodes.

1b) If you enable table custom-drawing but still need to draw some geometrical shape in the tables (as opposed to just calling DrawImage), you can indeed use a single ShapeNode: call the ShapeNode's Draw method from the DrawNode event handler raised for tables.

2) Having connected tables placed close to each other will improve the RouteAll performance a lot. E.g. you might run a few iterations of the Spring / Anneal / Grid layout classes to bring connected tables closer ,and call Routeall after that. You might also try using a bit larger RoutingOptions.GridSize.

3) Set Diagram.ValidityChecks = false. Try setting as much table-related default-value properties in the Diagram class as possible, and use the TableNode(diagram) constructor. Do that at least for the row and column count properties. Again, if you are using undo/redo, disable it during creation time.

4) You could temporarily set DiagramView.Diagram = new Diagram(), create the items in the now off-screen diagram, and only then assign it back to DiagramView.Diagram.

5) Yes, if RouteLinks / AutoRoute are enabled.

B. Is it your application calling RouteAllLinks, or the ContainerNode code? If the former, replace the RouteAllLinks call with a loop over Diagram.Links that calls the Route() methods only for links connected to nodes in the container, or having a Bounds that intersects with the container's Bounds. Using AutoRoute should do something of that kind, but it could slow bulk update operations a lot. So, if you are doing large updates on the diagram from some event handlers, it could be better to explicitly call Route() on the affected links after all node position changes are done, instead of relying on AutoRoute.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
marie
Full Member
***
Offline



Posts: 147
Joined: Nov 11th, 2008
Re: Performance loading + using diagram
Reply #2 - Feb 12th, 2009 at 1:57pm
Print Post  
Hi Stoyan,

I successfully increased the loading speed by using your tips and tricks. Thanks a lot! Grin

However, routing links is still quite long. I can't apply a layout like you suggested because the nodes can be placed anywhere by the user. So when I route links (when loading or while moving stuff around), it's ridiculously long (30 seconds to 2 minutes for 400 links only). Like you suggested, I'm calling Route only for needed links when I fold a container, however sometimes 40-50 links are concerned and it's still quite long. Also, at loading, all nodes need routing so I call link.Route() for all links in diagram.Links. Would
this solution you implemented help? Is there something else I can do?

Thanks,
Marie

p.s. This is my RouteAllLinks method
Code
Select All
foreach (DiagramLink link in this.diagram.Links)
{
    link.Route();
} 


and this is the code for a specific diagramNode
Code
Select All
foreach (DiagramLink link in this.diagram.Links)
{
    if (link.Origin == node || link.Destination == node || link.Intersects(node))
        link.Route();
} 

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Performance loading + using diagram
Reply #3 - Feb 12th, 2009 at 2:42pm
Print Post  
Nope, that finds graph-theoretic paths and not geometric ones Wink Email me your big diagram and our developer will try to find some better settings for routing the links.

Stoyan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Performance loading + using diagram
Reply #4 - Feb 12th, 2009 at 3:25pm
Print Post  
You might also consider using a timer and calling Route from the Tick event for only a handful of links at a time. You could start with links that are in the currently visible region of the diagram (that's view.ClientToDoc(view.ClientRectangle)).

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
marie
Full Member
***
Offline



Posts: 147
Joined: Nov 11th, 2008
Re: Performance loading + using diagram
Reply #5 - Feb 13th, 2009 at 7:53pm
Print Post  
Hi Stoyan,

I sent you a big diagram by email...

I could use the tick suggestion, but it doesn't solve my first RouteAll needed (just after loading) because all the graph is displayed at that time...

Thanks,
Marie
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Performance loading + using diagram
Reply #6 - Feb 17th, 2009 at 11:09am
Print Post  
Hi Marie,

Calling RouteAll on that diagram took 10 and a half minutes in our test, with all RoutingOptions values at their defaults.

Calling RouteAll after increasing the RoutingOptions.GridSize by 2.5 improved it to 1 minute, and the paths found still look good:

diagram.RoutingOptions.GridSize *= 2.5f;

Adding this line improved the time to 10 seconds:
diagram.RoutingOptions.DontOptimizeLongRoutes = true;

however it results in some weird staircase-like shape of long links.

I suppose you could implement something similar to progressive rendering in browsers: first run RouteAll with the above options to get a low quality representation of the diagram rendered quickly, next sort the links by their Length and Route() them from a timer event using the RoutingOptions that you prefer.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
marie
Full Member
***
Offline



Posts: 147
Joined: Nov 11th, 2008
Re: Performance loading + using diagram
Reply #7 - Feb 17th, 2009 at 5:15pm
Print Post  
Hi Stoyan,

It works great! For some reason, I don't even have the staircase-like links no matter if I don't optimize long routes Smiley.

Thanks a lot,
Marie
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint