GraphStream API: Custom Label Attribute Proxy

The GraphStream API provided by graphstream-project.org is a pretty nice library to work with graphs for analysis, calculation, presentation or anything else.

All elements, such as nodes and edges can carry attributes with any literal key you would like to set ( addAttribute(String key, Object… value) ).
If one opens a graph in the included viewers (e.g graph.display()), a predefined attribute named “ui.label” is checked and any value of the attribute is used as a label in the visualization of this element.

If you would like to derive the label from another custom attribute instead of setting the “ui.label” attribute in parallel, this can be achieved by using the proxy concept of the GraphStream API.

When a graph is opened in a viewer, this can not only be done by simply calling the display method of the graph, but by opening a Viewer explicitly and setting a Proxy in between of the Viewer and the graph itself:


Viewer v = new Viewer(new CustomEdgeLabelAttributeProxy(graph, "my.attribute"));
v.enableAutoLayout();
v.addDefaultView(true);
v.setCloseFramePolicy(CloseFramePolicy.HIDE_ONLY);

This ensures that visualizing the graph in the ui will pass the created nodes, edges and attributes through the CustomEdgeLabelAttributeProxy.
This proxy class is derived from the class ThreadProxyPipe and the method to react on a newly set node attribute is overridden.


@Override
public void sendEdgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value) {
if (attribute.equals(this.labelKey)) {
super.sendEdgeAttributeAdded(sourceId, timeId, edgeId, "ui.label", value);
attribute = "ui.label";
}
super.sendEdgeAttributeAdded(sourceId, timeId, edgeId, attribute, value);
}

The method registers when the custom label attribute, identified by the attribute’s key, passes by. It passes the submitted parameters twice to the super method. Once with the custom attributes id to set this in the GraphicElement as usual, and a second time to set the attribute’s value also for the ui.label attribute to be presented by the viewer.

To also adapt the edge label when the graph respectively the edges are modified when the graph is already updated, you should also override the method

edgeAttributeAdded(String graphId, long timeId, String edgeId, String attribute, Object value)

The implementation of this method follows the same concept as the sendEdgeAttributeAdded() method above.

The proxy provides methods not only for the edge attributes, but also for node and graph attributes to react on.

The complete code of the CustomEdgeLabelAttributeProxy is provided below:


package org.splevo.vpm.analyzer.graph;

import org.graphstream.graph.Graph;
import org.graphstream.stream.thread.ThreadProxyPipe;

/**
* A proxy to change the edge's labels to the value of a custom
* attribute if a value is set for it.
*
* @author Benjamin Klatt
*
*/
public class CustomEdgeLabelAttributeProxy extends ThreadProxyPipe {

/** The key of the label attribute to use instead of the ui.label. */
private String labelKey;

/**
* The constructor for the edge label.
*
* @param graph
* The graph to present.
* @param labelKey
* The label key to be aware of.
*/
public CustomEdgeLabelAttributeProxy(final Graph graph, final String labelKey) {
super(graph, true);

this.labelKey = labelKey;
}

@Override
public void sendEdgeAttributeAdded(String sourceId, long timeId, String edgeId, String attribute, Object value) {
if (attribute.equals(this.labelKey)) {
super.sendEdgeAttributeAdded(sourceId, timeId, edgeId, "ui.label", value);
}
super.sendEdgeAttributeAdded(sourceId, timeId, edgeId, attribute, value);
}
}

Leave a Comment