Modified link points do not move with node drag

Question: I have modified the points in a link. When I drag one of the linked nodes my link remains fixed on the diagram. What event should I listen for in order to invoke a function to re-compute the link points ?

That’s odd – moving or resizing a Node will automatically cause each connected Link to recompute its route. I don’t know how you are preventing that, other than having overridden some method on the Link class.

I have a click function called from the node.click event. This is all.

function nodeClicked(e, node) {

    node.diagram.clearSelection();
    var cnt=0, ptStart, ptEnd

    node.findLinksOutOf().each(function (l) {

        var it =l.points.iterator;
        cnt = 0
        while (it.next()) {

            cnt = cnt + 1
            if ( cnt == 1 ) { ptStart = it.value.copy()}
            if ( cnt == l.pointsCount ) { ptEnd = it.value.copy()}
        }
        
        var pts = [   {'x':ptStart.x, 'y': ptStart.y}
                    , {'x':ptStart.x + 10, 'y': ptStart.y}
                    , {'x':ptStart.x + 10, 'y': ptStart.y + 15}
                    , {'x':ptEnd.x - 10, 'y': ptStart.y + 15}
                    , {'x':ptEnd.x - 10, 'y': ptEnd.y}
                    , {'x':ptEnd.x, 'y': ptEnd.y}
                ]
        l.points = pts
    });

}

Is there possibly an override function for the link routing calculation ? That would be ideal for my current case and offer similar advantages to others with similar off-the-beaten-track requirements.

Yes, you can override the Link.computePoints method and do whatever you want. The default implementation, though, is pretty complicated, because it has to deal with a lot of different situations and combinations of property values on the Link and on the connected port elements.

There are a bunch of undocumented methods that are listed in the TypeScript definition file, goJS.d.ts. Search for “undocumented”. Of course there isn’t any documentation for them (and we reserve the right to change or remove that functionality without warning), but you can search for uses of some of the undocumented methods such as “computePoints” in the samples or extensions source code.

Thanks. I took the lead from the http://gojs.net/latest/samples/multiNodePathLinks.ht sample which includes an override for the go.link method that allows me to draw my own links. Whilst the sample is quite complicated, because of the simple nature of my needs the code I developed from it is very simple. Works a treat. See image below - the standard orthogonal link would make the path go right through the ‘Developer’ text, for example.

In the link template declaration for the diagram, replace go.Link with the name of your override linking function, mine was GanttNodePathLink. Mine looks like this:

    this.myDiagramGantt.linkTemplate =
        $(GanttNodePathLink  // replaced go.Link with the override name,
            , { fromPortId: 'portOut', toPortId: 'portIn' ,
               routing: go.Link.AvoidsNodes, corner: 2, relinkableTo: true}
            , $(go.Shape),
            $(go.Shape, { toArrow: "Standard"  })
        );

Then include this code:

go.Diagram.inherit(GanttNodePathLink, go.Link);

/** @override */
GanttNodePathLink.prototype.computePoints = function() {
    // get the list of Nodes that should be along the path
    debug.log('calc links')
    var offset = {from: 10, to: 17, ht: 15} // length of first and last segments, and y offset
    var portOut, portIn, p, ptStart, ptEnd, pts, neg
    if (this.fromNode !== null && this.fromNode.location.isReal()) {
        portOut=this.fromNode.findObject('portOut')
        p = portOut.getDocumentPoint(go.Spot.MiddleRight)
        ptStart = { x: p.x, y: p.y }

    }
    if (this.toNode !== null && this.toNode.location.isReal()) {
        portIn=this.toNode.findObject('portIn')
        p = portIn.getDocumentPoint(go.Spot.MiddleLeft)
        ptEnd= { x: p.x, y: p.y }
    }

    // clear old points
    this.clearPoints();

    // now do the routing
    if ( ptStart && ptEnd ) {
        neg = (ptStart.y > ptEnd.y ? -1 : 1)  // adjustor for upside down links
        debug.log('neg=' + neg)
        pts = [   {'x':ptStart.x, 'y': ptStart.y}
            , {'x':ptStart.x + offset.from, 'y': ptStart.y}
            , {'x':ptStart.x + offset.from, 'y': ptStart.y + (offset.ht * neg)}
            , {'x':ptEnd.x - offset.to, 'y': ptStart.y + (offset.ht * neg)}
            , {'x':ptEnd.x - offset.to, 'y': ptEnd.y}
            , {'x':ptEnd.x, 'y': ptEnd.y}
        ]

        for (var i = 0; i < pts.length; i++) {
            this.addPoint(new go.Point(pts[i].x, pts[i].y))
        }
    }
    return true;
};
// end GanttNodePathLink class

Edited to put vars where they should go and add simple error handling.

Thanks.

JavaScript code really shouldn’t use “var” inside “if” conditional blocks. One should only use “var” as if it were “let” in EcmaScript 6, where the scope of the variable declaration is the block.

Aye - edited the code sample in case anyone took my delinquency as the way it should be done.