Since you posted some code here, I hope you don’t mind getting some commentary on it. I’ll go line-by-line.
var newnode = JSON.parse(myDiagram.model.toJson());
This writes out the current diagram’s model as a text string (in JSON format) and then reads the whole thing back in. Basically you are making a copy of all of the model properties including the model data. This is extremely wasteful of time and space. Furthermore it could cause problems because you will be dealing with copies of the node data, not with the actual node data objects.
“newnode” is also a misleading name – it’s really the whole model’s state that has been copied, not just a single node.
for(i=0;i<newnode["nodeDataArray"].length;i++){
key = newnode["nodeDataArray"][i]["key"]
}
This iterates over all of the copied information’s array of copied node data objects, and sets the key
global variable repeatedly. It would be much more efficient to do something like:
var size = newmodel.nodeDataArray.length;
var key = newmodel.nodeDataArray[size-1].key;
But you don’t make use of key
in the rest of the listener, so it would be most efficient to just delete all of that code.
myDiagram.startTransaction("add node and link");
The documentation for the “ExternalObjectsDropped” DiagramEvent says that the listener is called within a transaction, so you don’t need to call startTransaction
. There’s no harm in doing so, except that you are calling it without making sure to call a corresponding commitTransaction
or rollbackTransaction
.
newlink = { from: newnode['nodeDataArray'][size-1]['key'], to: 0, text:"hangup" };
It’s a bit unsafe to create a new link that always goes to the node whose key is zero, but I suppose that might be OK in your scenario.
myDiagram.model.addLabelKeyForLinkData(newlink, newnode['nodeDataArray'][size-1]['key']);
I’m not sure what you are trying to accomplish here. It is highly unusual and somewhat problematic to have a link going from a node to somewhere and also have that same node be a label node on that link. Users cannot draw such a link interactively because the LinkingTool disallows it. You can certainly create such a link programmatically. However if you succeeded, you would probably get undesirable behavior.
As it so happens, unless you have set GraphLinksModel.linkLabelKeysProperty to be the name of some data property, the call to GraphLinksModel.addLabelKeyForLinkData will not succeed.
But do you really want to use the moderately obscure feature of having nodes be labels on links? Or do you just want to show some information on a link? If it’s the latter case, you’ll want to just add the label to your link template, and you don’t need to use nodes as labels at all. GoJS Link Labels -- Northwoods Software
Although I cannot be sure exactly what you want to do, I suggest that you add a label to your link template. At a minimum:
myDiagram.linkTemplate =
$(go.Link,
$(go.Shape),
$(go.TextBlock, new go.Binding("text"))
);
Then the following code should be equivalent to what you had written:
myDiagram.addDiagramListener("ExternalObjectsDropped", function(e) {
var newdata = e.diagram.selection.first().data;
if (newdata.text === 'Datasource') {
var newlink = { from: newdata.key, to: 0, text: "hangup" };
e.diagram.model.addLinkData(newlink);
openModalWindow(newdata.text, newdata);
} else if (newdata.text === 'Play') {
openModalWindow(newdata.text, newdata);
}
})
I hope these detailed comments will help you use GoJS more effectively.