Maybe when a second link is drawn you want to delete that new link and just change the appearance of the first link by adding an arrowhead and changing your code to treat the link as undirected or both-ways?
I still don’t understand the problem. Can’t you only set Link.curviness to zero when it’s not a Bezier curve? And even when the curve is Bezier, there really are two control points in the link route. Maybe they happen to be coincident.
Maybe this gif illustrates it better. Now I replaced the curviness from an attribute to a binding based on the whether it is a bezier link (as you described): direct=0, bezier=NaN.
So here you see that it works nicely when creating new links:
Left: 2 bezier links with 2 control points
Right: 2 direct links without any control points.
So far so good. However, when I transform the link from a bezier link to a direct link and back, I loose my control points. I only have one control point left as shown.
The following properties are bound on the bezier state:
The problem is caused by the binding (or setting) of Link.adjusting. When adjusting is Stretch or Scale or End, the routing depends on the previous route that it had. Since a straight link with a specified curviness and no fromSpot or toSpot will have three points, those points are what it starts with when the curve becomes Bezier.
If you comment out the setting or binding of Link.adjusting, the problem you report should go away. But if you need to have adjusting be Stretch, I wonder if you could implement a hack where the converter, besides returning either Stretch or None also set Link.points to an empty List. Here’s what I just tried:
myDiagram.linkTemplate =
$(go.Link,
{ curviness: 0, curve: go.Link.None, reshapable: false }, // defaults assume straight, not curved
new go.Binding('curviness', "bezier", b => b ? NaN : 0),
new go.Binding('curve', "bezier", b => b ? go.Link.Bezier : go.Link.None),
new go.Binding('adjusting', "bezier", (b, link) => {
if (b && link.adjusting === go.Link.None && link.pointsCount > 2) link.points = new go.List();
return b ? go.Link.Stretch : go.Link.None;
}),
new go.Binding('reshapable', "bezier"),
$(go.Shape, { strokeWidth: 2 }),
{ toShortLength: 2 },
$(go.Shape, { toArrow: "OpenTriangle" }),
$(go.TextBlock, { background: "white" },
new go.Binding("text", "points", lst => lst.count).ofObject())
);