Modify coordination of Points in a link

I would like to modify the coordination of Points in a link via adding a offset

                if (part instanceof go.Link) {
                    let points = new go.List<go.Point>(go.Point);
                    part.points.each((point: go.Point) => {
                        points.add(new go.Point(offset.x + point.x, offset.y + point.y));
                    });
                    part.points = points;
                }

However, it seems the number of points is wrong through iteration, it should be 6 but I only get 4. So I get a weird shape of link. The left part is before offset but right is with offset.

I then realize if I drag the node a little bit, the link auto correct itself.

What might be the possible issue here? Thanks.

-Chuan

When are you executing that code? It might be that you’re trying to do that at the wrong time, in the middle of Link.computePoints, or before then.

An easier way to shift a link route by a constant offset is to call Link.move.

I am calling it in the ClipboardPasted diagram event. Can I just use Link.Move but still call in this event?

-Chuan

I’m not sure that in a “ClipboardPasted” DiagramEvent that the routes have been computed yet.

It seems to me that if you do not want the standard routing as determined by the properties of the link and the two connected ports/nodes, that just shifting the route will not produce lasting results. As soon as the user moves one of the nodes, the route will go back to being the standard route again.

If you want the route to be shifted you really ought to set properties or override methods so that the computed route meets your requirements.

Thanks for explanation, Walter. I solve the problem now.

The reason why I want to shift the link by an offset is because I shift the node first but realize link doesn’t shift with the node. I need to move node after shifting to invoking computePoints. I end up with calling Link.invalidateRoute after shifting nodes to make a explicit recompute on points. In this way, I don’t need to shift link points manually. I also realize that it doesn’t matter when to call invalidateRoute method on link, even before shifting nodes.

            e.subject.each((part: go.Part) => {
                // relocate node
                if (part instanceof go.Node) {
                    let position = new go.Point(offset.x + part.location.x, offset.y + part.location.y);
                    model.setDataProperty(part.data, "loc", go.Point.stringify(position));
                    this.sharedDataService.broadcastChanged(Events.MOVE_DIALOG_FLOW_NODE, [part.data]);
                }

                // relocate link
                if (part instanceof go.Link) {
                    part.invalidateRoute();
                }
            });

Does that make sense to you?

-Chuan

Why would you want to implement any of that?

If you want to automatically update the “loc” property on the model data, use a TwoWay Binding.

If you want to broadcast change notifications to other software, implement a Model Changed listener to detect the changes that you care about and broadcast those.

Link route invalidation happens automatically whenever a Node is moved – you don’t have to do anything.

Here is the thing. Actually, this is related to my other post before.

I have to shift node by an offset in order to paste the objects in the clipboard to another layer at my lastInput position.

Accordingly, I need to update links position as well which I believe should be calculated automatically via new position of linked node. So I have to call invalidateRoute to force it happen. Otherwise, like what I mentioned, I have to drag the node a little bit after paste in order to trigger that function happen and update my link.

-Chuan

It would be easiest to call Diagram.moveParts.