Page Index Toggle Pages: 1 Send TopicPrint
Hot Topic (More than 10 Replies) DiagramLayout messedup (Read 4631 times)
henry k
Junior Member
**
Offline


I Love MindFusion!

Posts: 51
Location: Finland
Joined: Apr 4th, 2012
DiagramLayout messedup
Apr 27th, 2012 at 1:04pm
Print Post  
Once again I'm facing a issue with diagrams layeredLayout.

Images below describes the situation...
(What it needs to look like and what it looks like after layeredLayout arranged it)

basically what i do on the code side is (layer = depth of loop):
#1 Loop first "layer" of nodes in diagram
#2 find first/next containerNode if any
#3 loop the containerNodes content and goto #2
#4 if there are no containers found, arrange the nodes that is shown in this "layer"
#5 fall back on each layer and repeat #4
#6 arrange the root "layer" on the diagram
# done

In other words... recursive loop of nodes and containerNodes within diagram.

Br. Henry
  

diagramLayout_NeedToBe.png (Attachment deleted)
diagramLayout_Result.png (Attachment deleted)
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramLayout messedup
Reply #1 - Apr 30th, 2012 at 6:56am
Print Post  
This layered approach has the drawback of not matching the layout of inner layers with layout of outer layers, so you get crossing links. You will need to use some additional sorting as shown in http://mindfusion.eu/Forum/YaBB.pl?num=1330644188. Also LayeredLayout won't place connected nodes at the same vertical position. You might try setting IgnoreLayout on some links to allow for the nodes they connect to be placed on the same Y layer.

Stoyan
  
Back to top
 
IP Logged
 
henry k
Junior Member
**
Offline


I Love MindFusion!

Posts: 51
Location: Finland
Joined: Apr 4th, 2012
Re: DiagramLayout messedup
Reply #2 - Apr 30th, 2012 at 8:40am
Print Post  
Stoyo wrote on Apr 30th, 2012 at 6:56am:
This layered approach has the drawback of not matching the layout of inner layers with layout of outer layers, so you get crossing links. You will need to use some additional sorting as shown in http://mindfusion.eu/Forum/YaBB.pl?num=1330644188. Also LayeredLayout won't place connected nodes at the same vertical position. You might try setting IgnoreLayout on some links to allow for the nodes they connect to be placed on the same Y layer.

Stoyan


I am very sorry, but I didn't quite understand.  Embarrassed Embarrassed Embarrassed

Could you please make a example of this scenario? As I tried to use same methods as described behind your link, but the layout went from bad to worse.

I'm very sorry, but if it would be possible I'd appreciate if you could spare a moment to type example for me (and possible for others that may be seeking same kind of solution).

Br. Henry
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramLayout messedup
Reply #3 - May 2nd, 2012 at 10:21am
Print Post  
The code below creates this layout:



Code
Select All
LayeredLayout outerLayout = new LayeredLayout();
outerLayout.Orientation = MindFusion.Diagramming.Layout.Orientation.Vertical;
outerLayout.StraightenLongLinks = true;
outerLayout.IgnoreNodeSize = false;
outerLayout.Anchoring = Anchoring.Reassign;

LayeredLayout innerLayout = new LayeredLayout();
innerLayout.Orientation = MindFusion.Diagramming.Layout.Orientation.Horizontal;
innerLayout.StraightenLongLinks = true;
innerLayout.Anchoring = Anchoring.Reassign;

Arrange(diagram, outerLayout, innerLayout);
SortByIncomingLinks();
outerLayout.Arrange(diagram);

void SortByIncomingLinks()
{
	foreach (DiagramNode node in diagram.Nodes)
	{
		ContainerNode ctr = node as ContainerNode;
		if (ctr != null)
		{
			SortByIncomingLinks(ctr);
			ctr.UpdateBounds();
		}
	}
}

void SortByIncomingLinks(ContainerNode ctr)
{
	List<DiagramNode> children = new List<DiagramNode>();
	foreach (DiagramNode node in ctr.SubordinateGroup.AttachedNodes)
		children.Add(node);
	children.Sort(CompareByInLinks);

	float x = ctr.Bounds.X + 15;
	foreach (DiagramNode node in children)
	{
		node.Move(x, node.Bounds.Y);
		x = node.Bounds.Right + 15;
	}

	foreach (DiagramNode node in children)
		foreach (DiagramLink link in node.GetAllLinks())
			link.ReassignAnchorPoints();
}

int CompareByInLinks(DiagramNode n1, DiagramNode n2)
{
	DiagramLink link1 = null;
	if (n1.IncomingLinks.Count > 0)
		link1 = n1.IncomingLinks[0];
	DiagramLink link2 = null;
	if (n2.IncomingLinks.Count > 0)
		link2 = n2.IncomingLinks[0];

	if (link1 != null && link2 == null)
		return -1;
	if (link1 == null && link2 != null)
		return 1;
	if (link1 == null && link2 == null)
		return 0;

	PointF p1 = link1.ControlPoints[link1.ControlPoints.Count - 2];
	PointF p2 = link2.ControlPoints[link2.ControlPoints.Count - 2];
	return p1.X.CompareTo(p2.X);
} 



