100% CPU usage when moving groups

Hello

I encountered a problem when moving collapsed groups in realtime (GoView.DragsRealtime is set to true).

Suppose I make 500 nodes in SubGraphApp sample application and group all of them together.
When moving the collapsed group, 100% of CPU is used and the move is intrerupted from time to time.
In my opinion this should not hapen as on the screen, a single object seems to move (the object representing the collapsed group) and this does not justify 100% CPU usage.

As an additional information, my computer has a 1.8Ghz processor.

Do anybody have any sugestion for improving the performance in the above situation?

Any help would be much appreciated.


Best Regards

Liviu

Well, you could certainly set DragsRealtime to false.
I suspect a significant part of the overhead is due to recording all the bounds changes for undo/redo.

We have to leave DragsRealtime = true



I’ve made

goView1.Document.UndoManager = null



After this modification no visible improvement occured. So I suspect the undo/redo is not the reason for our problem.



Do you have any other sugestion to improve the behaviour here?





Thanks







Liviu





Ah, well, I wonder if you can get away with overriding MoveChildren to be a no-op if the subgraph is collapsed. The problem is that I don’t know about making sure all link strokes are recalculated, for those outside links that are connected to ports inside your subgraph. Since you implied in an earlier post that you are having all of the external links use the CollapsedObject as the PortObject when the subgraph is collapsed, perhaps you just need to override MoveChildren to iterate over all of the external links and call CalculateStroke on them, and without calling the base MoveChildren method.
I haven’t tried this, so I have no idea if this will work.
Hmmm, not moving the child nodes might cause the Border not to be drawn correctly. You might need to use version 2.3 for this experiment, since only v2.3 (now in beta) supports having the bordered area be independent of the Bounds. Then again, since you are using a CollapsedObject, perhaps having the Bounds not be what you would expect won’t matter.

This seems to work well–except I haven’t tested this when all external links connect to ports whose GoPort.PortObject property refers to the GoSubGraph.CollapsedObject.
protected override void MoveChildren(RectangleF prevRect) {
if (this.IsExpanded) {
base.MoveChildren(prevRect);
} else {
float dX = this.Left - prevRect.X;
float dY = this.Top - prevRect.Y;
GoObject x = this.Handle;
if (x != null) {
RectangleF r = x.Bounds;
x.Bounds = new RectangleF(r.X + dX, r.Y + dY, r.Width, r.Height);
}
x = this.Label;
if (x != null) {
RectangleF r = x.Bounds;
x.Bounds = new RectangleF(r.X + dX, r.Y + dY, r.Width, r.Height);
}
x = this.Port;
if (x != null) {
RectangleF r = x.Bounds;
x.Bounds = new RectangleF(r.X + dX, r.Y + dY, r.Width, r.Height);
}
x = this.CollapsedObject;
if (x != null) {
RectangleF r = x.Bounds;
x.Bounds = new RectangleF(r.X + dX, r.Y + dY, r.Width, r.Height);
}
foreach (IGoLink link in this.ExternalLinks) {
GoLink l = link as GoLink;
if (l == null) {
GoLabeledLink ll = link as GoLabeledLink;
if (ll != null) l = ll.RealLink;
}
if (l != null) l.CalculateStroke();
}
}
}

Hello again

I’ve tested the above code and it works as expected.

Anyway, as a related problem, when we have hundreds of external links between a single GoObject and the collapsed group, the same problem still occurs. The collapsed group moves slowly and also the GoObject moves slowly so this is related to the fact that there are many links involved.

As a solution, I think it would be a good ideea to make the links between the GoObject and the group not visible. The links will be made not visible when collapsing the group and they will be restored when the group is expanded. When collapsed I will create a single link between the GoObject and the collapsed group just to create the impresion the GoObject and the collapsed group are linked with eachother.

Can you tell me if you see any problems with this approach. Do you have any other sugestions regarding this?


Thanks in advance


Liviu


That sounds like a reasonable approach. Certainly that will save time drawing all those links. However, there would still be a lot of calls to GoLink.CalculateStroke, which might be time-intensive. You might want to override that method to be a no-op when CanView() is false.

Good point.



Thanks



Liviu

Hello!

<?:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

We got exactly same issue with moving collapsed group which contains hundreds of inner nodes. The current version we using is GoDiagram Win 2.2.1 for Win-.Net.

Based on SubGraphApp sample, we developed a small application as our test.

We have tried some steps which you guys mentioned above.

  1. Set GoView.DragsRealtime to FALSE

The difference between setting DragsRealtime to TRUE is the collapsed group becomes faster, but related links are slower as before. If setting back DragsRealtime to TRUE, the collapsed group is moved with all links together at same time.

  1. We have realized that we have not called GoLink.CalculateStroke in our small application, But we did use this function in our project because it gives us good link shapes.

  1. Testing override MoveChildren function.

When we moving one collapsed group, the subGraph was been moved, but all related links are not been moved. Even make all the links moved, the performance issue is not solved.

We wonder whether Walter¡¯s the latest suggestion solves Vasilegrafu¡¯s issue. Could someone give us more specific method or coding for this kind of issue here?

Cheers.

I believe the performance problem was due to having hundreds of links recalculate their stroke in real time while dragging in real time.
There’s no way to avoid that problem when the subgraph is expanded, since presumably most of those links go to different places inside the subgraph, so all of the links need to have their stroke recalculated.
But when the subgraph is collapsed all of the external links connecting to invisible subgraph children could be made invisible, and a single link could be made visible between the collapsed subgraph port and each outside node. Perhaps these “cables” or “coalesced links”, representing all of the links connecting the subgraph to each node, could be drawn with a thick pen and/or distinctive color. Changing the visibility of these external links could be done in an override of GoSubGraph.Collapse(), after calling the base method. But remember to leave (or make) Visible those “cable” links that are connected to the GoSubGraph.Port.
public override void Collapse() { // we’re not modifying the subgraph
base.Collapse();
foreach (IGoLink link in this.ExternalLinks) {
link.GoObject.Visible = (link.FromPort == this.Port || link.ToPort == this.Port);
}
}


Then by overriding GoLink.CalculateStroke() to be a no-op when GoObject.Visible is false, there would be much less overhead involved as the invisible subgraph children are moved, or as an external node is moved.
public override void CalculateStroke() {
if (CanView()) base.CalculateStroke();
}


The override of GoSubGraph.Expand, after calling the base method, could make those external links visible again.