Mix of Normal and AvoidNodes routing

Hi,

I have a problem with the routing of the links in my diagram…

In my link template. I set the routing to go.Link.Normal and some links overlap nodes. I suppose that is ok. But when I call the function “layoutDiagram(true)” on my diagram, it seems that the routing change to a mix of normal and avoidNodes and I don’t know why.
Personally, I prefer the second state, but I want to know how to manage this behavior.

Before the call of layoutDiagram:


After the call of layoutDiagram:

Here my code:

    this._linkTemplates.add('',
        $(go.Link,
            {
                routing: go.Link.Normal,
                fromSpot: go.Spot.Bottom,
                toSpot: go.Spot.Top,
                cursor: 'pointer',
                corner: 5
            },
            $(go.Shape,
                {
                    isPanelMain: true,
                    strokeWidth: 4,
                    name: 'BORDER'
                },
                new go.Binding('stroke', '', this.getLinkColor.bind(this))
            ),
            $(go.Shape,
                {
                    toArrow: 'Standard',
                    strokeWidth: 6
                })
        )
    );

protected getLayout(): go.Layout {
let $ = go.GraphObject.make;
return $(go.LayeredDigraphLayout, { direction: 90, columnSpacing: 10, layerSpacing: 120, isOngoing: false });
}

Thank you

Yes, LayeredDigraphLayout does route Links, by default. (You can turn that off by setting Layout.isRouting to false.)

But if neither a layout nor some other mechanism is explicitly routing links, you will get the default routes as determined by the link properties and the properties of the ports that the link connects.

Hi,

Thanks for the answer. if I set the isRouting to false, the layoutDiagram will keep the same routes.

However, I prefer when the links avoid nodes and the routing is Link.Normal… I did some tests and I noticed this behavior:


Also, the application is a single page application and this behavior happens only on first use of the diagram. If I go back after a navigation, the links always avoid nodes.

Can this behavior be caused by ports?? If I set the routing to AvoidNodes, the problem not happen.

Thanks for your help

What are you doing “during a load”? As far as GoJS is concerned, the only step that acts as “loading” is when you set Diagram.model to refer to a new Model. So you would not get a chance to see your first screenshot. Your app must be doing something else after setting Diagram.model.

Hi,

The page loads other controls, but if I remove all other controls to keep only the diagram, I get the same result (but faster).
The model is set once (on the ngOnChanges) of my component. Like I said, it’s just on the first use of the gojs diagram that I meet this problem.
After, the routing is correct (routing normal, but the nodes are avoided like the last screen shot).

It’s for this reason that I don’t understand…

I’m still unclear what is happening between the first screenshot (routes are good) and the second one (links have lost their layout-determined routes).

Normally that will happen when either the nodes are moved (unlikely in your case I think) or the nodes changed size. Might the node sizes depend on some data that is loaded? Perhaps some text changes? Or some image loads? If so, change the template so that there is a fixed width and height on each TextBlock and Picture.

I tried with static image and text and I get the same result.
The diagram seems to redraw the links twice, but I don’t know what can trigger this.

I added the attribute “adjusting: go.Link.Stretch” in my linkTemplate and it works. I don’t why it works in this case.

The use of Link.adjusting “fixing” the routes is a definite indication that the nodes are moving or changing size after the first screenshot. But I have no idea of what in your app is causing those changes.

But you may have wanted to set Link.adjusting anyway, for real reasons.

It was just a test…
I will continue my investigation. I will let you know if I find the problem.
Have a nice day!

Hi,

I think that I have find the source of the problem.
It turns around the binding of the property “source” of my go.Picture. If I remove the binding of the property source and add the static property (here in comments), It works well.

Here my node template:

this._nodeTemplates = new go.Map<string, go.Part>();
        this._nodeTemplates.add('assetTypeElement',
            $(go.Node, 'Auto', this.nodeStyle(),
                {
                    cursor: 'pointer'
                },
                new go.Binding('visible', '', this.elementVisibleConverter.bind(this)),
                $(go.Shape, 'None',
                    {
                        figure: 'rectangle',
                        fill: 'transparent',
                        margin: 0,
                        minSize: new go.Size(160, NaN),
                        maxSize: new go.Size(160, NaN),
                        name: 'FILL',
                        strokeWidth: 5
                    },
                    new go.Binding('stroke', 'isHighlighted', (h) => h ? '#b71c1c' : 'transparent').ofObject()
                ),
                $(go.Panel, 'Table',
                    $(go.Picture,
                        {
                            row: 0,
                            column: 0,
                            width: 80,
                            height: 80,
                            margin: 5,
                            imageStretch: go.GraphObject.Uniform/*,
                            source: 'images/logo.png'*/
                        },
                        new go.Binding('source', '', () => { return 'images/logo.png'; })
                    ),
                    $(go.TextBlock, 'UniformToFill',
                        {
                            row: 1,
                            column: 0,
                            font: 'bold 11pt Helvetica, Arial, sans-serif',
                            margin: 8,
                            minSize: new go.Size(160, NaN),
                            maxSize: new go.Size(160, NaN),
                            wrap: go.TextBlock.WrapFit,
                            textAlign: 'center'
                        },
                        new go.Binding('text', '', this.nodeTextConverter.bind(this))
                    )
                ),
                this.addShapeForNewElement(this.nodeIsNewConverter.bind(this)),
                this.makePort('T', go.Spot.Top, false, true, this.nodeIsToPortVisibleConverter.bind(this), true, 15),
                this.makePort('B', go.Spot.Bottom, true, false, this.nodeIsFromPortVisibleConverter.bind(this), true, 15)
            ));

In the application, the binding call a function, but the problem is still there if I return the static .png (logo.png).

Can you tell how can I optimize the binding “source” of a go.Picture?
Maybe the “real” problem is not there, but the correlation is good.

Thank you

You set the width and the height of the Picture, so I’m surprised that your nodes would invalidate the routes of connected links when the image is loaded.

I don’t know what this.nodeTextConverter does, but I would guess that would be more likely to change size.

However, I’m wondering if you try using the library at GoJS - Build Interactive Diagrams for the Web (http://gojs.net/beta/release/go-debug.js) if you encounter the problem at all. Link route invalidation is a bit smarter in version 1.7.

Hi walter,

You’re right.
I tried with the “GoJS v1.7.0-rc” and it seems to solve the problem. It’s maybe a bit smarter, but it’s enough!
I will tell this to my team’s members.

Thank you!

Hi,

Do you know when the version 1.7 will be release?

Thank you

This week, I hope.

Great.
I will wait the new release.

Thank you and have a nice day!