NAME

Tk::GraphViz - Render an interactive GraphViz graph

SYNOPSIS

    use Tk::GraphViz;
    my $gv = $mw->GraphViz ( qw/-width 300 -height 300/ )
      ->pack ( qw/-expand yes -fill both/ );
    $gv->show ( $dotfile );

DESCRIPTION

The GraphViz widget is derived from Tk::Canvas. It adds the ability to render graphs in the canvas. The graphs can be specified either using the DOT graph-description language, or using via a GraphViz or GraphViz2 object.

When show() is called, the graph is passed to the dot command to generate the layout info. That info is then used to create rectangles, lines, etc in the canvas that reflect the generated layout.

Once the items have been created in the graph, they can be used like any normal canvas items: events can be bound, etc. In this way, interactive graphing applications can be created very easily.

METHODS

$gv->show ( graph, ?opt => val, ...? )

Renders the given graph in the canvas. The graph itself can be specified in a number of formats. 'graph' can be one of the following:

- An instance of the GraphViz class (or subclass thereof)
- A scalar containing a graph in DOT format. The scalar must match /^\s*(?:di)?graph /.
- An instance of the IO::Handle class (or subclass thereof), from which to read a graph in DOT format.
- The name / path of a file that contains a graph in DOT format.

show() will recognize some options that control how the graph is rendered, etc. The recognized options:

layout => CMD

Specifies an alternate command to invoke to generate the layout of the graph. If not given, then default is 'dot'. This can be used, for example, to use 'neato' instead of 'dot'.

graphattrs => [ name => value, ... ]

Allows additional default graph attributes to be specified. Each name => value pair will be passed to dot as '-Gname=value' on the command-line.

nodeattrs => [ name => value, ... ]

Allows additional default node attributes to be specified. Each name => value pair will be passed to dot as '-Nname=value' on the command-line.

edgeattrs => [ name => value, ... ]

Allows additional default edge attributes to be specified. Each name => value pair will be passed to dot as '-Ename=value' on the command-line.

fit => $boolean

If true, calls the "$gv->fit()" method after parsing the DOT output. As of 1.05, this no longer defaults to true.

prerender => \&coderef

If given, the code-ref will be called with the graph description data before the actual drawing on a canvas begins, in a hash-ref, e.g. for the file digraph G { a -> b }:

  {
    edge => {
      a => {
        b => [
          {
            pos => [
              { e => 1 },
              [
                [ '27', '71.697' ],
                [ '27', '63.983' ],
                [ '27', '54.712' ],
                [ '27', '46.112' ],
                [ '27', '36.104' ],
              ]
            ]
          }
        ]
      }
    },
    global => { dpi => 72 }, # default value, might be overridden
    node => {
      a => { height => '0.5', label => '\\N', pos => '27,90', width => '0.75' },
      b => { height => '0.5', label => '\\N', pos => '27,18', width => '0.75' }
    },
    subgraph => [
      [ '0', '0', '54', '108' ]
    ]
  }

The code's return value needs to be a hash-ref structured similarly to the above, which will be used to render the graph. Coordinates increase upwards and to the right. Nodes' pos are at their centre.

This feature is experimental as of 1.10, and the data-structure shape or interface may change.

For example, to use neato to generate a layout with non-overlapping nodes and spline edges:

    $gv->show ( $file, layout => 'neato',
                graphattrs => [qw( overlap false spline true )] );

$gv->createBindings ( ?option => value? )

The Tk::GraphViz canvas can be configured with some bindings for standard operations. If no options are given, the default bindings for zooming and scrolling will be enabled. Alternative bindings can be specified via these options:

-zoom => true

Creates the default bindings for zooming. Zooming in or out in the canvas will be bound to <Shift-2> (Shift + mouse button 2). To zoom in, click and drag out a zoom rectangle from top left to bottom right. To zoom out, click and drag out a zoom rectangle from bottom left to top right.

-zoom => spec

This will bind zooming to an alternative event sequence. Examples:

    -zoom => '<1>'      # Zoom on mouse button 1
    -zoom => '<Ctrl-3>' # Zoom on Ctrl + mouse button 3
-scroll => true

