Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

getEdgeData array[connId] is undefined #2938

Closed
kowdykung opened this issue Mar 31, 2017 · 4 comments
Closed

getEdgeData array[connId] is undefined #2938

kowdykung opened this issue Mar 31, 2017 · 4 comments
Assignees

Comments

@kowdykung
Copy link

kowdykung commented Mar 31, 2017

I am working on saveAndLoad and manipulation example

I got this network which load form JSON.

image

I deleted node 1 and its edge, then I export to JSON file. I got the correct JSON file.

[
  {
    "x": 0,
    "y": -1,
    "id": "0",
    "connections": [
      "3",
      "2"
    ]
  },
  {
    "x": 123,
    "y": -7,
    "id": "2",
    "connections": [
      "0"
    ]
  },
  {
    "x": -52,
    "y": -115,
    "id": "3",
    "connections": [
      "0"
    ]
  }
]

When I want to load this JSON back but it's got an error on import JSON in function getEdgeData

image

I don't know why this function error as I see it should be correct because of JSON is correct.

var ourRequest = new XMLHttpRequest();
			ourRequest.open('GET','http://localhost/2.json');
			var inputData;
			ourRequest.onload = function() {
				inputData = JSON.parse(ourRequest.responseText);
				nodes = getNodeData(inputData);
				edges = getEdgeData(inputData);
				data = {
						nodes: nodes,
						edges: edges
				};

			};
			ourRequest.send();
@wimrijnders
Copy link
Contributor

wimrijnders commented Apr 1, 2017

Reproducing this with saveAndLoad example in chromium/linux, I get the error:

Uncaught TypeError: Cannot read property 'connections' of undefined
    at file:///home/wim/projects/github/issues/%232938/saveAndLoad.html:158:63
    ...

I believe this is the same error as reported with a different text. Location in code, in saveAndLoad.html:

function getEdgeData(data) {
  var networkEdges = [];

  data.forEach(function(node, index, array) {
  // add the connection
    node.connections.forEach(function(connId, cIndex, conns) {
      networkEdges.push({from: node.id, to: connId});

      var elementConnections = array[connId].connections;   // <= ERROR HAPPENS HERE
...

    });
  });

  return new vis.DataSet(networkEdges);
}

@wimrijnders
Copy link
Contributor

What I notice, is that on export, the node id's get renumbered. When I delete node 1, the following is exported:

[
  {
    "x": 1,
    "y": 0,
    "id": 0,
    "connections": [
      2,
      3
    ]
  },
  {
    "x": -7,
    "y": -123,
    "id": 1,
    "connections": []
  },
  {
    "x": 95,
    "y": 83,
    "id": 2,
    "connections": [
      0
    ]
  }
]

I note that id: 3 is missing in the node id's, but that it does feature in the connections.

@kowdykung, are you sure that your example JSON file is as how it was exported?

In any case, this is the problem; the node id's are renumbered on export, but the id's in the connections aren't. The source of the problem can be traced to the following two items:

1. Only position information is used on export:

function exportNetwork() {
	clearOutputArea();

	var nodes = objectToArray(network.getPositions());
...
}

2. The node index is used to set the exported node id's:

function addId(elem, index) {
  elem.id = index;
}

I conclude that issue is in the saveAndLoad demo. I'll think now how to solve this.

@wimrijnders
Copy link
Contributor

I figured it out. This will require a PR to fix fully.

For your personal case, assuming you're using code from the saveAndLoad example, please make the following changes:

             function addContextualInformation(elem, index, array) {
                //addId(elem, index);                    // CHANGED
                 addConnections(elem, index);
             }

            // NEW 
            function getNodeById(data, id) {
              var foundNode;

              data.forEach(function(node) {
                if (node.id == id) {  // double equals since id can be numeric or string
                  foundNode = node;
                }
              });

              if (foundNode === undefined) {
                throw 'Can not find id \'' + id + '\' in data';
              }

              return foundNode;
            }


             // CHANGED - please copy this over the existing function
             function getEdgeData(data) {
                 var networkEdges = [];
 
                     // add the connection
                     node.connections.forEach(function(connId, cIndex, conns) {
                         networkEdges.push({from: node.id, to: connId});
                        let cNode = getNodeById(data, connId);
 
                        var elementConnections = cNode.connections;
 
                         // remove the connection from the other node to prevent duplicate connections
                         var duplicateIndex = elementConnections.findIndex(function(connection) {
                          return connection == node.id; // double equals since id can be numeric or string
                         });

                        if (duplicateIndex != -1) {
                          elementConnections.splice(duplicateIndex, 1);
                        };
                  });
                 });
 
                 return new vis.DataSet(networkEdges);
             }

             // CHANGED - please copy this over the existing function
             function objectToArray(obj) {
                return Object.keys(obj).map(function (key) {
                  obj[key].id = key;
                  return obj[key];
                });
             }

(I'm truly sorry that I can not make it simpler than this)

@wimrijnders
Copy link
Contributor

This issue has been fixed in vis.js 4.20.0, closing for that reason.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants