In this tutorial we will learn how to set up an additional GraphStream module providing a new viewer. This viewer uses the Open Graphic Library (OpenGL) and therefore allows to use the graphic processing unit (GPU) provided now by most computers to display larger graphs more easily. This also adds the ability to see graphs in three dimensions if you want.
Note this module is still in development and does not support the whole set of features of the Java2D/Swing default implementation provided by GraphStream. It particularly does not yet support the full CSS styling properties.
The OpenGL viewer
The usual Swing/Java2D viewer shipped with GraphStream is made to be easily portable. It is available in all environments where a JDK or JRE is available and does not require any more libraries or jars.
However for some operations, Java2D can become slow and CPU intensive. Furthermore as the Java2D name implies, this viewer is limited to planar representations. Some very large graphs may be easier to see and explore in three dimensions.
Therefore a new graph viewer has been created whose goals are to :
- allow to display very large graphs ;
- allow to use the GPU to consume the less CPU as possible for visualisation and make it available for graph algorithms ;
- allow to accelerate some operations that may be slow (transparencies, anti-aliasing, etc.) ;
- allow to draw graphs either in two or three dimensions ;
- provide a new way to explore a graph representation using an "orbiting camera".
Installation
This module is separate since it can eventually becomes quite large, and because it requires additional libraries. Most notably it requires the OpenGL Java implementation provided by the Jogl project. This project will ultimately become a part of future JRE and JDK, but this is not actually the case (however this is the reason why we have chosen it).
Furthermore, as this module is actually in development it must be obtained from the GraphStream SVN repository. This is quite simple :
svn co https://graphstream.svn.sourceforge.net/svnroot/graphstream/GraphStreamUI/trunk GraphStreamUI
This will create a new directory whose name is GraphStreamUI with the sources of the viewer.
To compile it and use it you will also need to fetch the latest Jogl implementation. You can obtain it here.
Download at least the jogl-X.X.X.system.zip (where X.X.X is the version and system is the name of your system). And unpack it.
This archive should contain two important jars jogl.jar and gluegen-rt.jar in its lib directory that you must put in your class path.
The same directory also contains several libraries that you must also make accessible to your JVM. There are several options to do that. The most simple is to use the -Djava.library.path=/the/path/where/you/installed/jogl/lib/ JVM argument. Do not forget that this is an argument of the JVM, and therefore must be placed before the class name. For example java -Djava.library.path=/some/path/jogl/lib/ foo.bar.MyGraphStreamClass.
Depending on you system, there are other ways to configure your environment so that Java finds these libraries. It is for example quite easy to do this in eclipse using "User Libraries". But this is out of the scope of this tutorial.
The GraphStreamUI directory should also contain a lib sub-directory. Place the glutil.jar jar it contains into your class path.
Naturally, the GraphStream jar should also be in your class path.
You are now ready to use the viewer. You can test all went well by running the following class : org.miv.graphstream.ui.ogl.test.TestBasic. You should see a very basic graph with ugly colours in three dimensions. You can orbit around this graph using the left and right arrow keys and reset the camera using the ALT-R shortcut.
How to use the viewer in your programs
There is almost nothing to change compared to the usual Java2D viewer, since the 3D viewer is a drop-in replacement.
You cannot use the graph.display() method since it creates the Java2D viewer for you. Therefore you need to create the viewer yourself, and eventually setup a graph layout algorithm that uses three dimensions instead of two.
First, let's see how to setup a 3D viewer without automatic layout :
GraphViewer viewer = new OglGraphViewer( graph, false, false );
Quite simple.
If for the second constructor argument (autoLayout) you pass the true value, you will obtain a 2D graph layout. However there is another constructor that takes a layout algorithm as argument&nbs;:
GraphViewer viewer = new OglGraphViewer( graph, new org.miv.graphstream.algorithm.layout2.elasticbox.ElasticBox( true ), false );
And you are done.
Naturally, if you do not use the automatic layout, simply using the usual x and y attributes or the xy attribute will not allow you to place your nodes in the 3d space.
To do this, you can use the z attribute in addition of x and y or use the xyz attribute. Here are examples :
Node node = graph.getNode("A");
node.setAttribute( "x", 1 );
node.setAttribute( "y", 2 );
node.setAttribute( "z", 3 );
or :
Node node = graph.getNode("A");
node.setAttribute( "xyz", 1, 2, 3 );
Here is a complete basic example :
import org.miv.graphstream.graph.Graph;
import org.miv.graphstream.graph.implementations.MultiGraph;
import org.miv.graphstream.ui.GraphViewer;
import org.miv.graphstream.ui.ogl.OglGraphViewer;
public class TestBasic {
public static void main( String args[] ) {
new TestBasic();
}
public TestBasic() {
Graph graph = new MultiGraph( "In 3D !!", false, true );
GraphViewer viewer = new OglGraphViewer( graph, false, false );
viewer.setQuality( 0 );
graph.addEdge( "AB", "A", "B" );
graph.addEdge( "BC", "B", "C" );
graph.addEdge( "CD", "C", "D" );
graph.addEdge( "DA", "D", "A" );
graph.getNode("A").setAttribute( "xyz", -1, 0, 1 );
graph.getNode("B").setAttribute( "xyz", 0, 1, 0 );
graph.getNode("C").setAttribute( "xyz", 1, 0, 0 );
graph.getNode("D").setAttribute( "xyz", 0, -1, -1 );
}
}
The viewer is in development. There are five quality levels. Actually only the zero-th quality level is activated. This level is created to provide the maximum performance using OpenGL vertex buffer objects. It does not support a large set of the CSS styling possibilities offered by the standard viewer. You can only assign colors to individual elements. You can specify widths, border widths and border colors, but only for node, edge and sprite selectors (that is for the whole node, edge or sprite sets, not for individual elements).
You can also put a border on the graph selector so that a 3D enclosing box is drawn around your graph. This should make it more easy to see in 3D. Here is a simple style sheet that works well :
graph { background-color: white; border-width: 0.5px; border-color: #808080; }
edge { width: 1px; border-width: 2px; border-color: white; }
node { width: 5px; border-width: 2px; border-color: white; }
Developing extensions for the OpenGL viewer
This viewer is built around a "pluggable renderer" architecture.
To do ...