Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Order of DiagramLinks (Read 3752 times)
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Order of DiagramLinks
Sep 19th, 2012 at 12:31pm
Print Post  
Hi,

Apologies in advance if this is a very simple problem! It's possible i just can't see the Wood for the Trees!

On my flow diagram i have some nodes which are only temporary and the user must drag components from a list onto them in order to incorporate the component in the diagram. (I hope that makes sense)... So, essentially, i need to delete the temporary node, add the new node and redraw the links with the parents and children.

The issue i'm having is with the parent node, in that, if it has 2 children and you try to replace Child #1, it will delete it and create a new node/link to the right-hand-side of Child #2... So the order of the children changes. This is an annoyance for 2 children but a real problem for more, i.e.

parent
1 2 3 4 5 6 7

If i want to replace child 4 with a component it will do this to the children:

1 2 3 5 6 7 4

Is there any way to order the DiagramLink objects? I am using the .Tag property for other data so i can't use it to store an integer, is there anything else i can use?

Any help will be fab Smiley

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Order of DiagramLinks
Reply #1 - Sep 19th, 2012 at 12:48pm
Print Post  
Hi,

The order or child nodes in layouts such as TreeLayout or FlowchartLayout depends on the order of links in the parent's OutgoingLinks collection. So instead of recreating links, try connecting the existing ones to the new node. That should ensure the link order in the neighbor nodes collections won't change. I haven't tried the code, but this should do the trick:

Code
Select All
void ReplaceNode(DiagramNode oldNode, DiagramNode newNode)
{
	DiagramLinkCollection inLinks = oldNode.IncomingLinks.Clone();
	DiagramLinkCollection outLinks = oldNode.OutgoingLinks.Clone();
	foreach (DiagramLink link in inLinks)
		link.Destination = newNode;
	foreach (DiagramLink link in outLinks)
		link.Origin = newNode;
	diagram.Items.Remove(oldNode);
} 



I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Re: Order of DiagramLinks
Reply #2 - Sep 19th, 2012 at 1:30pm
Print Post  
Hi Stoyan,

Thanks for your very speedy reply!

The theory behind your suggestion makes perfect sense but i still can't seem to get it to keep the link order that it started with...

I am using a LayeredLayout - could that make a difference?

I could be missing something obvious too!

Thanks so far!

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Order of DiagramLinks
Reply #3 - Sep 19th, 2012 at 2:16pm
Print Post  
Hi Rich,

If I understand the LayeredLayout code correctly, it depends more on the initial order of nodes within Diagram.Nodes collection than on links' order. LayeredLayout first assigns nodes to layers according to StartNode,EndNode,EnforceLinkFlow and/or EnableCustomLayers properties, where nodes in a layer are initially added in the same order as they have in diagram.Nodes. Then the layers are rearranged in a way that minimizes link crossings between nodes in adjacent layers. So I think in this case you should try placing the new node at the same position within diagram.Nodes. E.g. try saving the Nodes.IndexOf(oldNode) value, add the new node, then offset nodes in a loop:

Code
Select All
for (int i = diagram.Nodes.Count - 1; i > oldNodeIndex; i--)
  diagram.Nodes[i] = diagram.Nodes[i - 1];
diagram.Nodes[oldNodeIndex] = newNode; 



LayeredLayout might be depending on the links order too, so you should probably still use the ReplaceChild method above to preserve the links order.

You might also consider using the same node object but replacing its content. E.g. if your diagram uses ControlNodes, just replace ControlNode.Control instead of creating a new node to host the control.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Re: Order of DiagramLinks
Reply #4 - Sep 19th, 2012 at 2:56pm
Print Post  
Hi Stoyan,

Once again thanks for your help and advice. Once again your suggestion made perfect sense and i have implemented the code but it's still drawing the 2 children in the reverse order to their starting order.

Through tracing i can see that the order of the nodes in document.Nodes did change exactly the way i'd expect it to but it doesn't seem to follow this order to draw the diagram...

Sorry to keep bugging you with this...

I don't currently use ControlNodes - is that recommended? I tried changing the node properties to match the new requirements but it didn't allow me to reroute the links at all... I may have been doing it wrong though, to be fair.

Thanks again,

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


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Order of DiagramLinks
Reply #5 - Sep 19th, 2012 at 3:23pm
Print Post  
Perhaps you should also try preserving the order in diagram.Items, just in case. I.e. duplicate the code above and replace diagram.Nodes with diagram.Items. It's really hard to say what all the factors are, LayeredLayout.cs has about 3000 lines of code...

Regarding reusing objects instead of creating new ones, ControlNodes were just an example. If you are using ShapeNodes, you can update the node's Text, Shape, Brush / Image, etc. to show the dropped data instead of creating a new node. Same applies to other node types - you should be able to easily update their content to show the new data instead of creating a new node and removing the temporary one, and should be much easier than ensuring all items in all collections preserve their order.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Re: Order of DiagramLinks
Reply #6 - Sep 20th, 2012 at 11:59am
Print Post  
Hi Stoyo,

Thanks again for your reply.

As per your suggestion i tried arranging the diagram.items in the original order too and that made no difference.

What i decided to do was take it right back to the bare bones of what i was trying to do... So, rather than replacing the node that was already on the document; i'll leave it completely unchanged and untouched (not changing a single parameter) and i'll just add 2 children to it...... The same thing happened again!! It jumps to be the last child of it's parent node, even when i don't change the node at all...

I'm fairly confident it's the laying out of the diagram that's doing it but i just can't see what controls the order of child nodes.

Cheers,
Rich
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Order of DiagramLinks
Reply #7 - Sep 20th, 2012 at 12:22pm
Print Post  
Do you mean that two runs of LayeredLayout on the same graph result in different arrangements, or that running it once on a changed graph does not show the children in the order you expect them? I was assuming you are trying to preserve the arrangement when running LayeredLayout for a second time with a replaced node - the results should be consistent if all collections preserve their order and the connections between nodes do not change.

In the general case, the order of nodes within a layer does not reflect the order of node connections to their parent. It probably has some impact, since the initial configuration of LayeredLayout data structures depends on it. However, while the algorithm runs it reshuffles the nodes within a layer many times, looking to minimize crossing of links between layers, so adding a new child node can change the final result a lot. So I'm afraid there's nothing you can do to preserve the order within a LayeredLayout layer after adding new children and connections.

If your data is hierarchical, use TreeLayout instead: TreeLayout arranges children under a parent node in the order of links within the OutgoingLinks collection. If your diagram is an arbitrary graph where nodes could have more than one parent, you can still use TreeLayout, but must implement some additional processing for non-tree links because TreeLayout will ignore them.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Rich Cassell
Junior Member
**
Offline


I Love MindFusion!

Posts: 63
Joined: Sep 19th, 2012
Re: Order of DiagramLinks
Reply #8 - Sep 21st, 2012 at 9:26am
Print Post  
Hi Stoyo,

I've managed to get it doing what i need! Going through all that you told me i have managed to keep the original order of the child nodes - for the basic tests at least!

I'm still using a LayeredLayout, but after running the Activate method (ll.Activate(doc)), i'm then calling my own method which traverses the diagram and whenever it finds the relevant control it removes the links that are in the wrong place and re-adds them. This forces them to be drawn at the end of the children; so essentially, any child that should come after the new node is redrawn.

It's a bit of a bodge but for the very simple 2-output nodes it works a treat. If, in the meantime, you find a more elegant solution to force the Activate code to do it automatically then please let me know!

Thanks again,

Rich
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint