Save and restore entities coordinates and links points in a diagram


#1

I have a diagram with entity and links and following this example I’m trying to save the entities and links position and following restore them.

The diagram is very simple, and is initialized like that:

myDiagram = $(go.Diagram, "myDiagramDiv", {
  initialContentAlignment: go.Spot.Center,
  initialAutoScale: go.Diagram.Uniform,

  layout: $(go.TreeLayout, {
    angle: 90,
    nodeSpacing: 100,
    layerSpacing: 100,
    setsPortSpot: IS_TREE_LINK,
    setsChildPortSpot: IS_TREE_LINK,
  }),
...
}

In my entity template I have bind the coordinates to location:

new go.Binding("location", "Coordinates", Coordinates => {
  return go.Point.parse(Coordinates)
}).makeTwoWay(go.Point.stringify),

and in my link template I have bind the points:

new go.Binding("points").makeTwoWay(),

I have the following problems:

  1. when I receive data with coordinates and points empty or null, the links in the diagram follow a very strange and chaotic path.

  2. I created the following function for saving links points:

     const points = myDiagram.model.linkDataArray.map(lda => {
       let flattenPoints = []
       lda.points.n &&
         lda.points.n.forEach(elem => {
           flattenPoints.push(elem.x)
           flattenPoints.push(elem.y)
         })
    
       return {
         points JSON.stringify(flattenPoints),
       }
     })
    

but sometimes the lda.points.n is null and I can’t explain why.
Do you have any advices?

Thanks


#2
  1. How are you loading your data when you receive it?

  2. I’m not sure why you need a special function here. What is the purpose of it?

You should probably take a close look at the Flowchart sample, which has a location binding on the nodes, a points binding on the links, and saving and loading of the model. Since you are also using a layout in combination with manually positioned elements, you should probably read about layout invalidation.


#3

Hi Jhardy,
when I receive the data I use myDiagram.model = new go.GraphLinksModel(entities, links) to init the diagram model.
I creted the function to get the coordinates and points and send the data using a POST.
What is the difference between Flowchart sample and State chart sample ? They both use the same binding.


#4

Yes, the state chart sample is similar.

For your function, lda.points.n is a minified property name, and I think you probably mean to refer to lda.points.iterator or maybe lda.points.toArray(). Since you want to save the points as a flattened array, you probably want to use conversion functions in your points binding. One will convert the array of strings to a list of points, and one will convert the list to an array of strings.

Maybe something like this:

// convert a stringified array of points to a list
function parsePoints(pts) {
  var ptarr = JSON.parse(pts);
  var list = new go.List();
  for (var i = 0; i < ptarr.length; i += 2) {
    var x = parseFloat(ptarr[i]);
    var y = parseFloat(ptarr[i + 1]);
    var pt = new go.Point(x, y);
    list.add(pt);
  }
  return list;
}

// convert a list of points to a stringified array
function stringifyPoints(pts) {
  var it = pts.iterator;
  var arr = [];
  while (it.next()) {
    var pt = it.value;
    arr.push(pt.x);
    arr.push(pt.y);
  }
  return JSON.stringify(arr);
}
...
new go.Binding("points", "points", parsePoints).makeTwoWay(stringifyPoints)
...