# GraphStream Tutorials

### Let's get some coding done

DGS0004
cg "id":"GraphStream Team"
an "Stefan Balev"
an "Antoine Dutot"
an "Yoann Pigné"
an "Guilhelm Savin"

## Outlook

1. Installation of GraphStream
2. Tutorial 1: Basic tasks with GraphStream
3. Tutorial 2: A first dynamic graph

# Installation of GraphStream

Basic steps to install GraphStream

1. Get a working java SDK installed
2. Get Eclipse installed
3. Get the GraphStream CSSS2012 tutorial workspace
4. Get GraphStream binaries

## Get the tutorial workspace

### Let's run it

• Start Eclipse form the application inside the eclipse folder.
• When asked about a workspace, indicate the GraphStreamWorkspace folder.

## Get GraphStream binaries

• Go to the GraphStream Nightly Builds page at:
http://graphstream-project.org/pub/1.x/nightly-build/last/
• We need the 3 binaries
• gs-algo-1.2-git-last.jar
• gs-core-1.2-git-last.jar
• gs-ui-1.2-git-last.jar
• Save those jar files in the lib/ folder of the CSSS-2012-Demos project.
• Right-clic on the CSSS-2012-Demos, then properties, then Java build path (left panel), then libraries (right panel), then clic the Add jars button, and select our 3 jar files in the CSSS-2012-Demos/lib folder.

# Tutorial 1

## Creating a basic graph and displaying it

Open CSSS-2012-Demos > src > org > graphstream > csssdemo > tutorial1 > Tutorial1.java:

import org.graphstream.graph.*;
import org.graphstream.graph.implementations.*;

public class Tutorial1 {
public static void main(String args[]) {
Graph graph = new SingleGraph("Tutorial 1");

graph.display();

graph.addEdge("BC", "B", "C", true); // Directed edge.
}
}

We can improve the display with some CSS:

...
graph.display();

"edge { fill-color: grey; }");

...

• Each node, edge and attribute is identified by an unique string.
• The node and edge elements are created for you.
• You can access them however, when created:
Node n = graph.addNode("A");
• Or after creation:
Node n = graph.getNode("A");

• You can remove nodes and edges the same way:
graph.removeNode("A");
• You can change the graph this way at any time. Each change is considered as an “event”.
• The sequence of changes is seen as the dynamics of the graph.
• There are many other ways to modify the graph.

• Data stored in the graph, on nodes and edges, are called “attributes”.
• An attribute is a pair (name,value).

Edge ab = graph.getEdge("AB");
Edge bc = graph.getEdge("BC");
Edge ca = graph.getEdge("CA");

ab.setAttribute("ui.label", "AB");
bc.setAttribute("ui.label", "BC");
ca.setAttribute("ui.label", "CA");

• But you can add any kind of data on each graph element.
• However not all attributes appear in the viewer.
• Notice the way you can add arrays with setAttribute() and a variable number of arguments:

ab.setAttribute("aNumber", 10);
bc.setAttribute("anObject", new Double(10));
ca.setAttribute("anArrayOfThings", 1, 2, 3);

• You can access attributes in several ways:

int value1 = ((Number) ab.getAttribute("aNumber")).intValue();
double value2 = bc.getAttribute("anObject");
Object[] value3 = ca.getAttribute("anArrayOfThings");

• Special methods are here to simplify things:

double value4 = ab.getNumber("aNumber");
double value5 = bc.getNumber("anObject");

• Travelling through all nodes of the graph is easy:

for(Node n: graph) {
System.out.println(n.getId());
}

• The same for edges:

for(Edge e: graph.getEachEdge()) {
System.out.println(e.getId());
}

• You can also do it with iterators:

Iterator<? extends Node> nodes = graph.getNodeIterator();

while(nodes.hasNext()) {
System.out.println(nodes.next().getId());
}

• The same for edges:

Iterator<? extends Edge> edges = graph.getEdgeIterator();

while(edges.hasNext()) {
System.out.println(edges.next().getId());
}		

• Or even with indices:

int n = graph.getNodeCount();

for(int i=0; i<n; i++) {
System.out.println(graph.getNode(i).getId());
}

• The same for edges:

int n = graph.getEdgeCount();

for(int i=0; i<n; i++) {
System.out.println(graph.getEdge(i).getId());
}


Be careful: indices remains the same as long as the graph is unchanged, but as soon as an addition or removal occurs, indices are no more tied to their old node or edge.

• You can also travel the graph using nodes:

import static org.graphstream.algorithm.Toolkit.*;
...
Node node = randomNode(graph);

for(Edge e: node.getEachEdge()) {
System.out.printf("neighbor %s via %s%n",
e.getOpposite(node).getId(),
e.getId() );
}


• Toolkit is a collection of often used methods and small algorithms.
• Each node and edge allows to iterate on its neighbourhood.

