Problem with links layout


Please look at the following example
We have 2 issues with it:

  1. Run the example, link “first item” of “Name” with the “first item” of “Name (2)”. So far so good. Then link “second item” with “second item” and you’ll see links go crazy. Then link the rest 3 with 3 and 4 with 4 to see even more crazy links layout. Then move any node and the links layout become normal. Is there a way to fix that?
  2. With links created at step 1) move one of the nodes up. You’ll see that all links are “merged” (like a bus) so there is no way to tell which port is linked to which port anymore. The same will happen if you link node to itself. How we may avoid this and make links to be always visually separate?


I haven’t had the chance to look at your app. For (2) I suggest using FromSpot and ToSpot that are “…Side” values, rather than Spot.MiddleRight or Spot.MiddleLeft or whatever you are using.

Hello Walter,

Have you looked at the example? Do you have any suggestion how to solve my issues? Regarding the 2) may be I was not clear, I meant the following

Links here are merged so user cannot see which port is linked with which port. I would like to have each link to be separate visually. The even worse situation is when we have crossed links like 1-3, 2-1, 3-2, 4-4, the result is the following

And here is the picture related to 1), after I linked corresponding ports

Thank you.

I’ll take a look at the app when I get a chance.

(1) Are you using LayeredDigraphLayout? That would introduce intermediate points in the routing of each link, which is what I think you are seeing. It appears that the distance between those intermediate points is a lot greater than the distance between the ports. Also it appears that there isn’t enough room between the layers.

(2) It appears that you are using Routing=“AvoidsNodes”, which will cause link segments to overlap even when you don’t want them to. In fact, I don’t recommend using orthogonal routing at all for such cases – it’s much easier to see the relationships in a small area when the links are at different angles instead of all orthogonal.

Also, since you are using separate ports on each node, my earlier suggestion regarding setting go:Node.FromSpot=“RightSide” and the like does not apply.

Hello Walter,

Yes, we are using LayeredDigraphLayout. We didn’t change anything related to any intermediate points as I know. When we add the first link in the attached example it is added correctly as a straight line. But when we add the next link the problem as in image above occur. And it is not related to layers spacing I think, because when we change node position (even move one node closer to the other) the links layout become correct.

Graph with orthogonal links layout looks much better IMHO. But the problem is that we cannot (as I know) have AvoidNodes but not orthogonal links. With links layout set to Normal, after initialization graph looks more or less good, i.e. links don’t cross nodes. But when user start to add additional links they cross nodes which is unacceptable for us.

Why links merge at all? IMHO it is incorrect graph behavior even if it is by design. In any entity editor for example, links are orthogonal but they never merge. They are layouted as parallel lines.

If I use this Diagram.Layout:
<Layout:LayeredDigraphLayout Direction=“0” ColumnSpacing=“12” LayerSpacing=“50” />
I don’t think the initial results are too bad.

By default a layout occurs when there is a new link or a deleted link (or new or deleted node).
In this case it is good because the layout is smarter about routing.

But when the user moves a node, the links normally default to their standard routing, which doesn’t have the same contextual information. “AvoidsNodes” routing is just designed to avoid nodes, not to avoid other links.

One feature in GoDiagram that isn’t in GoXam is the ability to try to keep multiple links between the same pair of nodes in parallel. However, “AvoidsNodes” routing in GoDiagram still can result in overlapping link segments.

You can reproduce some of the desired effects, but statically (i.e. not adapted to the particular circumstances) by data-binding the …EndSegmentLength properties.

I notice you already had a “Segment” property defined – I used it and duplicated it:

public class PortData {
public int Id { get; set; }
public double FromSegment { get; set; }
public double ToSegment { get; set; }
public string Name { get; set; }

And then in the port definitions (the Polygons):
go:Node.FromEndSegmentLength="{Binding Path=FromSegment}"
go:Node.ToEndSegmentLength="{Binding Path=ToSegment}"

One can add a method to initialize the end-segment-lengths:
public void FinishedItems() {
const double step = 6;
int num = this.Items.Count;
//System.Diagnostics.Debug.WriteLine(this.Name + " " + num.ToString());
int i = 0;
foreach (PortData pd in this.Items) {
if (i < num/2) {
pd.FromSegment = 10 + 2stepi + step;
pd.ToSegment = 10 + stepi + step/2;
} else {
pd.FromSegment = 10 + 2
step*(num-1 - i);
pd.ToSegment = 10 + step*(num-1 - i);
//System.Diagnostics.Debug.WriteLine(" " + pd.Name + " " + pd.FromSegment.ToString() + " " + pd.ToSegment.ToString());
and call it when creating a node, after adding all of the “Items”.

Now there are two problems with this – it’s not smart enough to adapt to which direction a link comes/goes, and it doesn’t adapt the “curviness” of the orthogonal routing to avoid overlapped middle segments. This is why all of this should be done automatically in the implementation of Route.