2.2. Getting more control by action files

Reproduciblity can be a very important expectation while working with graphs. This can be fulfilled easier if you need to write down the actions that you initiate even if you are just asking Glay to set the sizes of all the vertices to 0.3.

Maybe the previous argument seems to be only a poor apology for not having a complete and advanced gui interface. However, experience shows that providing a scripting way of control is very important: good user interfaces can built on top of them, but it is hard to create a scripting environment for a gui-based program design. (Some well-known cad programs are very good examples for both category.)

In this section we will see how to use action files. It is very straightforward to use or combine them without any knowledge of programming. Creating completely new actions however requires the knowledge of the Perl language.

2.2.1. Using existing action files

You can initiate an action by using the -a parameter, followed by the name of the action file and maybe some arguments of that particular action, for example

glay ... -a sizes 0.2 0.1 ...
means to run the builtin action called sizes with parameters 0.2 and 0.1.

Actions are searched first in the path given for Glay in the GLAYACTIONPATH environment variable, and then in the builin action paths. If GLAYACTIONPATH is empty, then it is initialized to a simple "." which means "current directory".

You can list all the actions seen available by Glay with the command

glay -a list_actions | less

There are a lot of small actions needed when visualizing a graph, the already mentioned sizes being one of them. See for a list of the builtin actions.

FIXME: chap_reference megirando

2.2.2. Combining action files into a new action file

Action files are plain series of commands, no invocations like "#include <stdio.h>" are necessary. You can run actions with the "action" command, followed by the name of the action and optionally the parameters of that particular action:


action "keep_biggest_component";
action "layout", "J";
action "sizes", 0.2, 0.1;
action "dump", "layed.glay";
action "visual";
If you write these lines into a file with a text-editor, and give it a name, you can use that name after the -a argument of Glay:
glay -i filename -a my_brand_new_action_filename
Word for Windows as a text-editor is not an optimal solution, since you really need plain text with no formatting. If you don't know what it means, please ask about it from your system administrator or some friends.

2.2.3. Creating new action files

This is how Perl programming comes into the picture. An action is simply a file evaluated in the namespace Glay::Action. It can contain any valid Perl code.

Since any action is run in the namespace Action it is able to use the subroutines defined there. They are the following:

action "actionname", "opt_arg1", ...;

Runs the specified action with optional arguments as if it were invoked from the command line with the command line with the -a parameter.

input "filenaname", "opt_format";

Inputs the given file. It is almost equivalent with action "input", "opt_format";. The only extra it doest that it checks the validity of the filename and dies if it is neither a minus nor is an existing file. If "filename" is a minus sign, then it reads from the IMPORT filehandle, which is STDIN by default.

dump "filename", "optional_format_name";

Dumps the "data" to the given file if format is "native". For other formats it usually dumps the appropriate portion of the "data". The "data" is defined as: all the variables of the "Glay::Data" namespace having names not starting with an underscore. In most cases it means that the %Glay::Data::vtx and %Glay::Data::edge hashes are dumped. Calling this subroutine is actually equivalent with calling action "dump", "filename", "optional_format_name";

parfile "filename";

Reads the given parameter file, and actually "unshifts" it into a list variable. Later the Glay::Parameters::use_parameters(); function can be used to evaluate the contents of that list variable one by one in the calling namespace. Hence parameter files without a package something; in them are evaluated in all the namespaces of the actions using this method of parameter setting, that is calling the use_parameter function.

There are some very important objects that are imported from other places, namely the Glay::Data; namespace and the Glay::Channels namespace. These are:

%vtx

A hash in Glay::Data containg the edges of "the graph". The internal structure is that the vertices are stored in a hash, labelled by unique identifier labels, all of them being also hashes. The keys of a hash representig a vertex are called "tags". A vertex can have any "tags" you'd like, just the tag "neighbour" is used and maintained internally. See the example above for the format called native to see how a vertex is stored in memory.

You should never drop vertices that have appropriate edges going into them. Dropping vertices is best left to the function Glay::Data::Drop::drop_vtx.

Naturally you can store more graphs then one in the memory, even in the Glay::Data namespace, although actions manipulating only on one graph will look for this particular variable. A useful technique to switch between graphs is to store them under different names then the defaults and set the *Glay::Data::vtx and *Glay::Data::edge globs appropriately before calling a particular function. Be aware that the values of &Glay::Data::vtx and &Glay::Data::edge functions is better preserved, since they are used by a lot of actions!

vtx "label", "tag1=value1", "tag2=value2", ...;

A function in Glay::Data to help accessing the main vertex hash %vtx. If a vertex "label" is not yet exists it creates one, if it does, then it just adjusts the appropriate tags of it. If a value of a tag has braces or brackets around them, then it is evaluated, hence you can even use complete structures dumped by Data::Dumper. The most important use of this feature is that the command

vtx "some_vertex", "xyz=[2,3,4.2]", ...;
does not store the value for xyz as a string, but parses it to a list of scalars.

It is advisable to use this function for creating new vertices, although they can also be simply created by commands like

$vtx{new_label}{color}="red";

%edge

A hash in Glay::Data containg the edges of "the graph". The internal structure is that the edges are stored in a hash, labelled by unique identifier labels, all of them being also hashes. The keys of a hash representig an edge are called "tags". An edge can have any "tags" you'd like, just the tags "from" and "to" have fixed meanings: they are the labels of vertices that the edge connects (see the example above for native file format)

You should never rewire or drop edges (changing the values of from and to tags without taking care of the neighbour tags of the appropriate vertices. Rewiring edges is best left to the function "edge", and dropping edges is best left to the function Glay::Data::Drop::drop_edge().

edge "label", "tag1=value1", "tag2=value2", ...;

A function in Glay::Data to help accessing the main edge hash %edge. If an edge "label" is not yet exists it creates one, if it does, then it just adjusts the appropriate tags of it. If a value of a tag has braces or brackets around them, then it is evaluated like for vertices.

It is advisable to use this function for creating new edges or altering their from and to tags, since it adjusts the neighbour tags for the appropriate vertices.

2.2.3.1. Example

Now we know the most important things to start writing new actions. Let's say we needed an action that sets the size of the vertices to 0.1 if they didn't have yet a size, and doubles the size of them if they have a size already. The action would look like something like this:


foreach my %vtxname (keys %vtx) {
  if ( exists $vtx{$vtxname}{size} and defined $vtx{$vtxname}{size} ) {
     $vtx{$vtxname}{size} *= 2;
  else {
     $vtx{$vtxname}{size} = 0.1;
  }
}
That's all! Putting that into a file being in the path GLAYACTIONPATH you can use it as your new action.í