almende / vis

⚠️ This project is not maintained anymore! Please go to https://github.com/visjs
7.85k stars 1.48k forks source link

Network : Problem when updating Nodes #3096

Closed mztikz closed 7 years ago

mztikz commented 7 years ago

Hey I am using vis js Network , and when ever I update the nodes for what ever reason the nodes relocating themself to other position and starting to drift back to the position they were , I dont have a direct code to give but if it will be problem to understand I will write one, But its kinda similar to this example http://visjs.org/examples/network/exampleApplications/neighbourhoodHighlight.html if you move a node and then click on one to highlight its moves him back.

Thanks alot from advanced.

wimrijnders commented 7 years ago

I looked at the example: in that particular application, the xy-coordinates are determined in the node definitions, e.g. first item:

'Algeria' + '<br>' + 'Team: ' + 'Club Africain', value: 22, group: 24, x: -1392.5499, y: 1124.1614},

These value are initialization values, used to set the actual coordinates when starting a network. What happens in the application, is that, on a click, a given node in initialized again from the starting value with minor changes (highlighting). So a given node jumps back to its initial position when clicked.


I do not think this is comparable to your network. The initial comment mentions 'drifting back'. This implies that physics is enabled.

I suggest that you turn physics off during display. In addition, if your network relies on it, keep the stabilization on for creating an initial layout. In the options:

physics: {
  enabled: false,     // Stops node movement during display
  stabilization: {    // Determines an initial layout; enabled by default
   enabled: true,
    iterations: 1000
  }
},

This will stop the autonomous movement. HTH.

mztikz commented 7 years ago

I have done that , but If I have a clusters and I open them while the physics are off , all the nodes are staying at the same place, soo I done when I open the cluster i turn physics on. The problems occurs if I have for example 5 clusters where each has 4 nodes inside or soo.. and then I open one or two of them(clusters) and updating their value that increase the size according to the connected number of nodes (highest connected node = biggest node) , When I do this while physics are off , when I update the graph its kicking them to some where ( probly where they suppose to be if all the graph is opened from clusters), and then if physics on they are starting to drift back to where all the clusters are.. if physics off they just stay far away from all other clusters. Hope its more clear now..

wimrijnders commented 7 years ago

Ah, OK, you're using clusters. That's extra info. Would truly appreciate an example jsfiddle.

mztikz commented 7 years ago

I will do a jsfiddle, just about the first example is there a way that when you do update to the graphdata set it wont pop the node back? cause even if the physics are false its still relocate it back to the original place..

wimrijnders commented 7 years ago

The most likely reason that happens, is that there were coordinates for the nodes in the setup options. These coordinates get reset when the options change. So the thing to do IMHO is to remove the coordinates from the options after initialization.

This, when I think of it, smells a bit like unexpected behavior. Perhaps the thing you need is an option to not reset the coordinates. Will think about this.

Awaiting the jsfiddle (for which I thank you for taking the time to make it).

mztikz commented 7 years ago

I think that also the bug with the clusters is also because of this reason because they are jumping always to the same place and it is where the graph placed them at the beginning , is there a way to make them not jump like that ? like to set X/Y to the current X/Y ?

mztikz commented 7 years ago

I have checked it and yea , It does save the previous X/Y and move all the nodes that I opened on the cluster to there when I do some updates on nodes which kicking them every time to the same spot and then they drift back to the graph location... any way to avoid the "kicking" of the nodes? (to set new x/y to current?)

wimrijnders commented 7 years ago

any way to avoid the "kicking" of the nodes? (to set new x/y to current?)

Off the top of my head, no. I have to investigate if that is possible. I'll come back to it.


Update: what I said in my previous comment is possible:

So the thing to do IMHO is to remove the coordinates from the options after initialization.

mztikz commented 7 years ago

How can I remove the coordinates ,? When I do like nodes.getNodes().. it not giving me the nodes with x/y .. is there a way to get nodes with their x/y?

wimrijnders commented 7 years ago

Put your node and edge data into DataSet instances and then you can adjust those directly. That's the easiest way.

mztikz commented 7 years ago

I do it all the time, but the Dataset when I look into it does not contain x/y ..

wimrijnders commented 7 years ago

OK. If initial values for x/y were set in the node data, they will be there. If not, they won't be. In the first case, they will be used to reset the coordinates if the options change. In the second case, no reset.

It appears that you don't have initial x/y values, then. So something else must be going on.

Please make a jsfiddle or suchlike, it would help tremendously with analyzing the issue.

mztikz commented 7 years ago