The difference from the old code is that SortByIncomingLinks previously did not process links between nodes inside the container, and now it calls ReassignAnchorPoints to align them to nodes after sorting. However if you expect links both inside the container and ones coming form the outside, you will probably have to modify the sort criteria to compare by both. Another change is the second call to outerLayout.Arrange for rearranging the outer diagram with the new containers sizes.

Setting IgnoreLayout on the bottommost link did not work here as I thought because LayeredLayout strives to preserve link flow direction and places the nodes on different sides of the container (so the flow is node5 -> container -> node4 when node4->node5 link is ignored). You would get the result from your screenshot if the node5 -> container link was reversed. If you can't ensure links flow direction, you might try using a different outer layout, e.g. try AnnealLayout - it will make links as short as possible so node4&5 should be on the same side of container, but it will not align nodes horizontally.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
henry k
Junior Member
**
Offline


I Love MindFusion!

Posts: 51
Location: Finland
Joined: Apr 4th, 2012
Re: DiagramLayout messedup
Reply #4 - May 2nd, 2012 at 10:44am
Print Post  
where does this { Arrange(diagram, outerLayout, innerLayout); } comes from? (the Arrange -function)
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramLayout messedup
Reply #5 - May 2nd, 2012 at 10:55am
Print Post  
You can find several versions of it by searching the forum. Here's what I have currently in my test app:

Code
Select All
private DiagramItemCollection GetContainerItems(ContainerNode container)
{
	DiagramItemCollection items = new DiagramItemCollection();
	foreach (DiagramNode node in container.SubordinateGroup.AttachedNodes)
	{
		items.Add(node);
		foreach (DiagramLink link in node.GetAllLinks())
		{
			DiagramNode node2 = GetOtherEnd(link, node);
			if (ContainerNode.GetContainer(node2) == container && !items.Contains(link))
				items.Add(link);
		}
	}
	return items;
}

private void ArrangeContainers(ContainerNode parent, Layout layout)
{
	DiagramItemCollection children = GetContainerItems(parent);
	foreach (DiagramItem child in children)
	{
		if (child is ContainerNode)
			ArrangeContainers((ContainerNode)child, layout);
	}
	layout.Arrange(diagram, GetContainerItems(parent));
	parent.UpdateBounds(true);
}

private void miLayoutContainersRecursively_Click(object sender, EventArgs e)
{
	LayeredLayout layout = new LayeredLayout();
	layout.MultipleGraphsPlacement = MultipleGraphsPlacement.MinimalArea;

	ArrangeContainers(diagram.Nodes[0] as ContainerNode, layout);
}

private void Arrange(Diagram diagram, Layout outerLayout, Layout innerLayout)
{
	foreach (DiagramNode node in diagram.Nodes)
	{
		ContainerNode container = node as ContainerNode;
		if (container == null)
			continue;

		innerLayout.Arrange(diagram, GetContainerItems(container));
		container.UpdateBounds();
	}

	outerLayout.Arrange(diagram);

	/*foreach (DiagramLink link in diagram.Links)
	{
		if (ContainerNode.GetContainer(link.Origin) != ContainerNode.GetContainer(link.Destination))
			link.Route();
	}*/

	diagram.ResizeToFitItems(5);
} 

  
Back to top
 
IP Logged
 
henry k
Junior Member
**
Offline


I Love MindFusion!

Posts: 51
Location: Finland
Joined: Apr 4th, 2012
Re: DiagramLayout messedup
Reply #6 - May 2nd, 2012 at 11:19am
Print Post  
Stoyo wrote on May 2nd, 2012 at 10:55am:
You can find several versions of it by searching the forum. Here's what I have currently in my test app:

Code
Select All
private DiagramItemCollection GetContainerItems(ContainerNode container)
{
	DiagramItemCollection items = new DiagramItemCollection();
	foreach (DiagramNode node in container.SubordinateGroup.AttachedNodes)
	{
		items.Add(node);
		foreach (DiagramLink link in node.GetAllLinks())
		{
			DiagramNode node2 = GetOtherEnd(link, node);
			if (ContainerNode.GetContainer(node2) == container && !items.Contains(link))
				items.Add(link);
		}
	}
	return items;
}

private void ArrangeContainers(ContainerNode parent, Layout layout)
{
	DiagramItemCollection children = GetContainerItems(parent);
	foreach (DiagramItem child in children)
	{
		if (child is ContainerNode)
			ArrangeContainers((ContainerNode)child, layout);
	}
	layout.Arrange(diagram, GetContainerItems(parent));
	parent.UpdateBounds(true);
}

private void miLayoutContainersRecursively_Click(object sender, EventArgs e)
{
	LayeredLayout layout = new LayeredLayout();
	layout.MultipleGraphsPlacement = MultipleGraphsPlacement.MinimalArea;

	ArrangeContainers(diagram.Nodes[0] as ContainerNode, layout);
}

private void Arrange(Diagram diagram, Layout outerLayout, Layout innerLayout)
{
	foreach (DiagramNode node in diagram.Nodes)
	{
		ContainerNode container = node as ContainerNode;
		if (container == null)
			continue;

		innerLayout.Arrange(diagram, GetContainerItems(container));
		container.UpdateBounds();
	}

	outerLayout.Arrange(diagram);

	/*foreach (DiagramLink link in diagram.Links)
	{
		if (ContainerNode.GetContainer(link.Origin) != ContainerNode.GetContainer(link.Destination))
			link.Route();
	}*/

	diagram.ResizeToFitItems(5);
} 




Yeah, I found that just minute ago.. (took me around 8min to find it).
(I was wondering if you people could add tags to this forum, so that finding what users are looking may come a bit easier..? or something like FAQ; this scenario/post may sound like one)

I just have now problem with second containers nodes link... the anchor point is wrong... (do not understand, yet why)
(see attachment..)

Also your shown sample _had_ the:
autoshrink = false && container.UpdateBounds()
results: (containers get larger and larger every update)

Other than those... this seemed to solve my problem.. Smiley
  

diagramLayout_newResult.png (Attachment deleted)
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramLayout messedup
Reply #7 - May 2nd, 2012 at 2:14pm
Print Post  
Quote:
I was wondering if you people could add tags to this forum


If the YaBB developers add tags support, we will upgrade the forum Smiley Anyway, search should work better if you select all diagramming boards on the search page and change the post time field to (all posts).

Quote:
I just have now problem with second containers nodes link... the anchor point is wrong...


Do these nodes have any AnchorPattern set?
  
Back to top
 
IP Logged
 
henry k
Junior Member
**
Offline


I Love MindFusion!

Posts: 51
Location: Finland
Joined: Apr 4th, 2012
Re: DiagramLayout messedup
Reply #8 - May 3rd, 2012 at 7:27am
Print Post  
Quote:
Quote:
I just have now problem with second containers nodes link... the anchor point is wrong...


Do these nodes have any AnchorPattern set?


.... no.


I just noticed another thing... A container within container doesn't get arranged with nodes in the first layer (container)... also they're all in singular line (they don't get arranged equally horizontally and vertically... all links cross each and other).

Example:

Diagram {
a1 (container)
- a1.1 (node) (link to a1.2)
- a1.2 (node) (link from a1.1)
- a1.3 (container) (this one is overlapping a1.1 or a1.2 depending on arrange...)
-- a1.3.1 (node) (link to a1.3.2)
-- a1.3.2 (node) (link from a1.3.1)
}

Modify: [03.05.2012 10:30 local time]
Additional Info, this seems to be occurring only when there is a link from node that is in second container to a node that is in first container (second container is in first container)

Br. Henry
  

diagramLayout_LinksInContainer_should_be.png (Attachment deleted)
diagramLayout_LinksInContainer_Result.png (Attachment deleted)
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: DiagramLayout messedup
Reply #9 - May 3rd, 2012 at 10:25am
Print Post  
The Arrange(innerLayout, outerLayout) code processes only topmost containers. For nested containers, check the ArrangeContainers method (called from miLayoutContainersRecursively in the code block above). You might have to extend it if you need different layouts for different depths of containment - as innerLayout and outerLayout were used in the single-level case.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
henry k
Junior Member
**
Offline


I Love MindFusion!

Posts: 51
Location: Finland
Joined: Apr 4th, 2012
Re: DiagramLayout messedup
Reply #10 - May 21st, 2012 at 8:36am
Print Post  
Regardless of your code samples I'm unable to arrange nodes in correct way.
(if there is only one "layer" then it works in all cases; but when there is more than one "layer" they're all messed up; also cross-browsing is not working correct: IE and FF and Chrome all look different)


In my sample case I've reduced the number of "layers" to two... (diagram with containers and nodes within container...)
Regardless of this I get really weird situations... for example I have 2 containers container and 5 shapenodes in total.
[C1]
[S1]
[S2]

[C2]
[S3] (Link to S2 & S5)
[S4] (Link to S3)
[S5] (Link to S1 & S2 & S3)

(as in situation described image [1.png] below)
(but the result is described on image [2.png] below)

.. or in case where the S5 node is the last node on second container, then the first container should be moved to right around 50px or so to be aligned with the lines (not being crossing others).


There was a situation where I managed to get all nodes in correct places, but the links where crossing each and other...

Br. Henry

P.S. I would be really appreciated if you would have on next release a recursive arrange (considering the containers)...
  

1.png ( 11 KB | 117 Downloads )
1.png
2.png ( 12 KB | 128 Downloads )
2.png
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint