As for data, here's my hacky way to extract it for storage (I'll try to cut off code bits irrelevant to the question):
// get nodes and edges
var nodes = network.body.data.nodes._data; // contains id, label, x,y, custom per-node options and doesn't contain options from options.nodes; presumably contains option values set when network was created, not current ones (it is so for x,y)
// network.body.nodes[id].nodeOptions shows options from options.nodes but not custom per-node options (same for edges and network.body.edges[id].edgeOptions)
// network.body.nodes contain much more stuff (x,y, default stuff)
//# look for a suitable getter
var edges = network.body.data.edges._data; // map; for edges to/from? certain node use network.getConnectedNodes(id)
// network.body.data.edges._data is a hash of { id: , from: , to: }
// get node positions
var positions = network.getPositions(),
nodeIds = Object.keys(nodes);
// get data describing nodes, edges and options for storage
var storedEdges = [], storedEdge, storedNodes = [], storedNode;
var indexIds = {}, idIndex = 1, end;
for(var nodeId in nodes) {
// nodes[nodeId].x is the initial value, positions[nodeId].x is the current one
if(positions[nodeId]) { // undefined for hidden
nodes[nodeId].x = positions[nodeId].x;
nodes[nodeId].y = positions[nodeId].y;
}
storedNode = copyObjectProperties(nodes[nodeId]);
// don't store id unless that breaks connected edges
if(!network.getConnectedEdges(nodeId).length)
storedNode.id = undefined;
// substitute generated ids with no semantics with simple indices
if(/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/.exec(storedNode.id)) {
while(nodes[idIndex])
idIndex++;
indexIds[storedNode.id] = idIndex; // remember the given index
storedNode.id = idIndex; // substitute with an index
idIndex++;
}
storedNodes.push(storedNode);
}
for(var edgeId in edges) {
storedEdge = copyObjectProperties(edges[edgeId]);
storedEdge.id = undefined; // then strip id
// change from/to in accord to the substitution above (for nodes' ids)
for(end of ["from","to"])
storedEdge[end] = indexIds[storedEdge[end]] || storedEdge[end];
storedEdges.push(storedEdge);
}
dataAndOptions = {
data: { nodes: storedNodes, edges: storedEdges },
options: storedOptions
};
var dataAndOptionsText = JSON.stringify(dataAndOptions,"",4)
.replace(/ {4}/gm,"\t").replace(/},\n\t\t\t{/gm,"},{");
and helper definition:
// helper for storing options
var copyObjectProperties = function(obj) {
return JSON.parse(JSON.stringify(obj));
};
For more context, see my plugin for TiddlyWiki Classic (saveDataAndOptions
method). It's not the latest version, but I'll update it at some point.
As for network options (if they were changed), I haven't figured a nice way yet.