Here is how I init a graph with a data from my own graph data set using DataSet , stil there is no x/y after initialize http://plnkr.co/edit/uJ0XuZcz1YGR0U3c3Teq?p=preview PS ignore the button

wimrijnders commented 7 years ago

OK I have it running locally so I can debug. I note there is a very old version of vis.js. I see v4.9.0, current is v4.20.0. But that is beside the matter at this point. Reproduce first.

So, what do I do now to reproduce the issue? I tried changing a label of a node at runtime, I see nothing special happening.

mztikz commented 7 years ago

thats not a sample of the issue, to write a sample of issue will take a while , just wanted to show I have no x/y and ask if there way to get it , because the issue is 100% because of this , he has some hidden x/y on each node and when I do dataSet.update(nodes .. ) then he relocate them back to the default x/y that he saved on loading.

You said that :

OK. If initial values for x/y were set in the node data, they will be there. If not, they won't be. In the first case, they will be used to reset the coordinates if the options change. In the second case, no reset.

How to set Initial X/y?

P.S I say 100% because I checked it and it relocate it exactly to where the node was located after the stablize..

wimrijnders commented 7 years ago

'he': so there is someone else who sets up the nodes, right? So it's out of your control.

So, to reproduce, I could just add some x/y to the initialization. Also, where do the clusters come in?

It appears you want a concrete response to:

.. is there a way to get nodes with their x/y?

  data.nodes.forEach(function (item) {
    console.log('id ' + item.id + ': x: ' + item.x + ', x: ' + item.y);
  });
mztikz commented 7 years ago

Problem is I dont have every time X/Y for each node I wanna set up , there is no one who set up the nodes coordinates , I just dont want the nodes to go back to their previous location every time there is update on the node meta data..

wimrijnders commented 7 years ago

This is clear to me and what I'm aiming at. As I go along I try to address the question you ask along the way.

So, I can get something like what you describe if I do the following:

   data.nodes.update(data.nodes.get());

Would that be representative?

mztikz commented 7 years ago

To set up a random X/Y per node? , isnt it suppose to be set by the stablize? , I mean there is an algorithm that set the nodes on a location.. If I set x/y (randomly) It will not hurt the algorithm location? (barnesHut algorithm for example)

wimrijnders commented 7 years ago

I can confirm this also happens in v4.20.0. As a workaround, I propose the following solution:

On initialization, start up network as is with the first batch of data. So, just the regular:

var network = new vis.Network(container, data, options);

On every subsequent update, remove the x/y from the incoming data. Something like:

  // Strip out xy - assuming new_nodes is a DataSet
  new_nodes.forEach(function (item) {
    item.x = undefined;
    item.y = undefined;
    new_nodes.update(item);
  });

  // Do the update
  data.nodes.update(new_nodes.get());

HTH. I'll be looking within the code if there is a solution there for this.


Update: I just realized that you're probably updating with a reason, namely that the data changes. In that case, you only want to remove the xy from the nodes already present. Something like this would be more appropriate:

  // Strip out xy - assuming new_nodes is a DataSet
  new_nodes.forEach(function (item) {
    // Does this item already exist?
    if (data.nodes.get(item.id) !== undefined) {
      // Then we don't want the coordinates
      item.x = undefined;
      item.y = undefined;
    }
    new_nodes.update(item);
  });

HTH.

wimrijnders commented 7 years ago

isnt it suppose to be set by the stablize?

Sure, but then the xy would not be part of the initialization; it's just runtime data for the network. The goal is to reproduce the situation which causes the issue you report, so some trick is needed to put xy's in the initialization data.

I suppose you could run stabilize, read the coordinates and put them in the data and restart the network with that. Naah, too much work for me now :weary:. I just did a quick loop with a counter. If you must know:

  let count = 0;
  data.nodes.forEach(function (item) {
    data.nodes.update({id: item.id, x: count, y: count});
    count++;
  });

Does the job :wink:.

If I set x/y (randomly) It will not hurt the algorithm location? (barnesHut algorithm for example)

Not at all, the algorithm(s) can deal with that. Depending on option settings, the coordinates will either be fixed, or used as a starting point for stabilization.

mztikz commented 7 years ago

Well I tried it , It helped alot , Thanks alot for the helping , I set x/y to undefined when ever I updated the nodes( Before update) , Its now not jumping to the old X/Y , Thanks alot for the assist and the responsiveness .

wimrijnders commented 7 years ago

My sincere pleasure! If you're happy with the results, please close the issue.....ah, you beat me to it!

Have fun!