Layouting Subgraphs

Dear Support,
I have implemented “layout subgraph” method from subgraphapp. I think it is working fine. But when I click layoutsubgraph button again and again it changes layout and my top level subgraph and inside subgraphs start increasing its size even though there is only one subgraphnode inside it. This is not the case in subgraphapp sample, in the app even if I press layout button again and again layout remains the same.
Could you please tell me what could be the reason behind this.
Thanks in advance.

I’m not sure. My guess is some margin is getting added in again each time. I’ve never seen this before, so I’m also guessing it’s something in your overrides. Turn your option choices off one at a time and see if the behavior goes away.

Thanks for the reply.
I will check the overrides the way you suggested that is keeping one option off at a time and observing the behavior.

Same problem is happening in the sample application you sent last time through mail. Actually I asked that question through mail. Could you please look at your end what is happening in that application. My application is also giving same result as that of the sample application you sent, on clicking the layout button again and again.

I have found what is causing problem. But do not know how to solve it.
In the layout method there is one method at the end which calls LayoutChildren(null) method. I have added my own labels in my subgraph using CreateMethod in MultiportSubgraph class. If I dissable the code which is adding label while initialising the subgraph. It works fine.

I want these labels in my subgraph. Could you please tell me what could be the problem with these labels. It is creating problem while layouting childrens. Size is increasing because of label is moving every time layout button is clicked.

if your label is called Label2. and your subgraph is called MySubGraph

these will help:

protected override  bool ComputeInsideMarginsSkip(GoObject child) {
  if (child == this.Label2)
    return !child.Visible;
  return base.ComputeInsideMarginsSkip(child)

}

protected override void CopyChildren(GoGroup newgroup, GoCopyDictionary env) {
  base.CopyChildren(newgroup, env);
  MySubGraph newsg = (GoSubGraph)newgroup;
   newgraph.myLabel2 = (GoText)env[obj];
}

I have already implemented added label into copychildren method. I also tried skipping true and false both for label2 in the method “computeinsidemarginskip”.
I also looked into layoutchildren method where I set the location of label2. But this method is called only when label2 is changed. Once I double click on the label2 in the diagram then only it go to the location I set in the layout children.
This additional label i.e. label2 is added by me while initialising the subgraph. I also set the label2.text and location in initialization. It only sets the label2.text but does not set the location while initializing because the location set by me in initialization is different than the label2 location on diagram
When I skip label2 while calculating inside margin. The graph inside the subgraph is properly arranged but label2 text goes down to right side when I press layout button again and again.
I think I missing something in my Label i.e. Label2 , which is there for already avaialbael label i.e. Label. Whenever layout method is called on pressing layoutbutton. It is setting position of label2 to different location. Due to which the size of graph is increasing.
One more thing I want to make this label (Label2) visible even after collapsing and want to set its location an the top of the node outside the subgraphrectangle (on collapsed condition)
I tried adding label in subgraph in samples as well. It is showing same result as that of myapplication and the sample you sent to me.
Did above changes you suggested make the sample you sent behave properly on repeatedly clicking layoutbutton.?

Hi,
I tried all the possible ways to avoid increasing size of subgraph after repeatedly clicking layout button.
It is causing because of extra added label in it. I want to keep this label it to appear even it is collapsed and want it to be positioned at top outside the rectangle of subgraph. I have already set the position in initialisation and layouting as well., still not working as required and causing problem while layouting.
Please help me to resolve the issue.
Thanks…

I didn’t actually test the code above, I just typed it in here.

If you can bundle up the project (complete and buildable) and send it to our support email address, I’ll see if I can sort it all out.

Ok. I will send the project which you sent last time. It is also has the same problem. If I remove extra label in the subgraph. It works fine. But if I add it extra label i.e. label2. It starts giving same problem. I will send the project of subgraph containing the problem.

You weren’t setting the location of label2 in LayoutChildren. I’ll send you the full module, but here are the basic changes…

in constructor:

  GoText t = CreateLabel();
  t.Visible = true;
  this.Add(t);    
  this.AddChildName("label2", t);

//public GoText t; // /this is the extra label <----- get rid of “t”

