Hierarchycal graph on Tulip

Some variables:

  • input: the input (original) graph
  • orig: the same input graph, but it is made as a sub graph of input.
  • meta: a node that represents a sub graph

Creating a subgraph

Case: Some of nodes in the original graph will be grouped as a sub graph. Those nodes in the original graph will then be replaced with a (meta) node that represents that sub graph.

Precondition: The original graph must not be the root graph. Create a sub graph of it first that contains the same nodes and edges.

Graph* orig = input->getRoot()->addSubGraph();
copy(input, orig);

Subgraph creation

set<node> nodes = [ list of nodes of the original graph (input) that will be subgraph-ed ]
node meta = tlp::createMetaNode(orig, nodes);

Two local properties of the input will be created: viewMetaNode and viewColor.

viewMetaNode property contains mapping from meta node to the sub graph that it represents.

Edges to nodes in the sub graph will changed. They will be pointed to the meta node after the sub graph is created. However, the original information about the edges is saved, so it can be restored later.

Getting created subgraph

GraphProperty* gp = input->getLocalProperty<GraphProperty*>("viewMetaNode");
Graph* subgraph = gp->getNodeValue(meta);

Restoring a sub graph to its “parent”

tlp::openMetaNode(orig, meta)

Edges connections will be restored.

Remarks

  1. The copy function (taken from GrouseFlocks):
    void copy (Graph *src, Graph *dest) {
      StableIterator <node> nodes (src->getNodes());
      while (nodes.hasNext()) dest->addNode (nodes.next());
      StableIterator <edge> edges (src->getEdges());
      while (edges.hasNext()) dest->addEdge (edges.next());
    }//end copyFeature
    
  2. Edges in a directed graph are handled nicely. Might be a problem if you only expect at most one edge for every pair of nodes (simple graph)
  3. Sub graphs can contain other sub graphs
  4. Opening a sub graph inside another sub graph may lead into a problem. Open the outer subgraph first to avoid unexpected problem.

Hierarchycal graph on Tulip

Some variables:

  • input: the input (original) graph
  • orig: the same input graph, but it is made as a sub graph of input.
  • meta: a node that represents a sub graph

Creating a subgraph

Case: Some of nodes in the original graph will be grouped as a sub graph. Those nodes in the original graph will then be replaced with a (meta) node that represents that sub graph.

Precondition: The original graph must not be the root graph. Create a sub graph of it first that contains the same nodes and edges.

Graph* orig = input->getRoot()->addSubGraph();
copy(input, orig);

Subgraph creation

set<node> nodes = [ list of nodes of the original graph (input) that will be subgraph-ed ]
node meta = tlp::createMetaNode(orig, nodes);

Two local properties of the input will be created: viewMetaNode and viewColor.

viewMetaNode property contains mapping from meta node to the sub graph that it represents.

Edges to nodes in the sub graph will changed. They will be pointed to the meta node after the sub graph is created. However, the original information about the edges is saved, so it can be restored later.

Getting created subgraph

GraphProperty* gp = input->getLocalProperty<GraphProperty*>("viewMetaNode");
Graph* subgraph = gp->getNodeValue(meta);

Restoring a sub graph to its “parent”

tlp::openMetaNode(orig, meta)

Edges connections will be restored.

Remarks

  1. The copy function (taken from GrouseFlocks):
    void copy (Graph *src, Graph *dest) {
      StableIterator <node> nodes (src->getNodes());
      while (nodes.hasNext()) dest->addNode (nodes.next());
      StableIterator <edge> edges (src->getEdges());
      while (edges.hasNext()) dest->addEdge (edges.next());
    }//end copyFeature
    
  2. Edges in a directed graph are handled nicely. Might be a problem if you only expect at most one edge for every pair of nodes (simple graph)
  3. Sub graphs can contain other sub graphs
  4. Opening a sub graph inside another sub graph may lead into a problem. Open the outer subgraph first to avoid unexpected problem.

Tulip plugin problem on MacOS X

So, you thought that you have failed compiling Tulip on MacOS X? The plugins can’t get loaded? Can’t find the dylib files?

Look again! Check files inside the lib directory. Let me show you mine.

[email protected] ~/apps/tulip-3.1.0/lib
$ file *
libtulip:                    symbolic link to `libtulip-3.1'
libtulip-3.1:                Mach-O dynamically linked shared library i386
libtulip-ogl:                symbolic link to `libtulip-ogl-3.1'
libtulip-ogl-3.1:            Mach-O dynamically linked shared library i386
libtulip-ogl.la:             ASCII English text
libtulip-pluginsmanager:     symbolic link to `libtulip-pluginsmanager-3.1'
libtulip-pluginsmanager-3.1: Mach-O dynamically linked shared library i386
libtulip-pluginsmanager.la:  ASCII English text, with very long lines
libtulip-qt4:                symbolic link to `libtulip-qt4-3.1'
libtulip-qt4-3.1:            Mach-O dynamically linked shared library i386
libtulip-qt4.la:             ASCII English text, with very long lines
libtulip.la:                 ASCII English text
tlp:                         directory