• You can iterate on directed edges:

Node node = getRandomNode(graph);
Iterator<? extends Edge> edges = node.getLeavingEdgeIterator();

• Or:

Iterator<? extends Edge> edges = node.getEnteringEdgeIterator();

• And get the node degree, entering or leaving:

System.out.println(“Node degree %d (entering %d, leaving %d)%n”,
node.getDegree(),
node.getInDegree(),
node.getOutDegree());

# Tutorial 2

## A first dynamic graph

• Each graph is a source of events.
• You can connect to any source using the Source.addSink(Sink) method.
• You can choose to receive only events concerning the graph structure with addElementSink(ElementSink). Elements are nodes and edges.
• You can choose to receive only events concerning data attributes stored on elements with addAttributeSink(AttributeSink).
• A Sink is only an empty interface inheriting ElementSink and AttributeSink.

## A first dynamic graph

An element sink must follow the interface:

public interface ElementSink {
void nodeRemoved( ... );
void edgeRemoved( ... );
void graphCleared( ... );
void stepBegins( ... );
}

## A first dynamic graph

An attribute sink must follow the interface:

public interface AttributeSink {
void graphAttributeChanged( ... );
void graphAttributeRemoved( ... );

void nodeAttributeChanged( ... );
void nodeAttributeRemoved( ... );

void edgeAttributeChanged( ... );
void edgeAttributeRemoved( ... );
}

## A first dynamic graph

A source is an interface that only defines methods to handle a set of sinks.

public interface Source {
void removeSink(Sink sink);
void removeAttributeSink(AttributeSink sink);
void removeElementSink(ElementSink sink);
void clearElementSinks();
void clearAttributeSinks();
void clearSinks();
}

## A first dynamic graph

These three interfaces are the most important of GraphStream.

## A first dynamic graph

• As the graph is also a sink, you could use these methods to create the graph.
• But a better way is to send graph events using an existing source, like a file.
• Few graph file formats are dynamic.
• GraphStream provides a format named DGS that allows to store and load dynamic graphs.

## A first dynamic graph

A DGS file looks like this. You can find it in the Tutorial2 > tutorial2.dgs

DGS003
"Tutorial 2" 0 0
an "A"
an "B"
an "C"
ae "AB" "A" "B"
ae "BC" "B" "C"
ae "CA" "C" "A"
ce "AB" label="AB"
ce "BC" label="BC"
ce "CA" label="CA"
• an add a node and ae an edge.
• ae "AB" "A" > "B" adds a directed edge.
• cn, ce and cg change or add one or more attributes on a node, edge or graph.
• dn and de allow to remove nodes, edges.

## A first dynamic graph

• Each change in the graph is an event.
• However you may want to define a notion of time, and group some events as occurring "at the same time".
• You can do this using a step.
• The DGS notion for steps is st <number>.

## A first dynamic graph

• The ability to remove nodes and edges make the format dynamic.
• Add this to the previous DGS file:
st 2
an "D"
an "E"
ae "BD" "B" "D"
ae "CE" "C" "E"
ae "DE" "D" "E"
de "AB"
dn "A"
st 3
• And save it.

## A first dynamic graph

• We will now read this file.
• This can be done in one simple operation :

graph.read("tutorial2.dgs");

• However this will "play" all events as fast as possible.
• We have no control over the speed at which events occur.
• This form of reading is an utility method of the Graph interface allowing to read static graphs from all the supported file formats.

## A first dynamic graph

• We can read the DGS file event by event using an input source:

public class Tutorial2 {
public static void main(String args[]) {
Graph graph = new SingleGraph("Tutorial2");
graph.display();
try {
FileSource source = FileSourceFactory.sourceFor(
"tutorial2.dgs");
source.begin("tutorial2.dgs");
while(source.nextEvents());
source.end();
} catch(Exception e) { e.printStackTrace(); }
}
}

## A first dynamic graph

• We read the file event by event (line by line in the file), however it still does it as fast as it can.
• Note the line while(source.nextEvents()); that does the job.
• Also note that we have to call the begin() and end() methods before and after reading to cleanly open and close the file.

		while(source.nextEvents()) { Thread.sleep(1000); }

• We can also run it step by step so that events between two step appear together

  		while(source.nextStep()) { Thread.sleep(1000); }

## A first dynamic graph

• The graph is automatically reshaped for you.
• However you may want to position nodes by yourself.
• You can do this using the x and y attributes:

an "A" x=0 y=1
an "B" x=1 y=-1
an "C" x=-1 y=-1

• And:

an "D" x=1 y=1
an "E" x=-1 y=1

## A first dynamic graph

• You have to tell the viewer it should not place nodes for you:

	graph.display(false);

• You can now run the program anew.

## Slides and Material

Get the Slides and Materials for this session on GraphStream tutorial page at:

Use arrow keys to navigate