public virtual GoText Label2
{
  // use child names to avoid hassle with Copy
  get
  {
    return (GoText)this.FindChild("label2");
  }
}

public override void LayoutChildren(GoObject childchanged) {
  // implementations of LayoutChildren shouldn't do anything when Initializing is true
  if (this.Initializing) return;
  base.LayoutChildren(childchanged);

  LayoutLabel2();

  // don't call LayoutAllPorts when the child whose bounds were changed was a port
  if (childchanged == null || !this.MultiPorts.Contains(childchanged))
    LayoutAllPorts();


}

public virtual void LayoutLabel2() {
  GoText lab = this.Label2;
  if (lab == null)
    return;
  RectangleF rect;
  rect = ComputeInsideMargins(lab);
  PointF pt = GetRectangleSpotLocation(rect, BottomLeft);
  lab.Alignment = BottomLeft;
  lab.SetSpotLocation(TopLeft, pt);
}

Thank you very much for the reply.
It is working fine now.
I was setting location of label2 not like you set with separate method. I was setting the location in layout children (in my application, not in the code I sent to you) method referring variable t in my case. And that was working but only when i was editing label, It was getting at the location I set in layoutchildren method (fulfilling both purposes 1. getting rid of variable t. 2. stimulating label2 to call layoutchildren method) .
The code I put for setting location while initializing was not working properly. In the code above you have not set the location of label2 while initializing still it is taking the position at bottomleft corner as set in layoutchildren method. How is it calling layoutlabel2 method while initializing. You have not set label2 position in initialization still it is goingto layoutlabe2 method. How is it calling laoutlabel2 method? Is it because of this.AddChildName(“label2”, t) method?
Still not understanding what was i missing in it. I did set location in layouting and copychildren method without creating property “Label2” as you created and referring the gotext using string “label2”. I will look into it again.
One more thing, I want to make this label2 visible even in collapsed condition. I am using collapsedchild method (i.e. if (child is GoText) return;) to keep it visible even in collapsed condition. Is it right way to do it?

I put lot efforts to set the handle to left top corner in both collapsed and expanded condition. It was working fine(without moving subgraph on exapanding and collapsing). Though the code provided by you does not increase the size of the subgraph. It is causing subgraph to move on expanding and collapsing which was not happening before. I do not know why everything is so linked ???
Thank you very much.

The position gets set in LayoutChildren. AddChildName just gives Label2 a way to find it without a reference that has to be fixed up on a Copy.

prevent it’s collapse by doing this:

protected override void CollapseChild(GoObject child, RectangleF sgrect)
{
     **if (child == this.Label2) return;**
    if (child is IGoPort) return;  // don't "collapse" each port
    base.CollapseChild(child, sgrect);
}

I’m not seeing that in the code I sent back to you.

I have separate application where I set the handle at topleft corner. That method was not there in the project I sent to you. It was working fine on collapsing and expanding without moving subgraph and I could expand and collapse without moving mouse i.e. handle was at the same position on the screen. Thus I can just click on the same position to collapse and expand.
I am finding subgraph very difficult to use as compared to nodes in GoDiagram. It is difficult to follow user guide and online documentation. There are simple things which are obvious still can not get readily available in the subgraph. If I set the position of the handle on top-left corner it should not be changed in any case which is not happening. If somehow it sets the position to top-left corner then it starts moving and thus handle also changes the position on the screen. Which is not accepted behavior from user point of view.
I wanted to have subgraph with behaviours as that of colored node. In colored node, I can add ports on the node and remove and size of the node gets changed on addition and removal of the ports. But in subgraph it keep on adding ports in available space. It does not change the size of the subgraph(on both expanded and collapsed condition). In expanded position(as size already bigger due to interanal nodes in it) it looks better but when i collapse the subgraph it overlaps nodes. On collapsing it should increse the size to have better layouting of the ports. I tried to do it which resulted in changing layouting of the handle.

I’m not going to argue, there are things about GoSubGraph that aren’t easy to customize. That’s why our subgraph design has changed in GoXam and GoJS. We didn’t get it all right the first time.