line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Venn::Chart;
|
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
24063
|
use warnings;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
31
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict;
|
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
59
|
|
5
|
1
|
|
|
1
|
|
5
|
use Carp;
|
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
84
|
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
#==================================================================
|
8
|
|
|
|
|
|
|
# $Author : Djibril Ousmanou $
|
9
|
|
|
|
|
|
|
# $Copyright : 2011 $
|
10
|
|
|
|
|
|
|
# $Update : 01/01/2011 00:00:00 $
|
11
|
|
|
|
|
|
|
# $AIM : Create a Venn diagram image $
|
12
|
|
|
|
|
|
|
#==================================================================
|
13
|
|
|
|
|
|
|
|
14
|
1
|
|
|
1
|
|
470
|
use GD;
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use GD::Graph::hbars;
|
16
|
|
|
|
|
|
|
use GD::Graph::colour;
|
17
|
|
|
|
|
|
|
use GD::Text::Align;
|
18
|
|
|
|
|
|
|
use List::Compare;
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use vars qw($VERSION);
|
21
|
|
|
|
|
|
|
$VERSION = '1.02';
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
my %DEFAULT = (
|
24
|
|
|
|
|
|
|
Hlegend => 70,
|
25
|
|
|
|
|
|
|
Htitle => 30,
|
26
|
|
|
|
|
|
|
space => 10,
|
27
|
|
|
|
|
|
|
colors => [ [ 189, 66, 238, 0 ], [ 255, 133, 0, 0 ], [ 0, 107, 44, 0 ] ],
|
28
|
|
|
|
|
|
|
);
|
29
|
|
|
|
|
|
|
my $WIDTH = 500;
|
30
|
|
|
|
|
|
|
my $HEIGHT = 500;
|
31
|
|
|
|
|
|
|
my $MIN_LEGEND = 2;
|
32
|
|
|
|
|
|
|
my $MAX_LEGEND = 3;
|
33
|
|
|
|
|
|
|
my $MIN_PLOT = $MIN_LEGEND;
|
34
|
|
|
|
|
|
|
my $MAX_PLOT = $MAX_LEGEND;
|
35
|
|
|
|
|
|
|
my $MIN_LIST_REGION = 3;
|
36
|
|
|
|
|
|
|
my $MAX_LIST_REGION = 7;
|
37
|
|
|
|
|
|
|
my $CUBE_SIZE = 10;
|
38
|
|
|
|
|
|
|
my @RGB_WHITE = ( 255, 255, 255 );
|
39
|
|
|
|
|
|
|
my @RGB_BLACK = ( 0, 0, 0 );
|
40
|
|
|
|
|
|
|
my @RGBA = ( 0, 0, 0, 0 );
|
41
|
|
|
|
|
|
|
my @DEGREES = ( 0, 360 );
|
42
|
|
|
|
|
|
|
my $SLASH = q{/};
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub new {
|
45
|
|
|
|
|
|
|
my ( $self, $width, $height ) = @_;
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
$self = ref($self) || $self;
|
48
|
|
|
|
|
|
|
my $this = {};
|
49
|
|
|
|
|
|
|
bless $this, $self;
|
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
$this->{_width} = $width || $WIDTH;
|
52
|
|
|
|
|
|
|
$this->{_height} = $height || $HEIGHT;
|
53
|
|
|
|
|
|
|
$this->{_dim}{Ht} = 0;
|
54
|
|
|
|
|
|
|
$this->{_dim}{HLeg} = 0;
|
55
|
|
|
|
|
|
|
$this->{_dim}{space} = $DEFAULT{space};
|
56
|
|
|
|
|
|
|
$this->{_colors} = $DEFAULT{colors};
|
57
|
|
|
|
|
|
|
$this->{_circles}{number} = 0;
|
58
|
|
|
|
|
|
|
$this->{_legends}{number} = 0;
|
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
return $this;
|
61
|
|
|
|
|
|
|
}
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub set {
|
64
|
|
|
|
|
|
|
my ( $this, %param ) = @_;
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
carp("set method deprecated, please use set_options method\n");
|
67
|
|
|
|
|
|
|
$this->set_options(%param);
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
return 1;
|
70
|
|
|
|
|
|
|
}
|
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub set_options {
|
73
|
|
|
|
|
|
|
my ( $this, %param ) = @_;
|
74
|
|
|
|
|
|
|
$this->{_colors} = $param{'-colors'} || $DEFAULT{colors};
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
if ( exists $param{'-title'} ) {
|
77
|
|
|
|
|
|
|
$this->{_title} = $param{'-title'};
|
78
|
|
|
|
|
|
|
$this->{_dim}{Ht} = $DEFAULT{Htitle};
|
79
|
|
|
|
|
|
|
}
|
80
|
|
|
|
|
|
|
return 1;
|
81
|
|
|
|
|
|
|
}
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub set_legends {
|
84
|
|
|
|
|
|
|
my ( $this, @legends ) = @_;
|
85
|
|
|
|
|
|
|
$this->{_legends}{number} = scalar @legends;
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
if ( $this->{_legends}{number} < $MIN_LEGEND or $this->{_legends}{number} > $MAX_LEGEND ) {
|
88
|
|
|
|
|
|
|
carp("You must set $MIN_LEGEND or $MAX_LEGEND legends");
|
89
|
|
|
|
|
|
|
return;
|
90
|
|
|
|
|
|
|
}
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
$this->{_legend} = \@legends;
|
93
|
|
|
|
|
|
|
$this->{_dim}{HLeg} = $DEFAULT{Hlegend};
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
return 1;
|
96
|
|
|
|
|
|
|
}
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub _legend {
|
99
|
|
|
|
|
|
|
my ( $this, $image ) = @_;
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# Coords
|
102
|
|
|
|
|
|
|
my $cubex1 = $DEFAULT{space};
|
103
|
|
|
|
|
|
|
my $cubey1 = $this->{_dim}{Ht} + $this->{_dim}{Hc} + $CUBE_SIZE;
|
104
|
|
|
|
|
|
|
my $cubex2 = $cubex1 + $CUBE_SIZE;
|
105
|
|
|
|
|
|
|
my $cubey2 = $cubey1 + $CUBE_SIZE;
|
106
|
|
|
|
|
|
|
my $xtext = $cubex2 + $CUBE_SIZE;
|
107
|
|
|
|
|
|
|
my $ytext = $cubey1;
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
for ( 0 .. 2 ) {
|
110
|
|
|
|
|
|
|
my $idcolor = $_ + 1;
|
111
|
|
|
|
|
|
|
last if ( !( $this->{_legend}->[$_] and $this->{_conf_color}{"color$idcolor"} ) );
|
112
|
|
|
|
|
|
|
$image->filledRectangle( $cubex1, $cubey1, $cubex2, $cubey2, $this->{_conf_color}{"color$idcolor"} );
|
113
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont, $xtext, $ytext, $this->{_legend}->[$_], $this->{_conf_color}{black} );
|
114
|
|
|
|
|
|
|
$cubey1 = $cubey2 + $CUBE_SIZE;
|
115
|
|
|
|
|
|
|
$cubey2 = $cubey1 + $CUBE_SIZE;
|
116
|
|
|
|
|
|
|
$ytext = $cubey1;
|
117
|
|
|
|
|
|
|
}
|
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
return 1;
|
120
|
|
|
|
|
|
|
}
|
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
sub plot {
|
123
|
|
|
|
|
|
|
my ( $this, @data ) = @_;
|
124
|
|
|
|
|
|
|
$this->{_circles}{number} = scalar @data;
|
125
|
|
|
|
|
|
|
if ( $this->{_circles}{number} < $MIN_PLOT or $this->{_circles}{number} > $MAX_PLOT ) {
|
126
|
|
|
|
|
|
|
croak("You must plot $MIN_PLOT or $MAX_PLOT lists");
|
127
|
|
|
|
|
|
|
}
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
$this->{_dim}{R} = ( $this->{_width} - ( $MIN_PLOT * $this->{_dim}{space} ) ) / $MAX_PLOT;
|
130
|
|
|
|
|
|
|
$this->{_dim}{D} = $this->{_dim}{R} * $MIN_PLOT;
|
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# Check Height dimension and recalcul space
|
133
|
|
|
|
|
|
|
my $diff
|
134
|
|
|
|
|
|
|
= ( $this->{_dim}{Ht} + $this->{_dim}{D} + $this->{_dim}{R} + $this->{_dim}{HLeg} - $this->{_height} );
|
135
|
|
|
|
|
|
|
if ( $diff > 0 ) {
|
136
|
|
|
|
|
|
|
$this->{_dim}{space} += ( $diff / $MIN_PLOT );
|
137
|
|
|
|
|
|
|
$this->{_dim}{R} = ( $this->{_width} - ( $MIN_PLOT * $this->{_dim}{space} ) ) / $MAX_PLOT;
|
138
|
|
|
|
|
|
|
$this->{_dim}{D} = $this->{_dim}{R} * $MIN_PLOT;
|
139
|
|
|
|
|
|
|
}
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
my $image = GD::Image->new( $this->{_width}, $this->{_height} );
|
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
$this->{_conf_color}{white} = $image->colorAllocate(@RGB_WHITE);
|
144
|
|
|
|
|
|
|
$this->{_conf_color}{black} = $image->colorAllocate(@RGB_BLACK);
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
# make the background transparent and interlaced
|
147
|
|
|
|
|
|
|
$image->transparent( $this->{_conf_color}{white} );
|
148
|
|
|
|
|
|
|
$image->interlaced('true');
|
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# display circle
|
151
|
|
|
|
|
|
|
if ( $this->{_title} ) { $this->_title($image); }
|
152
|
|
|
|
|
|
|
$this->_circle( $image, @data );
|
153
|
|
|
|
|
|
|
if ( $this->{_legend} ) { $this->_legend($image); }
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
$this->{_gd}{plot} = $image;
|
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
return $image;
|
158
|
|
|
|
|
|
|
}
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub _title {
|
161
|
|
|
|
|
|
|
my ( $this, $image ) = @_;
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
if ( not defined $image ) { return; }
|
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
$this->{_coords}{xtitle} = $this->{_dim}{space};
|
166
|
|
|
|
|
|
|
$this->{_coords}{ytitle} = $this->{_dim}{Ht} / 2;
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
my $align = GD::Text::Align->new(
|
169
|
|
|
|
|
|
|
$image,
|
170
|
|
|
|
|
|
|
valign => 'center',
|
171
|
|
|
|
|
|
|
halign => 'center',
|
172
|
|
|
|
|
|
|
colour => $this->{_conf_color}{black},
|
173
|
|
|
|
|
|
|
);
|
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
$align->set_font(gdMediumBoldFont);
|
176
|
|
|
|
|
|
|
$align->set_text( $this->{_title} );
|
177
|
|
|
|
|
|
|
$align->draw( $this->{_width} / 2, $this->{_coords}{ytitle}, 0 );
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
return 1;
|
180
|
|
|
|
|
|
|
}
|
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub _circle {
|
183
|
|
|
|
|
|
|
my ( $this, $image, $ref_data1, $ref_data2, $ref_data3 ) = @_;
|
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
if ( not defined $image ) { return; }
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# Venn with 2 circles
|
188
|
|
|
|
|
|
|
# Coords
|
189
|
|
|
|
|
|
|
$this->{_coords}{xc1} = $this->{_dim}{space} + $this->{_dim}{R};
|
190
|
|
|
|
|
|
|
$this->{_coords}{yc1} = $this->{_dim}{R} + $this->{_dim}{Ht};
|
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
$this->{_coords}{xc2} = $this->{_coords}{xc1} + $this->{_dim}{R};
|
193
|
|
|
|
|
|
|
$this->{_coords}{yc2} = $this->{_coords}{yc1};
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
# display circles
|
196
|
|
|
|
|
|
|
$image->arc(
|
197
|
|
|
|
|
|
|
$this->{_coords}{xc1},
|
198
|
|
|
|
|
|
|
$this->{_coords}{yc1},
|
199
|
|
|
|
|
|
|
$this->{_dim}{D},
|
200
|
|
|
|
|
|
|
$this->{_dim}{D},
|
201
|
|
|
|
|
|
|
@DEGREES, $this->{_conf_color}{black}
|
202
|
|
|
|
|
|
|
);
|
203
|
|
|
|
|
|
|
$image->arc(
|
204
|
|
|
|
|
|
|
$this->{_coords}{xc2},
|
205
|
|
|
|
|
|
|
$this->{_coords}{yc2},
|
206
|
|
|
|
|
|
|
$this->{_dim}{D},
|
207
|
|
|
|
|
|
|
$this->{_dim}{D},
|
208
|
|
|
|
|
|
|
@DEGREES, $this->{_conf_color}{black}
|
209
|
|
|
|
|
|
|
);
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
# text circle
|
212
|
|
|
|
|
|
|
my $lcm = List::Compare->new( { lists => [ $ref_data1, $ref_data2, $ref_data3 ], } );
|
213
|
|
|
|
|
|
|
my @list1 = $lcm->get_unique(0);
|
214
|
|
|
|
|
|
|
my $data1 = scalar @list1;
|
215
|
|
|
|
|
|
|
my @list2 = $lcm->get_unique(1);
|
216
|
|
|
|
|
|
|
my $data2 = scalar @list2;
|
217
|
|
|
|
|
|
|
my @list3 = $lcm->get_unique(2);
|
218
|
|
|
|
|
|
|
my $data3 = scalar @list3;
|
219
|
|
|
|
|
|
|
my @list123 = $lcm->get_intersection;
|
220
|
|
|
|
|
|
|
my $data123 = scalar @list123;
|
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
my $lc = List::Compare->new( $ref_data1, $ref_data2 );
|
223
|
|
|
|
|
|
|
my @list12 = $lc->get_intersection;
|
224
|
|
|
|
|
|
|
my $lc12 = List::Compare->new( \@list12, \@list123 );
|
225
|
|
|
|
|
|
|
@list12 = $lc12->get_unique;
|
226
|
|
|
|
|
|
|
my $data12 = scalar @list12;
|
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
$lc = List::Compare->new( $ref_data1, $ref_data3 );
|
229
|
|
|
|
|
|
|
my @list13 = $lc->get_intersection;
|
230
|
|
|
|
|
|
|
my $lc13 = List::Compare->new( \@list13, \@list123 );
|
231
|
|
|
|
|
|
|
@list13 = $lc13->get_unique;
|
232
|
|
|
|
|
|
|
my $data13 = scalar @list13;
|
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
$lc = List::Compare->new( $ref_data2, $ref_data3 );
|
235
|
|
|
|
|
|
|
my @list23 = $lc->get_intersection;
|
236
|
|
|
|
|
|
|
my $lc23 = List::Compare->new( \@list23, \@list123 );
|
237
|
|
|
|
|
|
|
@list23 = $lc23->get_unique;
|
238
|
|
|
|
|
|
|
my $data23 = scalar @list23;
|
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# for get_regions
|
241
|
|
|
|
|
|
|
$this->{_regions} = [ $data1, $data2, $data12 ];
|
242
|
|
|
|
|
|
|
$this->{_listregions} = [ \@list1, \@list2, \@list12 ];
|
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
$this->{_coords}{xt1} = $this->{_dim}{space} + ( $this->{_dim}{R} / $MAX_PLOT );
|
245
|
|
|
|
|
|
|
$this->{_coords}{yt1} = $this->{_coords}{yc1};
|
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
$this->{_coords}{xt2} = $this->{_dim}{space} + $this->{_dim}{D} + ( $this->{_dim}{R} / $MAX_PLOT );
|
248
|
|
|
|
|
|
|
$this->{_coords}{yt2} = $this->{_coords}{yc1};
|
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
$this->{_coords}{xt12} = $this->{_coords}{xc1} + ( $this->{_dim}{R} / $MIN_PLOT );
|
251
|
|
|
|
|
|
|
$this->{_coords}{yt12} = $this->{_coords}{yc1} - ( $this->{_dim}{R} / $MIN_PLOT );
|
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
if ( $this->{_colors}->[0] and $this->{_colors}->[1] ) {
|
254
|
|
|
|
|
|
|
$this->{_conf_color}{color1} = $image->colorAllocateAlpha( @{ $this->{_colors}->[0] } );
|
255
|
|
|
|
|
|
|
$this->{_conf_color}{color2} = $image->colorAllocateAlpha( @{ $this->{_colors}->[1] } );
|
256
|
|
|
|
|
|
|
my $ref_color12 = $this->_moy_color( $this->{_colors}->[0], $this->{_colors}->[1] );
|
257
|
|
|
|
|
|
|
$this->{_conf_color}{color12} = $image->colorAllocateAlpha( @{$ref_color12} );
|
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
$image->fill( $this->{_coords}{xt1}, $this->{_coords}{yt1}, $this->{_conf_color}{color1} );
|
260
|
|
|
|
|
|
|
$image->fill( $this->{_coords}{xt2}, $this->{_coords}{yt2}, $this->{_conf_color}{color2} );
|
261
|
|
|
|
|
|
|
$image->fill( $this->{_coords}{xt12}, $this->{_coords}{yt12}, $this->{_conf_color}{color12} );
|
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
$this->{_colors_regions} = [ $this->{_colors}->[0], $this->{_colors}->[1], $ref_color12 ];
|
264
|
|
|
|
|
|
|
}
|
265
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont,
|
266
|
|
|
|
|
|
|
$this->{_coords}{xt1},
|
267
|
|
|
|
|
|
|
$this->{_coords}{yt1},
|
268
|
|
|
|
|
|
|
$data1, $this->{_conf_color}{black}
|
269
|
|
|
|
|
|
|
);
|
270
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont,
|
271
|
|
|
|
|
|
|
$this->{_coords}{xt2},
|
272
|
|
|
|
|
|
|
$this->{_coords}{yt2},
|
273
|
|
|
|
|
|
|
$data2, $this->{_conf_color}{black}
|
274
|
|
|
|
|
|
|
);
|
275
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont,
|
276
|
|
|
|
|
|
|
$this->{_coords}{xt12},
|
277
|
|
|
|
|
|
|
$this->{_coords}{yt12},
|
278
|
|
|
|
|
|
|
$data12, $this->{_conf_color}{black}
|
279
|
|
|
|
|
|
|
);
|
280
|
|
|
|
|
|
|
$this->{_dim}{Hc} = $this->{_dim}{D};
|
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
# Venn with 3 circles
|
283
|
|
|
|
|
|
|
if ( defined $ref_data3 ) {
|
284
|
|
|
|
|
|
|
$this->{_coords}{xc3} = $this->{_coords}{xc1} + ( $this->{_dim}{R} / $MIN_PLOT );
|
285
|
|
|
|
|
|
|
$this->{_coords}{yc3} = $this->{_coords}{yc1} + $this->{_dim}{R};
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
$image->arc(
|
288
|
|
|
|
|
|
|
$this->{_coords}{xc3},
|
289
|
|
|
|
|
|
|
$this->{_coords}{yc3},
|
290
|
|
|
|
|
|
|
$this->{_dim}{D},
|
291
|
|
|
|
|
|
|
$this->{_dim}{D},
|
292
|
|
|
|
|
|
|
@DEGREES, $this->{_conf_color}{black}
|
293
|
|
|
|
|
|
|
);
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
$this->{_coords}{xt3} = $this->{_coords}{xc3};
|
296
|
|
|
|
|
|
|
$this->{_coords}{yt3} = $this->{_coords}{yc3} + ( $this->{_dim}{R} / $MIN_PLOT );
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
$this->{_coords}{xt13} = $this->{_coords}{xc1} - ( $this->{_dim}{D} / ( $MAX_PLOT * 2 ) );
|
299
|
|
|
|
|
|
|
$this->{_coords}{yt13} = $this->{_coords}{yc3} - ( $this->{_dim}{R} / $MIN_PLOT );
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
$this->{_coords}{xt23} = $this->{_coords}{xc2};
|
302
|
|
|
|
|
|
|
$this->{_coords}{yt23} = $this->{_coords}{yc3} - ( $this->{_dim}{R} / $MAX_PLOT );
|
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
$this->{_coords}{xt123} = $this->{_coords}{xt3};
|
305
|
|
|
|
|
|
|
$this->{_coords}{yt123} = $this->{_coords}{yc3} - 2 * ( $this->{_dim}{R} / $MAX_PLOT );
|
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
if ( $this->{_colors}->[2] ) {
|
308
|
|
|
|
|
|
|
$this->{_conf_color}{color3} = $image->colorAllocateAlpha( @{ $this->{_colors}->[2] } );
|
309
|
|
|
|
|
|
|
my $ref_color13 = $this->_moy_color( $this->{_colors}->[0], $this->{_colors}->[2] );
|
310
|
|
|
|
|
|
|
my $ref_color23 = $this->_moy_color( $this->{_colors}->[1], $this->{_colors}->[2] );
|
311
|
|
|
|
|
|
|
my $ref_color123
|
312
|
|
|
|
|
|
|
= $this->_moy_color( $this->{_colors}->[0], $this->{_colors}->[1], $this->{_colors}->[2] );
|
313
|
|
|
|
|
|
|
$this->{_conf_color}{color13} = $image->colorAllocateAlpha( @{$ref_color13} );
|
314
|
|
|
|
|
|
|
$this->{_conf_color}{color23} = $image->colorAllocateAlpha( @{$ref_color23} );
|
315
|
|
|
|
|
|
|
$this->{_conf_color}{color123} = $image->colorAllocateAlpha( @{$ref_color123} );
|
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
$image->fill( $this->{_coords}{xt3}, $this->{_coords}{yt3}, $this->{_conf_color}{color3} );
|
318
|
|
|
|
|
|
|
$image->fill( $this->{_coords}{xt13}, $this->{_coords}{yt13}, $this->{_conf_color}{color13} );
|
319
|
|
|
|
|
|
|
$image->fill( $this->{_coords}{xt23}, $this->{_coords}{yt23}, $this->{_conf_color}{color23} );
|
320
|
|
|
|
|
|
|
$image->fill( $this->{_coords}{xt123}, $this->{_coords}{yt123}, $this->{_conf_color}{color123} );
|
321
|
|
|
|
|
|
|
push @{ $this->{_colors_regions} }, $this->{_colors}->[2], $ref_color13, $ref_color23, $ref_color123;
|
322
|
|
|
|
|
|
|
}
|
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont,
|
325
|
|
|
|
|
|
|
$this->{_coords}{xt3},
|
326
|
|
|
|
|
|
|
$this->{_coords}{yt3},
|
327
|
|
|
|
|
|
|
$data3, $this->{_conf_color}{black}
|
328
|
|
|
|
|
|
|
);
|
329
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont,
|
330
|
|
|
|
|
|
|
$this->{_coords}{xt13},
|
331
|
|
|
|
|
|
|
$this->{_coords}{yt13},
|
332
|
|
|
|
|
|
|
$data13, $this->{_conf_color}{black}
|
333
|
|
|
|
|
|
|
);
|
334
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont,
|
335
|
|
|
|
|
|
|
$this->{_coords}{xt23},
|
336
|
|
|
|
|
|
|
$this->{_coords}{yt23},
|
337
|
|
|
|
|
|
|
$data23, $this->{_conf_color}{black}
|
338
|
|
|
|
|
|
|
);
|
339
|
|
|
|
|
|
|
$image->string( gdMediumBoldFont,
|
340
|
|
|
|
|
|
|
$this->{_coords}{xt123},
|
341
|
|
|
|
|
|
|
$this->{_coords}{yt123},
|
342
|
|
|
|
|
|
|
$data123, $this->{_conf_color}{black}
|
343
|
|
|
|
|
|
|
);
|
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
$this->{_dim}{Hc} = $this->{_dim}{D} + $this->{_dim}{R};
|
346
|
|
|
|
|
|
|
push @{ $this->{_regions} }, $data3, $data13, $data23, $data123;
|
347
|
|
|
|
|
|
|
push @{ $this->{_listregions} }, \@list3, \@list13, \@list23, \@list123;
|
348
|
|
|
|
|
|
|
}
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
return 1;
|
351
|
|
|
|
|
|
|
}
|
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
sub get_list_regions {
|
354
|
|
|
|
|
|
|
my $this = shift;
|
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
if ( $this->{_listregions} ) { return @{ $this->{_listregions} }; }
|
357
|
|
|
|
|
|
|
return;
|
358
|
|
|
|
|
|
|
}
|
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
sub get_regions {
|
361
|
|
|
|
|
|
|
my $this = shift;
|
362
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
if ( $this->{_regions} ) { return @{ $this->{_regions} }; }
|
364
|
|
|
|
|
|
|
return;
|
365
|
|
|
|
|
|
|
}
|
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub get_colors_regions {
|
368
|
|
|
|
|
|
|
my $this = shift;
|
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
if ( @{ $this->{_regions} } == $MIN_LIST_REGION or @{ $this->{_regions} } == $MAX_LIST_REGION ) {
|
371
|
|
|
|
|
|
|
return @{ $this->{_colors_regions} };
|
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
}
|
374
|
|
|
|
|
|
|
else {
|
375
|
|
|
|
|
|
|
croak('No data to plot');
|
376
|
|
|
|
|
|
|
}
|
377
|
|
|
|
|
|
|
return;
|
378
|
|
|
|
|
|
|
}
|
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
sub _moy_color {
|
381
|
|
|
|
|
|
|
my ( $this, @couleurs ) = @_;
|
382
|
|
|
|
|
|
|
my ( $R, $G, $B, $A ) = @RGBA;
|
383
|
|
|
|
|
|
|
foreach my $ref_couleur (@couleurs) {
|
384
|
|
|
|
|
|
|
my ( $R2, $G2, $B2, $A2 ) = @{$ref_couleur};
|
385
|
|
|
|
|
|
|
$R += $R2;
|
386
|
|
|
|
|
|
|
$G += $G2;
|
387
|
|
|
|
|
|
|
$B += $B2;
|
388
|
|
|
|
|
|
|
$A += $A2;
|
389
|
|
|
|
|
|
|
}
|
390
|
|
|
|
|
|
|
my $total = scalar @couleurs;
|
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
my @moy_couleur = ( int( $R / $total ), int( $G / $total ), int( $B / $total ), int( $A / $total ) );
|
393
|
|
|
|
|
|
|
return \@moy_couleur;
|
394
|
|
|
|
|
|
|
}
|
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
sub plot_histogram {
|
397
|
|
|
|
|
|
|
my $this = shift;
|
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
# Get data regions
|
400
|
|
|
|
|
|
|
my @regions = $this->get_regions();
|
401
|
|
|
|
|
|
|
my ( @data, @names );
|
402
|
|
|
|
|
|
|
if ( scalar @regions == $MIN_LIST_REGION ) {
|
403
|
|
|
|
|
|
|
@data = (
|
404
|
|
|
|
|
|
|
[ 'Region 1', 'Region 2', 'Region 1/2', ],
|
405
|
|
|
|
|
|
|
[ $regions[0], undef, undef, ],
|
406
|
|
|
|
|
|
|
[ undef, $regions[1], undef, ],
|
407
|
|
|
|
|
|
|
[ undef, undef, $regions[2], ],
|
408
|
|
|
|
|
|
|
[ undef, undef, undef, ],
|
409
|
|
|
|
|
|
|
[ undef, undef, undef, ],
|
410
|
|
|
|
|
|
|
[ undef, undef, undef, ],
|
411
|
|
|
|
|
|
|
[ undef, undef, undef, ],
|
412
|
|
|
|
|
|
|
);
|
413
|
|
|
|
|
|
|
}
|
414
|
|
|
|
|
|
|
elsif ( scalar @regions == $MAX_LIST_REGION ) {
|
415
|
|
|
|
|
|
|
@data = (
|
416
|
|
|
|
|
|
|
[ 'Region 1', 'Region 2', 'Region 1/2', 'Region 3', 'Region 1/3', 'Region 2/3', 'Region 1/2/3' ],
|
417
|
|
|
|
|
|
|
[ $regions[0], undef, undef, undef, undef, undef, undef, ],
|
418
|
|
|
|
|
|
|
[ undef, $regions[1], undef, undef, undef, undef, undef, ],
|
419
|
|
|
|
|
|
|
[ undef, undef, $regions[2], undef, undef, undef, undef, ],
|
420
|
|
|
|
|
|
|
[ undef, undef, undef, $regions[3], undef, undef, undef, ],
|
421
|
|
|
|
|
|
|
[ undef, undef, undef, undef, $regions[4], undef, undef, ],
|
422
|
|
|
|
|
|
|
[ undef, undef, undef, undef, undef, $regions[5], undef, ],
|
423
|
|
|
|
|
|
|
[ undef, undef, undef, undef, undef, undef, $regions[6], ],
|
424
|
|
|
|
|
|
|
);
|
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
}
|
427
|
|
|
|
|
|
|
else {
|
428
|
|
|
|
|
|
|
croak('No data to plot an histogram');
|
429
|
|
|
|
|
|
|
}
|
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
my $graph = GD::Graph::bars->new( $this->{_width}, $this->{_height} );
|
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
if ( $this->{_circles}{number} == $MIN_LEGEND and $this->{_legends}{number} == $MIN_LEGEND ) {
|
434
|
|
|
|
|
|
|
@names = (
|
435
|
|
|
|
|
|
|
$this->{_legend}->[0],
|
436
|
|
|
|
|
|
|
$this->{_legend}->[1],
|
437
|
|
|
|
|
|
|
$this->{_legend}->[0] . $SLASH . $this->{_legend}->[1],
|
438
|
|
|
|
|
|
|
);
|
439
|
|
|
|
|
|
|
$graph->set_legend(@names);
|
440
|
|
|
|
|
|
|
}
|
441
|
|
|
|
|
|
|
elsif ( $this->{_circles}{number} == $MAX_LEGEND and $this->{_legends}{number} == $MAX_LEGEND ) {
|
442
|
|
|
|
|
|
|
@names = (
|
443
|
|
|
|
|
|
|
$this->{_legend}->[0],
|
444
|
|
|
|
|
|
|
$this->{_legend}->[1],
|
445
|
|
|
|
|
|
|
$this->{_legend}->[0] . $SLASH . $this->{_legend}->[1],
|
446
|
|
|
|
|
|
|
$this->{_legend}->[2],
|
447
|
|
|
|
|
|
|
$this->{_legend}->[0] . $SLASH . $this->{_legend}->[2],
|
448
|
|
|
|
|
|
|
$this->{_legend}->[1] . $SLASH . $this->{_legend}->[2],
|
449
|
|
|
|
|
|
|
$this->{_legend}->[0] . $SLASH . $this->{_legend}->[1] . $SLASH . $this->{_legend}->[2],
|
450
|
|
|
|
|
|
|
);
|
451
|
|
|
|
|
|
|
$graph->set_legend(@names);
|
452
|
|
|
|
|
|
|
}
|
453
|
|
|
|
|
|
|
elsif ( $this->{_circles}{number} > 0
|
454
|
|
|
|
|
|
|
and $this->{_legends}{number} > 0
|
455
|
|
|
|
|
|
|
and $this->{_circles}{number} != $this->{_legends}{number} )
|
456
|
|
|
|
|
|
|
{
|
457
|
|
|
|
|
|
|
carp("You have to set $this->{_circles}{number} legends if you want to see a legend");
|
458
|
|
|
|
|
|
|
}
|
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
$graph->set(
|
461
|
|
|
|
|
|
|
cumulate => 'true',
|
462
|
|
|
|
|
|
|
box_axis => 0,
|
463
|
|
|
|
|
|
|
x_ticks => 0,
|
464
|
|
|
|
|
|
|
x_plot_values => 0,
|
465
|
|
|
|
|
|
|
) or carp $graph->error;
|
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
my @color_regions = map { GD::Graph::colour::rgb2hex( @{$_}[ 0 .. 2 ] ) } $this->get_colors_regions();
|
468
|
|
|
|
|
|
|
$graph->set( dclrs => \@color_regions );
|
469
|
|
|
|
|
|
|
my $gd = $graph->plot( \@data ) or croak $graph->error;
|
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
return $gd;
|
472
|
|
|
|
|
|
|
}
|
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
1; # End of Venn::Chart
|
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
__END__
|