File Coverage

blib/lib/Graph/Writer/DSM.pm
Criterion Covered Total %
statement 46 54 85.1
branch 1 2 50.0
condition 3 6 50.0
subroutine 10 11 90.9
pod n/a
total 60 73 82.1


line stmt bran cond sub pod time code
1             package Graph::Writer::DSM;
2             {
3             $Graph::Writer::DSM::VERSION = '0.006';
4             }
5 1     1   1326169 use Modern::Perl;
  1         542  
  1         7  
6 1     1   177 use base qw( Graph::Writer );
  1         2  
  1         729  
7 1     1   516 use List::MoreUtils qw( uniq first_index apply );
  1         7  
  1         22  
8 1     1   1779 use Chart::Gnuplot;
  1         18791  
  1         56  
9 1     1   14 use File::Temp;
  1         3  
  1         767  
10              
11             =head1 NAME
12              
13             Graph::Writer::DSM - draw graph as a DSM matrix
14              
15             =head1 VERSION
16              
17             version 0.006
18              
19             =head1 DESCRIPTION
20              
21             Write graph as a quadractic matrix N x N, where N is the number of vertices in
22             the graph. It is useful to visualize graphs with at least 1k vertices.
23              
24             See more about DSM: L<http://en.wikipedia.org/wiki/Design_structure_matrix>.
25              
26             =head1 SYNOPSIS
27              
28             use Graph;
29             use Graph::Writer::DSM;
30             my $graph = Graph->new();
31             my $writer = Graph::Writer::DSM->new(%OPTIONS);
32             $writer->write_graph($graph, "output.png");
33              
34             =head1 METHODS
35              
36             =head1 new()
37              
38             Like L<Graph::Writer::GraphViz>, this module provide some extra parameters
39             to new() method.
40              
41             $writer = Graph::Writer::DSM->new(color => 'red');
42              
43             Supported parameters are:
44              
45             =over 4
46              
47             =item pointsize
48              
49             Default: 0.2.
50              
51             =item color
52              
53             Default: 'blue'.
54              
55             =item tics_label
56              
57             Default: false.
58              
59             =back
60              
61             =cut
62            
63             sub _init {
64 2     2   20195 my ($self, %param) = @_;
65 2         13 $self->SUPER::_init();
66 2   50     27 $self->{_dsm_point_size} = $param{pointsize} // 0.2;
67 2   50     14 $self->{_dsm_color} = $param{color} // 'blue';
68 2   50     15 $self->{_dsm_tics_label} = $param{tics_label} // undef;
69             }
70              
71             sub _move_file_to_filehandle {
72 1     1   9 my ($file, $FILEHANDLE) = @_;
73 1         113 open FILE, '<', $file;
74 1         26 local $/ = undef;
75 1         64 my $FILE = <FILE>;
76 1         10 close FILE;
77 1         57 print $FILEHANDLE $FILE;
78 1         22 unlink $file;
79             }
80              
81             =head1 write_graph()
82              
83             Write a specific graph to a named file:
84              
85             $writer->write_graph($graph, $file);
86              
87             The $file argument can either be a filename, or a filehandle for a previously
88             opened file.
89              
90             =cut
91              
92             sub _write_graph {
93 1     1   186 my ($self, $graph, $FILE) = @_;
94 1         6 my @vertices = uniq sort $graph->vertices;
95 1         68 my $output_temp = File::Temp::tempnam('/tmp', 'chart') . '.png';
96              
97 1 50       256 if ($self->{_dsm_tics_label}) {
98 0         0 my $i = -1;
99 0     0   0 my @y_labels = map { $i++; "'$_ $i' $i" } apply { s/.*\///; $_ } @vertices;
  0         0  
  0         0  
  0         0  
  0         0  
100 0         0 $self->{_dsm_ytics} = { labels => \@y_labels };
101 0         0 $self->{_dsm_x2tics} = [0 .. $#vertices];
102             }
103             else {
104 1         5 $self->{_dsm_ytics} = [0, $#vertices];
105 1         4 $self->{_dsm_x2tics} = [0, $#vertices];
106             }
107              
108             my $chart = Chart::Gnuplot->new(
109             x2range => [0, $#vertices],
110             xrange => [0, $#vertices],
111             yrange => [$#vertices, 0],
112             output => $output_temp,
113             bg => 'white',
114             xtics => undef,
115             x2tics => $self->{_dsm_x2tics},
116             ytics => $self->{_dsm_ytics},
117 1         15 size => 'ratio 1',
118             terminal => 'png',
119             );
120 1         519 my @points = ();
121 1         6 my @edges = $graph->edges;
122 1         78 foreach my $edge (@edges) {
123 2     2   13 my $col = first_index { $_ eq $edge->[0] } @vertices;
  2         6  
124 2     5   10 my $row = first_index { $_ eq $edge->[1] } @vertices;
  5         31  
125 2         8 push @points, [$row, $col];
126             }
127             my $dataSet = Chart::Gnuplot::DataSet->new(
128             points => \@points,
129             style => 'points',
130             color => $self->{_dsm_color},
131             pointtype => 5,
132             pointsize => $self->{_dsm_point_size},
133 1         12 );
134 1         335 $chart->plot2d($dataSet);
135 1         8880 _move_file_to_filehandle($output_temp, \*$FILE);
136 1         175 return 1;
137             }
138            
139             1;
140              
141             =head1 SEE ALSO
142              
143             L<Graph>, L<Graph::Writer>, L<Chart::Gnuplot>.
144              
145             =head1 COPYRIGHT
146              
147             Copyright (c) 2013, Joenio Costa