line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
############################################################ |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Module: GD::Graph::pie3d |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# Description: |
6
|
|
|
|
|
|
|
# This is merely a wrapper around GD::Graph::pie that forces |
7
|
|
|
|
|
|
|
# the 3d option for pie charts. |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# Created: 2000.Jan.19 by Jeremy Wadsack for Wadsack-Allen Digital Group |
10
|
|
|
|
|
|
|
# Copyright (C) 2000,2001 Wadsack-Allen. All rights reserved. |
11
|
|
|
|
|
|
|
############################################################ |
12
|
|
|
|
|
|
|
# Date Modification Author |
13
|
|
|
|
|
|
|
# ---------------------------------------------------------- |
14
|
|
|
|
|
|
|
# 2000APR18 Modified to be compatible w/ GD::Graph 1.30 JW |
15
|
|
|
|
|
|
|
# 2000APR24 Set default slice label color to black JW |
16
|
|
|
|
|
|
|
# 2001Feb16 Added support for a legend JW |
17
|
|
|
|
|
|
|
############################################################ |
18
|
|
|
|
|
|
|
package GD::Graph::pie3d; |
19
|
|
|
|
|
|
|
|
20
|
1
|
|
|
1
|
|
1036
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
36
|
|
21
|
1
|
|
|
1
|
|
1085
|
use GD; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use GD::Graph; |
23
|
|
|
|
|
|
|
use GD::Graph::pie; |
24
|
|
|
|
|
|
|
use GD::Graph::utils qw(:all); |
25
|
|
|
|
|
|
|
use Carp; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
@GD::Graph::pie3d::ISA = qw( GD::Graph::pie ); |
28
|
|
|
|
|
|
|
$GD::Graph::pie3d::VERSION = '0.63'; |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
my %Defaults = ( |
31
|
|
|
|
|
|
|
'3d' => 1, |
32
|
|
|
|
|
|
|
axislabelclr => 'black', # values on slices. black because default colors use dblue |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# Size of the legend markers |
35
|
|
|
|
|
|
|
legend_marker_height => 8, |
36
|
|
|
|
|
|
|
legend_marker_width => 12, |
37
|
|
|
|
|
|
|
legend_spacing => 4, |
38
|
|
|
|
|
|
|
legend_placement => 'BC', # '[BR][LCR]' |
39
|
|
|
|
|
|
|
lg_cols => undef, |
40
|
|
|
|
|
|
|
legend_frame_margin => 4, |
41
|
|
|
|
|
|
|
legend_frame_size => undef, |
42
|
|
|
|
|
|
|
); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
# PRIVATE |
45
|
|
|
|
|
|
|
# Have to include because this is a different %Defaults hash |
46
|
|
|
|
|
|
|
sub _has_default { |
47
|
|
|
|
|
|
|
my $self = shift; |
48
|
|
|
|
|
|
|
my $attr = shift || return; |
49
|
|
|
|
|
|
|
exists $Defaults{$attr} || $self->SUPER::_has_default($attr); |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub initialise { |
53
|
|
|
|
|
|
|
my $self = shift; |
54
|
|
|
|
|
|
|
my $rc = $self->SUPER::initialise(); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
while( my($key, $val) = each %Defaults ) { |
57
|
|
|
|
|
|
|
$self->{$key} = $val; |
58
|
|
|
|
|
|
|
} # end while |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
$self->set_legend_font(GD::gdTinyFont); |
61
|
|
|
|
|
|
|
return $rc; |
62
|
|
|
|
|
|
|
} # end initialise |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# Add lengend calc and draw code |
65
|
|
|
|
|
|
|
sub plot |
66
|
|
|
|
|
|
|
{ |
67
|
|
|
|
|
|
|
my $self = shift; |
68
|
|
|
|
|
|
|
my $data = shift; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
$self->check_data($data) or return; |
71
|
|
|
|
|
|
|
$self->init_graph() or return; |
72
|
|
|
|
|
|
|
$self->setup_text() or return; |
73
|
|
|
|
|
|
|
$self->setup_legend(); |
74
|
|
|
|
|
|
|
$self->setup_coords() or return; |
75
|
|
|
|
|
|
|
$self->{b_margin} += 4 if $self->{label}; # Kludge for descenders |
76
|
|
|
|
|
|
|
$self->draw_text() or return; |
77
|
|
|
|
|
|
|
$self->draw_pie() or return; |
78
|
|
|
|
|
|
|
$self->draw_data() or return; |
79
|
|
|
|
|
|
|
$self->draw_legend(); |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
return $self->{graph}; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
# Added legend stuff |
85
|
|
|
|
|
|
|
sub setup_text |
86
|
|
|
|
|
|
|
{ |
87
|
|
|
|
|
|
|
my $self = shift; |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
my $rc = $self->SUPER::setup_text( @_ ); |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
$self->{gdta_legend}->set(colour => $self->{legendci}); |
92
|
|
|
|
|
|
|
$self->{gdta_legend}->set_align('top', 'left'); |
93
|
|
|
|
|
|
|
$self->{lgfh} = $self->{gdta_legend}->get('height'); |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
return $rc |
96
|
|
|
|
|
|
|
} # end setup_text |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# Inherit everything else from GD::Graph::pie |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# Legend Support. Added 16.Feb.2001 - JW/WADG |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub set_legend # List of legend keys |
104
|
|
|
|
|
|
|
{ |
105
|
|
|
|
|
|
|
my $self = shift; |
106
|
|
|
|
|
|
|
$self->{legend} = [@_]; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub set_legend_font # (font name) |
110
|
|
|
|
|
|
|
{ |
111
|
|
|
|
|
|
|
my $self = shift; |
112
|
|
|
|
|
|
|
$self->_set_font('gdta_legend', @_); |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
# |
118
|
|
|
|
|
|
|
# Legend |
119
|
|
|
|
|
|
|
# |
120
|
|
|
|
|
|
|
sub setup_legend |
121
|
|
|
|
|
|
|
{ |
122
|
|
|
|
|
|
|
my $self = shift; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
return unless defined $self->{legend}; |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
my $maxlen = 0; |
127
|
|
|
|
|
|
|
my $num = 0; |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
# Save some variables |
130
|
|
|
|
|
|
|
$self->{r_margin_abs} = $self->{r_margin}; |
131
|
|
|
|
|
|
|
$self->{b_margin_abs} = $self->{b_margin}; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
foreach my $legend (@{$self->{legend}}) |
134
|
|
|
|
|
|
|
{ |
135
|
|
|
|
|
|
|
if (defined($legend) and $legend ne "") |
136
|
|
|
|
|
|
|
{ |
137
|
|
|
|
|
|
|
$self->{gdta_legend}->set_text($legend); |
138
|
|
|
|
|
|
|
my $len = $self->{gdta_legend}->get('width'); |
139
|
|
|
|
|
|
|
$maxlen = ($maxlen > $len) ? $maxlen : $len; |
140
|
|
|
|
|
|
|
$num++; |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
# Legend for Pie goes over first set, and all points |
143
|
|
|
|
|
|
|
last if $num >= $self->{_data}->num_points; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
$self->{lg_num} = $num; |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# calculate the height and width of each element |
149
|
|
|
|
|
|
|
my $legend_height = _max($self->{lgfh}, $self->{legend_marker_height}); |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
$self->{lg_el_width} = |
152
|
|
|
|
|
|
|
$maxlen + $self->{legend_marker_width} + 3 * $self->{legend_spacing}; |
153
|
|
|
|
|
|
|
$self->{lg_el_height} = $legend_height + 2 * $self->{legend_spacing}; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
my ($lg_pos, $lg_align) = split(//, $self->{legend_placement}); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
if ($lg_pos eq 'R') |
158
|
|
|
|
|
|
|
{ |
159
|
|
|
|
|
|
|
# Always work in one column |
160
|
|
|
|
|
|
|
$self->{lg_cols} = 1; |
161
|
|
|
|
|
|
|
$self->{lg_rows} = $num; |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
# Just for completeness, might use this in later versions |
164
|
|
|
|
|
|
|
$self->{lg_x_size} = $self->{lg_cols} * $self->{lg_el_width}; |
165
|
|
|
|
|
|
|
$self->{lg_y_size} = $self->{lg_rows} * $self->{lg_el_height}; |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
# Adjust the right margin for the rest of the graph |
168
|
|
|
|
|
|
|
$self->{r_margin} += $self->{lg_x_size}; |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# Adjust for frame if defined |
171
|
|
|
|
|
|
|
if( $self->{legend_frame_size} ) { |
172
|
|
|
|
|
|
|
$self->{r_margin} += 2 * ($self->{legend_frame_margin} + $self->{legend_frame_size}); |
173
|
|
|
|
|
|
|
} # end if; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
# Set the x starting point |
176
|
|
|
|
|
|
|
$self->{lg_xs} = $self->{width} - $self->{r_margin}; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
# Set the y starting point, depending on alignment |
179
|
|
|
|
|
|
|
if ($lg_align eq 'T') |
180
|
|
|
|
|
|
|
{ |
181
|
|
|
|
|
|
|
$self->{lg_ys} = $self->{t_margin}; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
elsif ($lg_align eq 'B') |
184
|
|
|
|
|
|
|
{ |
185
|
|
|
|
|
|
|
$self->{lg_ys} = $self->{height} - $self->{b_margin} - |
186
|
|
|
|
|
|
|
$self->{lg_y_size}; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
else # default 'C' |
189
|
|
|
|
|
|
|
{ |
190
|
|
|
|
|
|
|
my $height = $self->{height} - $self->{t_margin} - |
191
|
|
|
|
|
|
|
$self->{b_margin}; |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
$self->{lg_ys} = |
194
|
|
|
|
|
|
|
int($self->{t_margin} + $height/2 - $self->{lg_y_size}/2) ; |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
else # 'B' is the default |
198
|
|
|
|
|
|
|
{ |
199
|
|
|
|
|
|
|
# What width can we use |
200
|
|
|
|
|
|
|
my $width = $self->{width} - $self->{l_margin} - $self->{r_margin}; |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
(!defined($self->{lg_cols})) and |
203
|
|
|
|
|
|
|
$self->{lg_cols} = int($width/$self->{lg_el_width}); |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
$self->{lg_cols} = _min($self->{lg_cols}, $num); |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
$self->{lg_rows} = |
208
|
|
|
|
|
|
|
int($num / $self->{lg_cols}) + (($num % $self->{lg_cols}) ? 1 : 0); |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
$self->{lg_x_size} = $self->{lg_cols} * $self->{lg_el_width}; |
211
|
|
|
|
|
|
|
$self->{lg_y_size} = $self->{lg_rows} * $self->{lg_el_height}; |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Adjust the bottom margin for the rest of the graph |
214
|
|
|
|
|
|
|
$self->{b_margin} += $self->{lg_y_size}; |
215
|
|
|
|
|
|
|
# Adjust for frame if defined |
216
|
|
|
|
|
|
|
if( $self->{legend_frame_size} ) { |
217
|
|
|
|
|
|
|
$self->{b_margin} += 2 * ($self->{legend_frame_margin} + $self->{legend_frame_size}); |
218
|
|
|
|
|
|
|
} # end if; |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# Set the y starting point |
221
|
|
|
|
|
|
|
$self->{lg_ys} = $self->{height} - $self->{b_margin}; |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
# Set the x starting point, depending on alignment |
224
|
|
|
|
|
|
|
if ($lg_align eq 'R') |
225
|
|
|
|
|
|
|
{ |
226
|
|
|
|
|
|
|
$self->{lg_xs} = $self->{width} - $self->{r_margin} - |
227
|
|
|
|
|
|
|
$self->{lg_x_size}; |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
elsif ($lg_align eq 'L') |
230
|
|
|
|
|
|
|
{ |
231
|
|
|
|
|
|
|
$self->{lg_xs} = $self->{l_margin}; |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
else # default 'C' |
234
|
|
|
|
|
|
|
{ |
235
|
|
|
|
|
|
|
$self->{lg_xs} = |
236
|
|
|
|
|
|
|
int($self->{l_margin} + $width/2 - $self->{lg_x_size}/2); |
237
|
|
|
|
|
|
|
} |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
sub draw_legend |
242
|
|
|
|
|
|
|
{ |
243
|
|
|
|
|
|
|
my $self = shift; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
return unless defined $self->{legend}; |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
my $xl = $self->{lg_xs} + $self->{legend_spacing}; |
248
|
|
|
|
|
|
|
my $y = $self->{lg_ys} + $self->{legend_spacing} - 1; |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
# If there's a frame, offset by the size and margin |
251
|
|
|
|
|
|
|
$xl += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size}; |
252
|
|
|
|
|
|
|
$y += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size}; |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
my $i = 0; |
255
|
|
|
|
|
|
|
my $row = 1; |
256
|
|
|
|
|
|
|
my $x = $xl; # start position of current element |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
foreach my $legend (@{$self->{legend}}) |
259
|
|
|
|
|
|
|
{ |
260
|
|
|
|
|
|
|
$i++; |
261
|
|
|
|
|
|
|
# Legend for Pie goes over first set, and all points |
262
|
|
|
|
|
|
|
last if $i > $self->{_data}->num_points; |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
my $xe = $x; # position within an element |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
next unless defined($legend) && $legend ne ""; |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
$self->draw_legend_marker($i, $xe, $y); |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
$xe += $self->{legend_marker_width} + $self->{legend_spacing}; |
271
|
|
|
|
|
|
|
my $ys = int($y + $self->{lg_el_height}/2 - $self->{lgfh}/2); |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
$self->{gdta_legend}->set_text($legend); |
274
|
|
|
|
|
|
|
$self->{gdta_legend}->draw($xe, $ys); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
$x += $self->{lg_el_width}; |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
if (++$row > $self->{lg_cols}) |
279
|
|
|
|
|
|
|
{ |
280
|
|
|
|
|
|
|
$row = 1; |
281
|
|
|
|
|
|
|
$y += $self->{lg_el_height}; |
282
|
|
|
|
|
|
|
$x = $xl; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# If there's a frame, draw it now |
287
|
|
|
|
|
|
|
if( $self->{legend_frame_size} ) { |
288
|
|
|
|
|
|
|
$x = $self->{lg_xs} + $self->{legend_spacing}; |
289
|
|
|
|
|
|
|
$y = $self->{lg_ys} + $self->{legend_spacing} - 1; |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
for $i ( 0 .. $self->{legend_frame_size} - 1 ) { |
292
|
|
|
|
|
|
|
$self->{graph}->rectangle( |
293
|
|
|
|
|
|
|
$x + $i, |
294
|
|
|
|
|
|
|
$y + $i, |
295
|
|
|
|
|
|
|
$x + $self->{lg_x_size} + 2 * $self->{legend_frame_margin} - $i - 1, |
296
|
|
|
|
|
|
|
$y + $self->{lg_y_size} + 2 * $self->{legend_frame_margin} - $i - 1, |
297
|
|
|
|
|
|
|
$self->{acci}, |
298
|
|
|
|
|
|
|
); |
299
|
|
|
|
|
|
|
} # end for |
300
|
|
|
|
|
|
|
} # end if |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
sub draw_legend_marker # data_set_number, x, y |
305
|
|
|
|
|
|
|
{ |
306
|
|
|
|
|
|
|
my $s = shift; |
307
|
|
|
|
|
|
|
my $n = shift; |
308
|
|
|
|
|
|
|
my $x = shift; |
309
|
|
|
|
|
|
|
my $y = shift; |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
my $g = $s->{graph}; |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
my $ci = $s->set_clr($s->pick_data_clr($n)); |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
$y += int($s->{lg_el_height}/2 - $s->{legend_marker_height}/2); |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
$g->filledRectangle( |
318
|
|
|
|
|
|
|
$x, $y, |
319
|
|
|
|
|
|
|
$x + $s->{legend_marker_width}, $y + $s->{legend_marker_height}, |
320
|
|
|
|
|
|
|
$ci |
321
|
|
|
|
|
|
|
); |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
$g->rectangle( |
324
|
|
|
|
|
|
|
$x, $y, |
325
|
|
|
|
|
|
|
$x + $s->{legend_marker_width}, $y + $s->{legend_marker_height}, |
326
|
|
|
|
|
|
|
$s->{acci} |
327
|
|
|
|
|
|
|
); |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
1; |