File Coverage

blib/lib/Graph/Writer/Dot.pm
Criterion Covered Total %
statement 66 75 88.0
branch 11 14 78.5
condition 5 6 83.3
subroutine 7 7 100.0
pod n/a
total 89 102 87.2


line stmt bran cond sub pod time code
1             #
2             # Graph::Writer::Dot - write a directed graph out in Dot format
3             #
4             package Graph::Writer::Dot;
5             $Graph::Writer::Dot::VERSION = '2.09';
6 2     2   94891 use 5.006;
  2         4  
7 2     2   6 use strict;
  2         2  
  2         71  
8 2     2   7 use warnings;
  2         2  
  2         49  
9              
10 2     2   399 use parent 'Graph::Writer';
  2         219  
  2         6  
11              
12             #-----------------------------------------------------------------------
13             # List of valid dot 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             graph => [qw(bb bgcolor center clusterrank color comment compound
20             concentrate Damping defaultlist dim dpi epsilon fontcolor
21             fontname fontpath fontsize label labeljust labelloc layers
22             layersep lp margin maxiter mclimit mindist mode model nodesep
23             nojustify normalize nslimit nslimit1 ordering ordering
24             orientation outputorder overlap pack packmode page pagedir
25             quantum rank rankdir ranksep ratio remincross resolution
26             root rotate samplepoints searchsize sep showboxes size
27             splines start stylesheet target truecolor viewport voro_margin)],
28              
29             node => [qw(bottomlabel color comment distortion fillcolor fixedsize
30             fontcolor fontname fontsize group height width label layer
31             margin nojustify orientation peripheries pin pos rects regular
32             root shape shapefile showboxes sides skew style target
33             tooltip toplabel URL vertices width z)],
34              
35             edge => [qw(arrowhead arrowsize arrowtail color comment constraint decorate
36             dir fontcolor fontname fontsize headURL headclip headhref
37             headlabel headport headtarget headtooltip href id label
38             labelangle labeldistance labelfloat labelfontcolor labelfontname
39             labelfontsize layer len lhead lp ltail minlen nojustify
40             pos samehead sametail showboxes style tailURL tailclip
41             tailhref taillabel tailport tailtarget tailtooltip target
42             tooltip weight)],
43             );
44              
45             #=======================================================================
46             #
47             # _init()
48             #
49             # class-specific initialisation. There isn't any here, but it's
50             # kept as a place-holder.
51             #
52             #=======================================================================
53             sub _init
54             {
55 5     5   7 my $self = shift;
56 5         9 my %param = @_;
57              
58 5         16 $self->SUPER::_init();
59 5         18 $self->{_cluster} = $param{cluster};
60             }
61              
62             #=======================================================================
63             #
64             # _write_graph()
65             #
66             # The private method which actually does the writing out in
67             # dot format.
68             #
69             # This is called from the public method, write_graph(), which is
70             # found in Graph::Writer.
71             #
72             #=======================================================================
73             sub _write_graph
74             {
75 5     5   5 my $self = shift;
76 5         3 my $graph = shift;
77 5         7 my $FILE = shift;
78              
79 5         3 my $v;
80             my $from;
81 0         0 my $to;
82 0         0 my $gn;
83 0         0 my $attrref;
84 0         0 my @keys;
85              
86              
87             #-------------------------------------------------------------------
88             # If the graph has a 'name' attribute, then we use that for the
89             # name of the digraph instance. Else it's just 'g'.
90             #-------------------------------------------------------------------
91 5 50       24 $gn = $graph->has_graph_attribute('name') ? $graph->get_graph_attribute('name') : 'g';
92 5         66 print $FILE "digraph $gn\n{\n";
93              
94             #-------------------------------------------------------------------
95             # Dump out any overall attributes of the graph
96             #-------------------------------------------------------------------
97 5         38 $attrref = $graph->get_graph_attributes();
98 5         27 @keys = grep(exists $attrref->{$_}, @{$valid_attributes{'graph'}});
  5         44  
99 5 50       13 if (@keys > 0)
100             {
101 0         0 print $FILE " /* graph attributes */\n";
102 0         0 foreach my $a (@keys)
103             {
104 0         0 print $FILE " $a = \"", $attrref->{$a}, "\";\n";
105             }
106             }
107              
108             #-------------------------------------------------------------------
109             # Generate a list of nodes, with attributes for those that have any.
110             #-------------------------------------------------------------------
111 5         6 print $FILE "\n /* list of nodes */\n";
112 5         13 foreach $v (sort $graph->vertices)
113             {
114 17         206 print $FILE " \"$v\"";
115 17         29 $attrref = $graph->get_vertex_attributes($v);
116 17         805 @keys = grep(exists $attrref->{$_}, @{$valid_attributes{'node'}});
  17         85  
117 17 100       33 if (@keys > 0)
118             {
119             print $FILE " [", join(',',
120 8         9 map { "$_=\"".$attrref->{$_}."\"" } @keys), "]";
  8         20  
121             }
122 17         21 print $FILE ";\n";
123             }
124              
125 5 100 100     16 if ($self->{_cluster} && grep { $_ eq $self->{_cluster} } @{$valid_attributes{'node'}}) {
  144         124  
  4         5  
126             #-------------------------------------------------------------------
127             # Generate a list of subgraphs based on the attribute value.
128             #-------------------------------------------------------------------
129 3         4 print $FILE "\n /* list of subgraphs */\n";
130 3         4 my %cluster = ();
131 3         5 foreach my $v (sort $graph->vertices) {
132 9         88 my $attrs = $graph->get_vertex_attributes($v);
133 9 100 66     406 next unless $attrs && $attrs->{$self->{_cluster}};
134 8         8 my $attr_value = $attrs->{$self->{_cluster}};
135 8 100       27 $cluster{$attr_value} = [] unless exists $cluster{$attr_value};
136 8         9 push @{ $cluster{$attr_value} }, $v;
  8         15  
137             }
138 3         8 foreach my $attr_value (sort keys %cluster) {
139 5         8 print $FILE " subgraph \"cluster_$attr_value\" {\n";
140 5         5 print $FILE " label = \"$attr_value\";\n";
141 5         7 foreach my $node (@{ $cluster{$attr_value} }) {
  5         9  
142 8         11 print $FILE " node [label=\"$node\"] \"$node\";\n";
143             }
144 5         8 print $FILE " }\n";
145             }
146             }
147              
148             #-------------------------------------------------------------------
149             # Generate a list of edges, along with any attributes
150             #-------------------------------------------------------------------
151 5         7 print $FILE "\n /* list of edges */\n";
152 5         12 foreach my $edge (sort _by_vertex $graph->edges)
153             {
154 15         52 ($from, $to) = @$edge;
155 15         26 print $FILE " \"$from\" -> \"$to\"";
156 15         23 $attrref = $graph->get_edge_attributes($from, $to);
157 15         3684 @keys = grep(exists $attrref->{$_}, @{$valid_attributes{'edge'}});
  15         70  
158 15 50       27 if (@keys > 0)
159             {
160             print $FILE " [", join(',',
161 0         0 map { "$_ = \"".$attrref->{$_}."\"" } @keys), "]";
  0         0  
162             }
163 15         22 print $FILE ";\n";
164             }
165              
166             #-------------------------------------------------------------------
167             # close off the digraph instance
168             #-------------------------------------------------------------------
169 5         13 print $FILE "}\n";
170              
171 5         13 return 1;
172             }
173              
174              
175             sub _by_vertex
176             {
177 17     17   224 return $a->[0].$a->[1] cmp $b->[0].$b->[1];
178             }
179              
180              
181             1;
182              
183             __END__