2

i'm writing an eclipse plugin that draws a finite state system. since it may be large, i'd like to attach some existing graph layout algorithm (e.g. hierarchical layout, force-based layout, ...) that automatically optimize the system visualization.

is there a way to integrate the plugin i'm writing (written using GEF) so that generated edit parts could be place on the editor area following some of the common graph layout algorithms?

i've found this interesting article but instead of optimizing edit parts visualization, it focuses on drawing a completely new graph.

so far what I'm doing is adding the following code (based on Zest 1)

private static void createNewGraph(String autName) {
    Shell tmpShell = new Shell();
    currGraph = new Graph(tmpShell, SWT.NONE);
    mapStateAndNodes = new HashMap<State, GraphNode>();
}

private static void addGraphNode(State currState)
{
    GraphNode newNode = new GraphNode(currGraph, SWT.NONE, currState.getName());
    mapStateAndNodes.put(currState, newNode);
}

private static void addGraphConnection(Transition currTrans)
{
    GraphNode source = mapStateAndNodes.get(currTrans.getOrigState());
    GraphNode dest = mapStateAndNodes.get(currTrans.getDestState());

    GraphConnection newConn = new GraphConnection(currGraph, SWT.NONE, source, dest);

}

private static void completeGraph()
{
    currGraph.setLayoutAlgorithm(new SpringLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING), true);
}

and while building my model, I also call createNewGraph(...), addGraphNode(...), addGraphConnection(...) and completeGraph(...). the problem is: after currGraph.setLayoutAlgorithm(..., true) that true means it should apply the algorithm and place the objects in the "right" order. at this point (as suggested from some reader), it is possible to extract the computed coordinates through a GraphNode.getLocation() method. unfortunately after setting a layout and applying it, all the states have Point(0,0) as their location. i also found this comment:

/**
 * Runs the layout on this graph. It uses the reveal listener to run the
 * layout only if the view is visible. Otherwise it will be deferred until
 * after the view is available.
 */
 public void applyLayout() {
     ...
 }

in org.eclipse.zest.core.widgets.Graph sources :-[ to me it seems i cannot use zest Graph library to do this job. am i wrong? are there any alternatives?

any help would be appreciated :)

FSp
  • 1,545
  • 17
  • 37

1 Answers1

3

In short, Zest does not support this scenario directly.

However, you can build an in-memory representation of you edit parts that can be layouted using Zest. In Zest 1.0 you have to provide a translation to Graph Nodes and Graph Arcs Relations manually; in Zest 2.0 you only have to provide a LayoutContext. Zest 2.0 is not released yet, but it seems easier for me to handle this scenario.

Additional idea: the open source project Spray support Zest layouting for Graphiti graphs (Graphiti extends GEF - maybe there are some ideas that can be reused). See the following code file: http://code.google.com/a/eclipselabs.org/p/spray/source/browse/plugins/org.eclipselabs.spray.runtime.graphiti.zest/src/org/eclipselabs/spray/runtime/graphiti/zest/features/ZestLayoutDiagramFeature.java for some ideas.

EDIT: I looked into a related code in my computer; we managed to get such layouting to work in Zest 1.0 the following way:

  1. Have a single GraphNode for each node, and a Connection for each arc between the nodes. You can collect them into two different arrays; e.g. SimpleNode[] nodes; SimpleRelationship[] relationships;
  2. Instantiate an algorithm class, and set your optional parameters as you like.
  3. Call algorithm.applyLayout(nodes, relationships, 0, 0, diagram.width, diagram.height, false, false) - sorry, don't have an available Zest 1.0 installation to check the exact meanings of the parameters; the first two are the nodes and relationships used; then the next four sets the drawing board; and I honestly have no idea what are the final two for. :D

Further clarification: Zest uses nodes and relations as a terminology - replace my previous arc with relation.

Zoltán Ujhelyi
  • 13,788
  • 2
  • 32
  • 37
  • i edited my question and added some code that does what you suggested. my problem is that i don't know how to extract the computed coordinates from the `Graph` object :-/ also, i wonder whether i could directly apply an algorithm from zest library to my objects... – FSp Jan 18 '12 at 12:05
  • You have to maintain a link between the GraphNodes and your model object (e.g. by using a hashtable, or using the GraphNode objects model object store). Then you can iterate trough all Nodes, get their coordinates (if I remember correctly, there is a getPosition or getX kind of method on GraphNodes that you can use). About direct application: as Zest layout algorithms expect specific inputs, you have to translate for it. The input is less restrictive in Zest 2.0, so it would be easier to translate to, but it is still possible in Zest 1.0. – Zoltán Ujhelyi Jan 18 '12 at 12:44
  • hello, i edited again my question to make it more precise. nevertheless, to me it seems i cannot use zest to compute a layout for my graph without actually showing it :[ – FSp Jan 18 '12 at 23:16
  • I also edited my answer, and tried to provide a more step-by-step usage for layouting by Zest. This method is tried, I have seen it working. :D – Zoltán Ujhelyi Jan 19 '12 at 00:09