Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement: animate nodes into new position #45

Closed
FrissAnalytics opened this issue Jan 22, 2016 · 6 comments
Closed

enhancement: animate nodes into new position #45

FrissAnalytics opened this issue Jan 22, 2016 · 6 comments

Comments

@FrissAnalytics
Copy link

Hi,

I was wondering, with the current api of vis.js, would it be possible to animate a set of nodes into a new position, in which the user can specify the final x and y coordinates? I know in vis.js one can explicitly provide x and y coordinates, however, I didn't see a way to animate the transition from old to new.

Given the fact that nodes and edges can be made to move based on tick events and the fact that there is a animated 'fit network to screen dimensions' I think it would be possible. However, I couldn't find out to do this. Then again, perhaps it's just not possible.

http://stackoverflow.com/questions/32902720/vis-js-place-node-manually

http://stackoverflow.com/questions/31159422/vis-js-fit-a-set-of-nodes-on-screen

kind regards, Herman

@bthieurmel
Copy link
Contributor

Hi,

We can perhaps use the moveNode method (http://visjs.org/docs/network/#methods) for move just a node. I think there is actually no way to move all nodes, with some animation.
The moveNode method is not yet in visNetwork, but it's quite simple to add this feature using a visNetworkProxy,object.

@bthieurmel
Copy link
Contributor

You can also try to use setData with visSetData for passing new data (in your case same data with new coordinate), and see what happened ....? This method delete all previous data.

@bthieurmel
Copy link
Contributor

For some dynamically change with shiny, you can now have a look to new features visUpdateNodes and visUpdateEdges. Related to #50

@FrissAnalytics
Copy link
Author

Hi,

I made a simple example of the use of moveNode as you suggested, see here:

https://gist.github.com/FrissAnalytics/ecf8cfc756b5fcbb8766

Basically you have an original set of x,y coordinates and a target set of x,y coordinates for each node and then you create a convex combination of the two for each node and move the node to that position. In the example I've set up a tick event every 10ms, with a total animation time of 500ms. In the loop I compute what lambda (l) in the convex combination should be at a given iteration (k).

In the example all nodes start at 0,0, and then move into the position as computed by the force layout. Obviously it's just a toy example.

It sort of works, but my javascript code skill is very limited so for something useful a better implementation can be made for sure. Also, in the example there is no easing function. I don't know if this approach makes sense, but I think it can be made to work.

Obviously I would be nicer if the guys from vis.js made a function like this, but certainly for your extension to include layouts from iGraph a transition from one layout to another would be very cool.

Do you see a better way?

kind regards, Herman

@FrissAnalytics
Copy link
Author

fyi: I send a request to the vis.js authors to add an options to the moveNode method:

almende/vis#1703

@kudlas
Copy link

kudlas commented Mar 1, 2019

Hey I made this function, for animating Nodes using requestAnimationFrame instead of setTimeout.

function moveNodeAnim(nodeId, finX, finY, duration) {
            let startPos = network.getPositions([nodeId])[nodeId];
            let startX = startPos.x;
            let startY = startPos.y;
            let startTime = performance.now();
            let _duration = duration || 1000;

            let move = (function () {
                let time = performance.now();
                let deltaTime = (time - startTime) / _duration;
                let currentX = startX + ((finX - startX) * deltaTime);
                let currentY = startY + ((finY - startY) * deltaTime);

                if (deltaTime >= 1) {
                    network.moveNode(nodeId, finX, finY);
                } else
                {
                    network.moveNode(nodeId, currentX, currentY);
                    window.requestAnimationFrame(move);
                }
            });

            move();

        }

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

No branches or pull requests

3 participants