Save diagram model and nodes in Gojs

Hello,

Since there is no way of saving template data in GOJS, what would be the best way to save a diagram in case of multiple templates, link information and also be able to save the position data of nodes?

To be clear, there are templates and there are data in the model, but there is no “template data”.

Many samples demonstrate what you are asking for, such as:
https://gojs.net/latest/samples/flowchart.html
https://gojs.net/latest/samples/flowgrammer.html
https://gojs.net/latest/samples/grafcet.html
https://gojs.net/latest/samples/logicCircuit.html
https://gojs.net/latest/samples/network.html
https://gojs.net/latest/samples/pageFlow.html
https://gojs.net/latest/samples/processFlow.html
https://gojs.net/latest/samples/seatingChart.html
https://gojs.net/latest/samples/sequentialFunction.html
https://gojs.net/latest/samples/stateChart.html
https://gojs.net/latest/samples/systemDynamics.html

Sorry for the confusion, what I meant to say was I have multiple templates that I am adding to the template map. In an earlier issue, it was mentioned that this cannot to converted to JSON. So my question here is, do I have to recreate the templates for each node again while retrieving the diagram or is there a way to automate this? Thanks

The normal thing is to define when you initialize the Diagram all of the templates that it might need.

What situation do you have where you need to create templates dynamically? I cannot recall an instance where that was needed, but I can imagine it.

I am actually designing an editor where each node will have specific characteristics(eg predefined shape or geometry string) that depend on user selection, hence a different template for each node.
So you are saying it would be better to generate all the possible templates beforehand and assign to nodes as per the requirement?

Normally you don’t need to have different templates if the difference is just a matter of binding a few properties.

Technically it is possible for one node template to implement all possible nodes that you could want to show in a single diagram. But as a practical matter, that could require a tremendously complicated template, which would be unpleasant to maintain. So having multiple templates is convenient for organizing your code. https://gojs.net/latest/intro/templateMaps.html

I find it better to even split up a single complicated node template in to multiple paragraphs of code calling multiple supporting functions, even though the result is only a single template. You can find some of the samples organized that way, which helps for clarity.

And if you really want to generate templates dynamically when you load a model, you can. There just isn’t any built-in support for that.

I would need to save the position of nodes as well in this case. I read in one of your earlier posts that that is done in the node template as well with two way binding. How will that work if I do recreate the templates when I get the saved diagram?

Hey, if the information is on the data object, it’s accessible to any bindings or code that you want to use.

So I used :
new go.Binding(“location”, “loc”, go.Point.parse).makeTwoWay(go.Point.stringify)
to save the position of the node in the model. But when I retrieve model from JSON the node seems to lose its position specified in the ‘loc’ property. What might be going wrong here?

It sounds like you need to examine your persistence mechanisms.

Look at any of those samples that I reference above to see examples where the user can move a node, click the “Save” button, see the modified location information in the JSON-formatted model, delete everything in the diagram, click the “Load” button, and then see the node at its last moved location.

I took this from one of the earlier posts to get link data:
while (allNodesIt.next()) {
var node1 = allNodesIt.value;
console.log(node.data.text); //node text
var linkIt = node.findLinksOutOf(); // get all links out from it
while (linkIt.next()) { // for each link get the link text and toNode text
var link = linkIt.value;
nodeLinkStr += link.data.text;
nodeLinkStr += link.toNode.data.text;
}
}
This is not giving me the link data (code doesn’t go to the second while loop). The links are drawn by the user by dragging and none are created to begin with. Is there a way I can get links going out of all nodes?

Could you please post a small screenshot of a very simple case, along with tne result of calling Model.toJson?

Then draw a new link, or any other modification that you want to preserve. Post that screenshot and the value of another call to Model.toJson. Point out how the new model is different from what you expected.

I created a model, made changes and printed a json model that has the changed locations.
Saved the model, retrieved the model and created and applied templates followed by calling rebuildParts() (Template was not getting applied until I called this) and printed the model again.
Note the location in the second model. It did not save the loc property data.

Will it make a difference if I created the templates first and then applied the saved model?

You should not be calling rebuildParts. You should be setting all of the templates before loading the model.

What is the value of Diagram.layout? Layouts normally happen at the end of a transaction if a node or a link has been added or removed or changed visibility or changed size (for nodes), or when a model has been loaded. You can disable the latter by setting Layout.isInitial to false. Please read about how to control when layouts happen: https://gojs.net/latest/intro/layouts.html#LayoutInvalidation

It is saving the relative locations of nodes now, thanks