File Coverage

blib/lib/Graph/XGMML.pm
Criterion Covered Total %
statement 44 45 97.7
branch 4 8 50.0
condition n/a
subroutine 11 11 100.0
pod 6 6 100.0
total 65 70 92.8


line stmt bran cond sub pod time code
1             package Graph::XGMML;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Graph::XGMML - Simple Graph.pm-like interface for generating XGMML graphs
8              
9             =head1 SYNOPSIS
10              
11             use Graph::XGMML;
12            
13             my $output = '';
14             my $graph = Graph::XGMML->new(
15             directed => 1,
16             OUTPUT => \$output,
17             );
18             $graph->add_node('foo');
19             $graph->add_node('bar');
20             $graph->add_edge('foo', 'bar');
21             $graph->end;
22              
23             =head1 DESCRIPTION
24              
25             To produce useful diagrams on extremely large graphs, sometimes it is necesary
26             to move beyond simple graphing tools to applications specifically designed for
27             rendering very large graphs, many of which were designed for biology
28             applications (such as my favourite Cytoscape).
29              
30             B is a module that can be used to generate export files for
31             arbitrarily large graphs in B,
32             so that the graphs can be imported into these specialised tools.
33              
34             The API is intentionally designed to appear similar to more popular modules
35             such as L, L and L.
36              
37             =head1 METHODS
38              
39             =cut
40              
41 2     2   27292 use 5.008005;
  2         7  
  2         86  
42 2     2   12 use strict;
  2         5  
  2         78  
43 2     2   19 use warnings;
  2         4  
  2         77  
44 2     2   2366 use XML::Writer ();
  2         35878  
  2         885  
45              
46             our $VERSION = '0.01';
47              
48             =pod
49              
50             =head2 new
51              
52             # Quick constructor to write to a file
53             $graph = Graph::XGMML->new(
54             directed => 1,
55             OUTPUT => IO::File->new('file', 'w'),
56             );
57            
58             # Anonymous constructor
59             $graph = Graph::XGMML->new(
60             directed => 1,
61             );
62              
63             The C constructor is used to create a graph writer.
64              
65             It takes a single optional boolean C parameter, which indicates if
66             the graphs you will be generating will be directed or undirected.
67              
68             If any additional parameters are passed to C, the constructor will make an
69             additional call to the C method to start writing the document header and
70             to open the root C node, passing it the extra parameters.
71              
72             Returns a new B object, or throws an exception (dies) on error.
73              
74             =cut
75              
76             sub new {
77 1     1 1 14 my $class = shift;
78 1         5 my %param = @_;
79              
80             # Extract non-writer param
81 1 50       5 my $directed = delete($param{directed}) ? 1 : 0;
82              
83             # Create the object
84 1         5 my $self = bless {
85             writer => undef,
86             started => 0,
87             directed => $directed,
88             }, $class;
89              
90             # If we have any params, autostart
91 1 50       4 if ( %param ) {
92 1         8 $self->start( %param );
93             }
94              
95 1         3 return $self;
96             }
97              
98             =pod
99              
100             =head2 start
101              
102             The C method allows you to explicitly start the document writing, if the
103             original constructor was produced without additional parameters.
104              
105             Any parameters are passed directly to the underlying L constructor
106             which produces the object that will be used to generate the XML.
107              
108             Returns true if the document is started successfully, or throws an exception
109             (dies) on error.
110              
111             =cut
112              
113             sub start {
114 1     1 1 2 my $self = shift;
115 1         9 $self->{writer} = XML::Writer->new( @_ );
116 1 50       241 unless ( $self->{writer} ) {
117 0         0 die("Failed to create XML::Writer object");
118             }
119 1         29 $self->{writer}->xmlDecl('UTF-8');
120 1         34 $self->{writer}->doctype(
121             'graph',
122             '-//John Punin//DTD graph description//EN',
123             'http://www.cs.rpi.edu/~puninj/XGMML/xgmml.dtd',
124             );
125 1         34 $self->{writer}->startTag('graph',
126             directed => $self->{directed},
127             );
128 1         70 $self->{started} = 1;
129 1         2 return 1;
130             }
131              
132             =pod
133              
134             =head2 add_node
135              
136             # Add a simple node
137             $graph->add_node( 'name' );
138            
139             # Add optional tag attributes
140             $graph->add_node( 'name',
141             label => 'Tag Label',
142             weight => 100,
143             );
144              
145             The C method is used to add a new node to the graph.
146              
147             Because the B object doesn't remember its state as it produces
148             the graph, you must specify all nodes in the graph explicitly.
149              
150             The first parameter is the identifier for the node. Any additional parameters
151             will be treated XGMML C element tag pairs.
152              
153             Returns true or throws an exception (dies) on error.
154              
155             =cut
156              
157             sub add_node {
158 2     2 1 766 my $self = shift;
159 2         3 my $name = shift;
160 2         7 $self->{writer}->startTag('node',
161             id => $name,
162             label => $name,
163             @_,
164             );
165 2         126 $self->{writer}->endTag('node');
166 2         37 return 1;
167             }
168              
169             =pod
170              
171             =head2 add_vertex
172              
173             The C method is an alias to C, provided for increased
174             compatibility with the L API.
175              
176             It takes the same parameters as C.
177              
178             =cut
179              
180             sub add_vertex {
181 1     1 1 6 shift->add_node(@_);
182             }
183              
184             =pod
185              
186             =head2 add_edge
187              
188             # Add a simple edge
189             $graph->add_edge( 'foo' => 'bar' );
190            
191             # Add with optional attributes
192             $graph->add_edge( 'foo' => 'bar',
193             weight => 1,
194             );
195              
196             The c method adds an edge to the graph.
197              
198             The first two parameters are the source and target of the edge. Any additional
199             parameters should be a set of key/value pairs of edge attributes.
200              
201             Returns true or throws an exception (dies) on error.
202              
203             =cut
204              
205             sub add_edge {
206 1     1 1 4 my $self = shift;
207 1         13 $self->{writer}->emptyTag('edge',
208             source => shift,
209             target => shift,
210             @_,
211             );
212 1         65 return 1;
213             }
214              
215             =pod
216              
217             =head2 end
218              
219             # Explicitly terminate the document
220             $graph->end;
221              
222             The C method is used to indicate that the graph is completed that the XML
223             should be terminated.
224              
225             If you do not call it yourself, it will be called for you at C-time.
226              
227             =cut
228              
229             sub end {
230 1     1 1 2 my $self = shift;
231 1         4 $self->{writer}->endTag('graph');
232 1         16 $self->{writer}->end;
233 1         15 $self->{started} = 0;
234 1         103 delete $self->{writer};
235 1         4 return 1;
236             }
237              
238             sub DESTROY {
239 1 50   1   6 if ( $_[0]->{started} ) {
240 1         4 $_[0]->end;
241             }
242             }
243              
244             1;
245              
246             =pod
247              
248             =head1 SUPPORT
249              
250             Bugs should always be submitted via the CPAN bug tracker
251              
252             L
253              
254             For other issues, contact the maintainer.
255              
256             =head1 AUTHOR
257              
258             Adam Kennedy Eadamk@cpan.orgE
259              
260             =head1 SEE ALSO
261              
262             L, L, L
263              
264             =head1 COPYRIGHT
265              
266             Copyright 2009 Adam Kennedy.
267              
268             This program is free software; you can redistribute
269             it and/or modify it under the same terms as Perl itself.
270              
271             The full text of the license can be found in the
272             LICENSE file included with this module.
273              
274             =cut