How to Animate Graphs
Questions & AnswersSummary
Description
yFiles supports custom graph animations by means of implementations for interface AnimationObject.
The central methods defined by AnimationObject are initAnimation() and calcFrame(double).
They initialize an animation, respectively calculate the animation steps for the overall animation process.
Finally, disposeAnimation() disposes of an animation.
The following sample code shows how to create a custom graph animation.
It uses an AnimationObject implementation to show a graph's nodes and edges one by one.
This animation can be quite useful when presenting a graph to others.
It gives you the possibility to walk through the graph and go into each node's details.
What the sample code does:
- Initializes the animation by putting all graph elements into a list and hiding them from the graph.
- Defines an animation step by unhiding one of the graph elements in the implementation for AnimationObject.calcFrame(double).
- Disposes the animation by resetting the list.
package demo.view;
import y.anim.AnimationObject;
import y.base.*;
import y.util.Maps;
import y.view.*;
/**
* Animation object that successively unhides nodes and edges of a graph.
*/
public class GraphPresenter implements AnimationObject
{
Graph2D graph;
YList order;
Graph2DView view;
int all;
public GraphPresenter(Graph2DView view)
{
graph = view.getGraph2D();
this.view = view;
all = graph.N() + graph.E();
}
public void initAnimation()
{
// List of all graph elements.
order = new YList();
// Helper map to check if opposite node is already in element list.
NodeMap markMap = Maps.createIndexNodeMap(new boolean[graph.N()]);
NodeList nList = new NodeList(graph.nodes());
while (!nList.isEmpty())
{
Node v = nList.popNode();
// Add node to element list.
order.add(v);
markMap.setBool(v, true);
for (EdgeCursor ec = v.edges(); ec.ok(); ec.next())
{
Edge e = ec.edge();
// Add edge to element list if opposite node is already in it.
if (markMap.getBool(e.opposite(v)))
order.add(e);
}
}
// Hide all nodes (and edges).
while (!graph.isEmpty())
graph.hide(graph.firstNode());
}
/**
* Calculates the animation frame for the given point in time.
* Do not call this method directly.
* It is used by the animation framework classes.
*/
public void calcFrame(double time)
{
if (time >= ((double)(all + 1) - order.size()) / all)
{
if (order.first() instanceof Node)
graph.unhide((Node)order.pop());
else if (order.first() instanceof Edge)
graph.unhide((Edge)order.pop());
}
}
/**
* Disposes the animation. Do not call this method directly.
* It is used by the animation framework classes.
*/
public void disposeAnimation()
{
order = null;
}
/**
* Returns the animation's preferred duration in milliseconds.
*/
public long preferredDuration()
{
return 5000;
}
}
To start the animation, simply set up an AnimationPlayer with the view that contains your graph as an animation listener and tell the player to execute your animation object.
The following code snippet does so after performing a layout to the graph:
// Perform a layout.
new BufferedLayouter(layouter).doLayout(view.getGraph2D());
// Set up an AnimationPlayer.
AnimationPlayer player = new AnimationPlayer();
// Register the view as an animation listener.
player.addAnimationListener(view);
// Play the animation object.
player.animate(new GraphPresenter(view));