Creates the default bindings for scrolling / panning. Scrolling the canvas will be bound to <2> (Mouse button 2).

-scroll => spec

This will bind scrolling to an alternative event sequence. Examples:

    -scroll => '<1>'      # Scroll on mouse button 1
    -scroll => '<Ctrl-3>' # Scroll on Ctrl + mouse button 3
-keypad => true

Binds the keypad arrow / number keys to scroll the canvas, and the keypad +/- keys to zoom in and out. Note that the canvas must have the keyboard focus for these bindings to be activated. This is done by default when createBindings() is called without any options.

$gv->fit()

Scales all of the elements in the canvas to fit the canvas' width and height.

$gv->zoom( -in => factor )

Zoom in by scaling everything up by the given scale factor. The factor should be > 1.0 in order to get reasonable behavior.

$gv->zoom( -out => factor )

Zoom out by scaling everything down by the given scale factor. This is equivalent to

    $gv->zoom ( -in => 1/factor )

The factor should be > 1.0 in order to get reasonable behavior.

$gv->scrollTo(nodename)

If the given node (identified by being tagged with node and that nodename) exists, the viewport is moved to have that at the centre.

$gv->nodes

Returns a list of the names of the graph's nodes, as identified by being tagged with node.

$gv->edges

Returns a list of the graph's edges, as identified by being tagged with edge, as array-refs with the incident nodes' names.

TAGS

In order to facilitate binding, etc, all of the graph elements (nodes, edges, subgraphs) that are created in the canvas will be tagged. Prior to version 1.09, this was done in pairs of tags, but that is not how tags in Tk work: they are individual things.

Each element is composed of several parts, typically at least a shape, and text. Each of these parts will be tagged with its element type (e.g. node), so that all of the visible area will be bindable as such. They will also all be tagged with e.g. node=thisNodeName, for use together with gettags. Only the outermost (or for a record, the first) will be tagged with outermost, so that a single part can be found with e.g. a withtags "outermost&&node=thisNodeName", such as to find the coordinates of the whole element.

Additionally, all attributes attached to an element in the graph description (e.g. color, style, label) will be included as tags, in the form e.g. color=red.

Nodes

Node elements are identified with a 'node' tag. For example, to bind something to all nodes in a graph:

    $gv->bind ( 'node', '<Any-Enter>', sub { ... } );

Edges

Edge elements are identified with a 'edge' tag. For example, to bind something to all edges in a graph:

    $gv->bind ( 'edge', '<Any-Enter>', sub { ... } );

The "naming tag" will be string of the form edge=node1 node2, where node1 and node2 are the names of the respective nodes. To make it convenient to get the individual node names, the edge also has tags 'node1' and 'node2', which give the node names separately. Components of edges do not have an outermost tag.

Subgraphs

Subgraph elements are identified with a 'subgraph' tag.

EXAMPLES

The following example creates a GraphViz widgets to display a graph from a file specified on the command line. Whenever a node is clicked, the node name and label are printed to stdout:

    use GraphViz;
    use Tk;

    my $mw = MainWindow->new();
    my $gv = $mw->Scrolled ( 'GraphViz',
                             -background => 'white',
                             -scrollbars => 'sw' )
      ->pack ( -expand => '1', -fill => 'both' );

    $gv->bind ( 'node', '<Button-1>', sub {
        my @tags = $gv->gettags('current');
        my ($label) = map /^label=(.*)/, @tags;
        my ($node) = map /^node=(.*)/, @tags;
        printf ( "Clicked node: '%s' => %s\n", $node, $label );
    } );

    $gv->show ( shift );
    MainLoop;

BUGS AND LIMITATIONS

Lots of DOT language features not yet implemented

Various node shapes and attributes: polygon, skew, ...
Edge arrow head types

ACKNOWLEDGEMENTS

See http://www.graphviz.org/ for more info on the graphviz tools.

AUTHOR

Jeremy Slade <jeremy@jkslade.net>

Other contributors: Mike Castle, John Cerney, Phi Kasten, Jogi Kuenstner Tobias Lorenz, Charles Minc, Reinier Post, Slaven Rezic

COPYRIGHT AND LICENSE

Copyright 2003-2008 by Jeremy Slade

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.