However, at some point later on, it gets reset (to an array of length 6) - triggered by the same transaction that adds the edge to the model (altho I tried removing the transaction and it just gets triggered later on instead)
I do already have two-way location binding on the nodes. I am also pretty sure it is not a layout problem because I put a breakpoint in Diagram.layoutDiagram and it does not get triggered. The link template is this:
Have you set the Diagram.layout to anything, and if so, what?
I’m guessing that a layout is happening, since by default, layouts are invalidated and performed at the end of the transaction whenever a node or a link is added or removed or changes visibility. Read more about this at: Layouts | GoJS
I am pretty confident that there is no layout involved when the diagram is first loaded - as I said, I put a breakpoint in Diagram.layoutDiagram and it does not get triggered but there might be a better way to know for sure.
However, I found this really old post and the solution there seems to have fixed the problem… So I set the Link.adjusting to go.LinkAdjusting.Stretch and it now behaves - I am not sure if this is intended since the post was from 11 years ago and it says it was fixed
Hello, so after further testing, it appears that setting go.LinkAdjusting.Stretch works most of the time but not always… some edges get reset even with that. I added a “LayoutCompleted” DiagramEvent and it does get called twice but the Diagram.layout is an instance of the base Layout class and I cannot find a way to stop it from being called.
The docs say:
If you have position information for all of the nodes when you load a model, you will typically have data bound the Part.location to some property on your node data. In order to avoid an initial layout causing those saved node positions to be discarded, you can either not set the Diagram.layout to a predefined layout or you can set isInitial to false.
And we don’t set it, so I don’t quite get what’s going on. I also tried manually setting this right as the diagram is created (the default value was false)
Select and reshape a Link, click the “Save” button, optionally make any changes to the diagram that you like, then click the “Load” button to restore the flowchart including the manually just rerouted Link. The Link template does not set Link.adjusting. The “Load” button assumes that all Nodes have real locations.
The situation I described earlier was assuming that you had set Diagram.layout to a typical layout so that the diagram does automatic layouts. By default it would operate whenever you replace the Diagram.model, because they would be all new Nodes and Links, so it makes sense to automatically perform a layout.
But if you had node locations and link routes saved in the model, you would first have to set Layout.isInitial to false (and maybe also Layout.isOngoing) so that the initial automatic layout would not happen.
Do you have Pictures that when their images are loaded cause the Nodes that they are in to change size? That might be causing an automatic layout after the initial phase.
Or do you do anything else after the “InitialLayoutCompleted” DiagramEvent to modify nodes?
Perhaps the issue is in the way the model is created? In all the examples of saving and loading I see, the model is directly created from JSON, but what we do is create an empty GraphLinksModel and load into it using a bunch of addNodeData and addLinkData in a transaction - this is because we save the nodes in a different format and get them async.
And yes, “InitialLayoutCompleted” gets called before all the nodes are added using addNodeData
We do have go.Picture objects - I tried removing them to see if they are the cause but that does not seem to be the case.
Before setting Layout.isOngoing on the default layout to false, the order in breakpoints being hit goes like this:
“InitialLayoutCompleted” → “LayoutCompleted” → “addNodeData” → “LayoutCompleted”
After setting Layout.isOngoing to false the order goes like this but the result is the same
“InitialLayoutCompleted” → “LayoutCompleted” → “addNodeData”
If your loading of models involves the modification of the current Diagram.model rather than building a new model and replacing Diagram.model, then either you need to pretend that it’s a new diagram initialization by calling Diagram.delayInitialization (which is what gojs-react does), or else you can ignore all of the Diagram.initial… properties and handle everything yourself.
I think what you need to do is load all of the nodes, let the transaction complete, and then do another transaction to load the links. That way the addition or modification of nodes won’t happen after the links have been loaded, causing their routes to be invalidated and then recomputed.
Alternatively you could load all nodes and links, and then in your “LayoutCompleted” listener you could iterate through all of the link data and reset Link.points to their intended/saved values. But this scheme won’t work if you expect users to reshape link routes and thus you have a TwoWay Binding on the Link.points property, since any routing of the links would cause their saved “points” lists to be overwritten.