In this first tutorial we will meet the Graph class and see basic ways of handling it.

Creating a graph
Although you can do several things without a Graph object, like loading or writing data, or displaying things, most of the time you will need a data structure that represents the graph you plan to work with. The Graph interface models such a concept.
It is an interface because you can instantiate several kinds of graphs, depending on your needs. There may exist many implementations of the Graph interface that are faster, smaller in memory, have a specific internal representation, etc. but most of the time you will work either with DefaultGraph that is a bit faster or AdjacencyListGraph that is a bit smaller in memory. If you have a doubt, just choose DefaultGraph.
Let's see the structure of a program that uses GraphStream :
import org.miv.graphstream.graph.*;
import org.miv.graphstream.graph.implementations.*;
public class TutorialBase001 {
public static void main( String args[] ) {
new TutorialBase001();
}
public TutorialBase001() {
Graph graph = new DefaultGraph();
}
}
That's cool, but we have not done something useful with our graph. Let's populate it with edges and nodes to create a triangle :
public TutorialBase001() {
Graph graph = new DefaultGraph( "Triangle" );
graph.addNode( "node1" );
graph.addNode( "node2" );
graph.addNode( "node3" );
graph.addEdge( "edge1", "node1", "node2" );
graph.addEdge( "edge2", "node2", "node3" );
graph.addEdge( "edge3", "node3", "node1" );
}
Some new things appeared. First we changed the DefaultGraph constructor to pass a title or name to our graph. Then we used the addNode() and addEdge() methods. Adding a node requires only to provide a new unique name for this node. Adding an edge requires the name of two nodes and a new unique name for an edge. Notice that an edge can have the same name than a node. However this is probably a bad practice.
Displaying it
We have our graph. However one often needed feature, is to be able to visualise it (as well as visualise data on it). There exist plenty of ways for displaying graphs and accompanying data in GraphStream, but perhaps the most easy is the Graph.display() method :
public TutorialBase001() {
Graph graph = new DefaultGraph( "Triangle" );
graph.addNode( "node1" );
graph.addNode( "node2" );
graph.addNode( "node3" );
graph.addEdge( "edge1", "node1", "node2" );
graph.addEdge( "edge2", "node2", "node3" );
graph.addEdge( "edge3", "node3", "node1" );
graph.display();
}
You should end up with a display that looks like this :

This is a quick and easy way to check all went down as expected. However you will see in future tutorials that GraphStream has some more graph viewing capabilities.
Directed graphs
Often directed and undirected graphs are two independent concepts. In GraphStream however, one can create a totally undirected graph, totally directed or mixed. There are no such method as Graph.isDirected(), however it is possible to tell an edge is directed or not when the edge is created. For example changing the example above with :
graph.addEdge( "edge1", "node1", "node2", true );
would make only the edge 'edge1' directed. The graph viewer is able to see this and adds an arrow to the edge. The direction is given by the order of the nodes. Here the edge source is "node1" and the edge target is "node2".
As GraphStream is made to handle dynamic graphs, it is possible once an edge has been declared directed to change its direction or even to make it undirected. But this will be seen in another tutorial.
Some remarks on what have been done
What you can notice in the graph display is that the graph shapes up automatically so that it is easier to visualise. Nodes and edges choose their position in the window to minimise edge crossing and layout the graph as clearly as possible. This automatic layout feature is naturally optional and can be turned off. We will see this in a later tutorial when we will know how to position nodes using absolute coordinates.
The second thing to notice is the way nodes and edges are created. Some graph libraries let you create the node and edge objects first then to insert them in the graph in a second operation. Here the graph is the "factory" for the nodes and edges. This allows to instantiate the correct node and edge class for the chosen graph implementation easily. Furthermore, the graph can check the consistency of the requested operation. For example when an edge is created, one often want that the nodes it references exist. This is an optional part of the Graph interface. It can check these things for you.
An additional benefit of this way of doing is that you can request the graph to create things for you so that each operation is legal. For example, using the Graph.setAutoCreate() method, when you declare an edge without having declared the nodes it connect before, these nodes will be created for you. For example :
public TutorialBase001() {
Graph graph = new DefaultGraph( "Triangle" );
graph.setAutoCreate( true );
graph.addEdge( "edge1", "node1", "node2" );
graph.addEdge( "edge2", "node2", "node3" );
graph.addEdge( "edge3", "node3", "node1" );
graph.display();
}
The example above is a simplified version of the tutorial that is also usable. We find it less clear, but it can be easier to write.
The last thing worth to notice in this example is the way nodes and edges are identified. Here we are faced to a choice of implementation that has been made when creating GraphStream. Several graph libraries consider nodes as being integers. This is often easy and consumes less memory, however this is by far less flexible. We chosen to be compatible with all graph file formats and to support nodes (and edges) addressed by a string identifier. There are a lot of operations that can not be carried with integer identifiers.