AssignLayers

I still believe that the best way to this is only by changing the Vertex layer of each node in the AssignLayers…

OK, I’m sorry, but I really don’t understand the requirements of your application.

Are you saying that AssignLayers is being called more than once for each LayeredDigraphLayout? If you look on the stack, can you tell why it’s being called?

Do you have a custom Route? If so, maybe it doesn’t understand about connecting links with the layers in reverse order. It’s certainly true that the standard Route does not know about doing so with the standard port spots – or rather, it does, but it won’t do what I think you want.

AssignLayers is call everytime I add/remove a LabelNode, or when I create/remove a Split. If I look in my stack, it’s the LayerManager.PerformLayout that calls AssignLayers.

And no, I don’t have a custom route. What I want is that the splits on cold streams must be the same way as the splits on hot streams. Except the approach of swapping the header arrow, is there an other way?

Maybe to help you understand better, here is how it works. The user created in a DataGrid streams and defines temperatures for each stream. Each time a Stream is added, a new stream is added in the diagram. Then, once the streams are all provided, the user can add items (LabelNode) on the stream, creates Split, etc…

By default a layout will be invalidated each time one adds or removes a node or a link. You can change that automatic invalidation and subsequent re-performance of the layout by setting the DiagramLayout.Conditions property.

Apparently when you change the temperature, you already swap the “from/to of each link”. Maybe my confusion is due to that. I don’t understand why you are doing that, since that will cause parts of the graph to go in the opposite direction of the layout (i.e. the value of LayeredDigraphLayout.Direction). Also that would explain why a layout happens again. (This assumes you are using a single Diagram.Layout.)

Ok, maybe there is some confusion. The picture I shown illustrates what will happen if I use your approach of swapping from/to of each link. But currently, I not swapping anything. I only try to find a way to set the cold stream in the opposite direction of the layout.

And yes I only use a single Diagram.Layout. It’s you who suggested to replace the Group.Layout by one Layout.

Because what I was doing before was to have a specific layout associate to each StreamGroup, and depending if the stream was hot or cold, I was only changing the Layout.Angle

So when the temperature changes from hot to cold, you only need to change the colors (data-bound), maybe some text (also data-bound), and the arrowheads, yes? You can data-bind the arrowheads too. The routing does not change because the graph connectivity does not change.

Not only the color and the arrowhead, the order of each stream in the StreamGroup should change too. In the example below, if initialy (1) I have an hot stream with 2 elements on it (orange rectangle, green triangle) . Then, if this stream pass from hot to cold, I must have what we see in (3)…

OK, I see now why it was so much more natural for you to just change the LayeredDigraphLayout.direction when you were using a separate layout for each stream.

So you really do need to reverse the links. That does mean you must set SetsPortSpots=“False”. In fact, I suggest also that you override LayeredDigraphLayout.LayoutNodesAndLinks to first set all of the route spots and then call the base method. For each LayeredDigraphEdge you need to set the Edge.Link.Route.FromSpot and .ToSpot to be either Spot.MiddleLeft or Spot.MiddleRight, depending on what is appropriate. Something like:

public override void LayoutNodesAndLinks() {
  foreach (LayeredDigraphEdge edge in this.Network.Edges) {
    Link link = edge.Link;
    if (link != null) {
      link.Route.FromSpot = ...;
      link.Route.ToSpot = ...;
    }
  }
  base.LayoutNodesAndLinks();
}

I hope that works for you.

"So you really do need to reverse the links. "

By reverse the links you mean, when the temperature change from hot to cold:

Approach swapping from/to
Link1 a->b becomes Link1 b->a
Link2 b->c becomes Link2 c->b
Link3 c->d becomes Link3 d->c

<span =“Apple-tab-span” style=“white-space:pre”> OR

Approach changing Vertex.Layer
NodeA layer3 becomes NodeA layer0
NodeB layer2 becomes NodeB layer1

NodeC layer1 becomes NodeC layer2

NodeD layer0 becomes NodeD layer3

<span =“Apple-tab-span” style=“white-space:pre”> ???

I assume the former, since according to your diagram node “a” should be layer 3.

I don’t understand your last comment. Which approach are you talking about?

I’m sorry if I have caused any confusion because I don’t understand the details of what you want and may have made suggestions based on incomplete information.

But I believe my suggestions about setting LayeredDigraphLayout.SetsPortSpots=“False” and overriding LayoutNodesAndLinks are sound.

Yep, I’m agree with you for this part. And I tried it combine with the approach of only moving nodes on the right vertex, without swapping any from/to, and it doesn’t work when there is a split. The branches are flat as what you can see in the picture that my collegue has shown.

Have you tried to create a split in the opposite direction of the layout and have you got the same results as if you where in the right direction?

No, I haven’t had time to try anything.

My concern was that the layout explicitly has routing “around” nodes for links that are “backwards”, if the nodes/ports have defined spots. Of course you don’t want that, which is why I recommended that you avoid setting any spots on your port elements, on your routes, or by the layout itself, until afterwards at the LayoutNodesAndLinks time.

But I haven’t actually tried this, so I am not sure that it will work the way that you want.

Hi Walter,

After trying the layers method and the link method which didn't work, we decided to take another approach and create our own custom layout. So I overrided the DoLayout method completely, and everything seems to work ok except when I have multiple links between two nodes. When there's no other nodes between the link that I created everything works right, but when I try to create a link like the black one, the link won't use the good route. The black link will become congruent.
I also tried to override ComputePoints method but no luck :
'Dim result As Boolean = MyBase.ComputePoints()
'If result AndAlso Me.PointsCount = 3 Then
' Dim s As Point = GetPoint(0)
' Dim m As Point = GetPoint(1)
' Dim e As Point = GetPoint(2)
' Dim dx As Double = e.X - s.X
' Dim dy As Double = e.Y - s.Y
' Dim dist As Double = Math.Sqrt(dx * dx + dy * dy)
' Dim space As Double = dist / 2 - Math.Min(15, dist / 3)
' Dim angle As Double = GetAngle(dx, dy)
' Dim offX As Double = Math.Cos(angle) * space
' Dim offY As Double = Math.Sin(angle) * space
' SetPoint(1, New Point(m.X - offX, m.Y - offY))
' InsertPoint(2, New Point(m.X + offX, m.Y + offY))
'End If
'Return result
Thank you

Yes, that makes sense, because the default routing behavior does know about any other nodes that should affect the routing.

You might find it easier to override Route.HasCurviness and Route.ComputeCurviness. That will also give you more control over how far apart the middle points are from each other.

Hi Walter,
I have a question concerning how I should position nodes that are inside the multiple links section. When I overrided the dolayout method, I decided to set each node horizontal distance to 300. It works until I try to add new links with nodes inside one of my multiple links. Then I don't know which position I should set for nodes.
The following example(image 1) is one which works, but if I set my links at the bottom link it wont work(image 2). I thought if I didnt set the position, the route would take care of setting the nodes position but it doesn't seem to work either.
image1
image2

You’ll need to debug exactly where you position the nodes and how it routes the links.

I’m happy to answer specific questions, but there is a limit to what anyone can do in a forum.
Imagine if you were in my shoes trying to help someone.