Files that have “Mach-O dynamically linked shared library i386” as their description are surely interesting. Why don’t they have a .dylib extension? You can find a similar “phenomenon” inside the tlp directory which contains Tulip plugins. Where is the extension gone?

Since Tulip checks for .dylib extension on MacOS X, it would not be able to load the plugins. Because they are simply not there. No files with that extension. The application loads very fast since no plugins found. And you also can’t do much since Tulip is (probably) nothing without plugins.

I don’t know why the configuration scripts or the compiler or the linker or whatever it is don’t create shared libraries with .dylib extension. But as a workaround, I found a simple solution to make Tulip recognize the libraries. Just by simply adding the extension!

One simple command and all is done.

$ ls *-3.1 *-3.1.0 | while read file; do ln -s $file $file.dylib; done

Run that inside the lib, lib/tlp, lib/tlp/glyph, and lib/tlp/view directories. Maybe inside lib/tlp/designer too. Don’t worry when it tells “No such file or directory”.

And.. now you have it.

Tulip plugin problem on MacOS X

So, you thought that you have failed compiling Tulip on MacOS X? The plugins can’t get loaded? Can’t find the dylib files?

Look again! Check files inside the lib directory. Let me show you mine.

[email protected] ~/apps/tulip-3.1.0/lib
$ file *
libtulip:                    symbolic link to `libtulip-3.1'
libtulip-3.1:                Mach-O dynamically linked shared library i386
libtulip-ogl:                symbolic link to `libtulip-ogl-3.1'
libtulip-ogl-3.1:            Mach-O dynamically linked shared library i386
libtulip-ogl.la:             ASCII English text
libtulip-pluginsmanager:     symbolic link to `libtulip-pluginsmanager-3.1'
libtulip-pluginsmanager-3.1: Mach-O dynamically linked shared library i386
libtulip-pluginsmanager.la:  ASCII English text, with very long lines
libtulip-qt4:                symbolic link to `libtulip-qt4-3.1'
libtulip-qt4-3.1:            Mach-O dynamically linked shared library i386
libtulip-qt4.la:             ASCII English text, with very long lines
libtulip.la:                 ASCII English text
tlp:                         directory

Files that have “Mach-O dynamically linked shared library i386” as their description are surely interesting. Why don’t they have a .dylib extension? You can find a similar “phenomenon” inside the tlp directory which contains Tulip plugins. Where is the extension gone?

Since Tulip checks for .dylib extension on MacOS X, it would not be able to load the plugins. Because they are simply not there. No files with that extension. The application loads very fast since no plugins found. And you also can’t do much since Tulip is (probably) nothing without plugins.

I don’t know why the configuration scripts or the compiler or the linker or whatever it is don’t create shared libraries with .dylib extension. But as a workaround, I found a simple solution to make Tulip recognize the libraries. Just by simply adding the extension!

One simple command and all is done.

$ ls *-3.1 *-3.1.0 | while read file; do ln -s $file $file.dylib; done

Run that inside the lib, lib/tlp, lib/tlp/glyph, and lib/tlp/view directories. Maybe inside lib/tlp/designer too. Don’t worry when it tells “No such file or directory”.

And.. now you have it.

Calling a Plugin in Tulip

After digging Tulip‘s code for several days, I still couldn’t find out how to load and run a plugin. This afternoon, my thesis project assistant sent me a working sample code that does what I want! Only in one or two days I guess. Oh God, he’s so fast!

This is how it’s done.

  1. Initialize Tulip. At least I can figure this out myself 🙂

    tlp::initTulipLib();
    tlp::loadPlugins();
    
  2. Check the existence of a plugin.

    string layoutName = "Circular";
    tlp::LayoutProperty::factory->pluginExists(layoutName);
    
  3. And this is the most important chunk of code that I’m looking for.

    tlp::LayoutProperty *myLayout = graph->getProperty<tlp::LayoutProperty>("viewLayout");
    graph->computeProperty(layoutName, myLayout, errorMsg);
    

After that, the layouting is hopefully done. We only need to iterate the vertices and get position of each vertex.

tmp1 = myLayout->getNodeValue(n);
printf("node: %d, x=%f, y=%f, z=%fn", n.id, tmp1.getX(), tmp1.getY(), tmp1.getZ());