File Coverage

blib/lib/Graph/Writer/daVinci.pm
Criterion Covered Total %
statement 53 80 66.2
branch 10 18 55.5
condition n/a
subroutine 5 6 83.3
pod n/a
total 68 104 65.3


line stmt bran cond sub pod time code
1             #
2             # Graph::Writer::daVinci - write a directed graph out in daVinci format
3             #
4             package Graph::Writer::daVinci;
5              
6 1     1   380 use strict;
  1         2  
  1         28  
7 1     1   4 use warnings;
  1         1  
  1         20  
8              
9 1     1   3 use parent 'Graph::Writer';
  1         1  
  1         3  
10             our $VERSION = '2.07';
11              
12             #-----------------------------------------------------------------------
13             # List of valid daVinci attributes for the entire graph, per node,
14             # and per edge. You can set other attributes, but they won't get
15             # written out.
16             #-----------------------------------------------------------------------
17             my %valid_attributes =
18             (
19             node => [qw(OBJECT FONTFAMILY FONTSTYLE COLOR CCOLOR _GO _CGO
20             ICONFILE CICONFILE HIDDEN BORDER)],
21              
22             edge => [qw(EDGECOLOR EDGEPATTERN _DIR HEAD)],
23             );
24              
25             #=======================================================================
26             #
27             # _write_graph()
28             #
29             # The private method which actually does the writing out in
30             # daVinci format.
31             #
32             # This is called from the public method, write_graph(), which is
33             # found in Graph::Writer.
34             #
35             #=======================================================================
36             sub _write_graph
37             {
38 1     1   3 my $self = shift;
39 1         2 my $graph = shift;
40 1         1 my $FILE = shift;
41              
42 1         2 my $v;
43             my $from;
44 0         0 my $to;
45 0         0 my $gn;
46 0         0 my $aref;
47 0         0 my @keys;
48 0         0 my (@nodes, @edges);
49 1         2 my %done = ();
50 1         1 my $node;
51              
52              
53 1         4 @nodes = sort $graph->source_vertices;
54 1 50       484 if (@nodes == 0)
55             {
56 0         0 die "expecting source vertices!\n";
57             }
58              
59 1         7 print $FILE "[\n";
60 1         4 while (@nodes > 0)
61             {
62 1         2 $node = shift @nodes;
63 1         4 $self->_dump_node($graph, $FILE, $node, \%done, 1);
64 1 50       5 print $FILE ",\n" if @nodes > 0;
65             }
66 1         2 print $FILE "\n]\n";
67              
68 1         3 return 1;
69              
70             #-------------------------------------------------------------------
71             # Generate a list of edges, along with any attributes
72             #-------------------------------------------------------------------
73 0         0 print $FILE "\n /* list of edges */\n";
74 0         0 @edges = sort _by_vertex $graph->edges;
75 0         0 for (my $i = 0; $i < @edges; $i++)
76             {
77 0         0 ($from, $to) = @{ $edges[$i] };
  0         0  
78 0         0 print $FILE " $from -> $to";
79 0         0 $aref = $graph->get_graph_attributes($from, $to);
80 0         0 @keys = grep(exists $aref->{$_}, @{$valid_attributes{'edge'}});
  0         0  
81 0 0       0 if (@keys > 0)
82             {
83 0         0 print $FILE " [", join(',',
84 0         0 map { "$_ = \"".$aref->{$_}."\"" } @keys), "]";
85             }
86 0 0       0 print $FILE ", " if $i < @edges - 1;
87             }
88              
89 0         0 return 1;
90             }
91              
92              
93             sub _by_vertex
94             {
95 0     0   0 return $a->[0].$a->[1] cmp $b->[0].$b->[1];
96             }
97              
98              
99             #=======================================================================
100             #
101             # _dump_node
102             #
103             # Write out a node, using a reference if we've already written it.
104             # If there are any outgoing edges, we dump them out, recursively
105             # calling ourself to dump the nodes at the other end of each edge.
106             #
107             #=======================================================================
108             sub _dump_node
109             {
110 8     8   10 my ($self, $graph, $FILE, $node, $doneref, $depth) = @_;
111 8         8 my $aref;
112             my @keys;
113 0         0 my @children;
114 0         0 my $child;
115 8         9 local $_;
116              
117              
118 8 100       13 if (exists $doneref->{$node})
119             {
120 3         11 print $FILE ' ' x (2 * $depth), "r(\"Node $node\")";
121             }
122             else
123             {
124 5         15 print $FILE ' ' x (2 * $depth), "l(\"Node $node\", n(\"\"";
125 5         10 $aref = $graph->get_vertex_attributes($node);
126 5         267 @keys = grep(exists $aref->{$_}, @{$valid_attributes{'node'}});
  5         15  
127 5 50       12 if (@keys > 0)
128             {
129 0         0 print $FILE ", [", join(', ',
130 0         0 map { "a(\"$_\", \"".$aref->{$_}."\")" } @keys), "]";
131             }
132             else
133             {
134 5         6 print $FILE ", []";
135             }
136              
137 5         7 $doneref->{$node} = 1;
138              
139 5         10 @children = sort $graph->successors($node);
140 5 100       325 if (@children == 0)
141             {
142 1         2 print $FILE ", []";
143             }
144             else
145             {
146 4         16 print $FILE ",\n", ' ' x (2 * $depth + 1), "[\n";
147 4         9 while (@children > 0)
148             {
149 7         7 $child = shift @children;
150 7         17 print $FILE ' ' x (2 * $depth + 2),
151             "l(\"Edge ${node}->$child\", e(\"\", [";
152              
153             # write out any attributes of the edge
154 7         13 $aref = $graph->get_edge_attributes($node, $child);
155 7         1437 @keys = grep(exists $aref->{$_}, @{$valid_attributes{'edge'}});
  7         20  
156 7 50       13 if (@keys > 0)
157             {
158 0         0 print $FILE join(', ',
159 0         0 map { "a(\"$_\", \"".$aref->{$_}."\")" } @keys);
160             }
161              
162 7         11 print $FILE "],\n";
163 7         27 $self->_dump_node($graph, $FILE, $child, $doneref, $depth+2);
164 7         7 print $FILE "))";
165 7 100       16 print $FILE ",\n" if @children > 0;
166             }
167 4         8 print $FILE ' ' x (2 * $depth + 1), "]";
168             }
169 5         8 print $FILE "))";
170             }
171             }
172              
173             1;
174              
175             __END__