GD-Graph3d

 view release on metacpan or  search on metacpan

lib/GD/Graph/axestype3d.pm  view on Meta::CPAN

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
} # end initialise
 
# PUBLIC
# Inherit plot
# Inherit set
# Inherit setup_text
# Inherit set_x_label_font
# Inherit set_y_label_font
# Inherit set_x_axis_font
# Inherit set_y_axis_font
# Inherit set_legend
# Inherit set_legend_font
 
 
 
# ----------------------------------------------------------
# Sub: init_graph
#
# Args: (None)
#
# Description:
# Override GD::Graph::init_graph to add 3d shading colors,

lib/GD/Graph/axestype3d.pm  view on Meta::CPAN

122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
                $self->{'3d_highlights'}[$self->{alci}] = $self->set_clr( $self->_brighten( _rgb($self->{axislabelclr}) ) );
                $self->{'3d_shadows'}[$self->{alci}]    = $self->set_clr( $self->_darken( _rgb($self->{axislabelclr}) ) );
 
                $self->{'3d_highlights'}[$self->{acci}] = $self->set_clr( $self->_brighten( _rgb($self->{accentclr}) ) );
                $self->{'3d_shadows'}[$self->{acci}]    = $self->set_clr( $self->_darken( _rgb($self->{accentclr}) ) );
 
                $self->{'3d_highlights'}[$self->{valuesci}] = $self->set_clr( $self->_brighten( _rgb($self->{valuesclr}) ) );
                $self->{'3d_shadows'}[$self->{valuesci}]    = $self->set_clr( $self->_darken( _rgb($self->{valuesclr}) ) );
 
                $self->{'3d_highlights'}[$self->{legendci}] = $self->set_clr( $self->_brighten( _rgb($self->{legendclr}) ) );
                $self->{'3d_shadows'}[$self->{legendci}]    = $self->set_clr( $self->_darken( _rgb($self->{legendclr}) ) );
 
                if( $self->{boxclr} ) {
                        $self->{'3d_highlights'}[$self->{boxci}] = $self->set_clr( $self->_brighten( _rgb($self->{boxclr}) ) );
                        $self->{'3d_shadows'}[$self->{boxci}]    = $self->set_clr( $self->_darken( _rgb($self->{boxclr}) ) );
                } # end if
        } # end if
 
        return $self;
} # end init_graph

lib/GD/Graph/axestype3d.pm  view on Meta::CPAN

691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
# Inherit draw_ticks
# Inherit draw_data
# Inherit draw_data_set
# Inherit set_max_min
# Inherit get_max_y
# Inherit get_min_y
# Inherit get_max_min_y_all
# Inherit _get_bottom
# Inherit val_to_pixel
# Inherit setup_legend
 
 
# [JW] Override draw_legend and reverse the drawing order
# if cumulate is enabled so legend matches data on chart
sub draw_legend
{
        my $self = shift;
 
        return unless defined $self->{legend};
 
        my $xl = $self->{lg_xs} + $self->{legend_spacing};
        my $y  = $self->{lg_ys} + $self->{legend_spacing} - 1;
 
        # If there's a frame, offset by the size and margin
        $xl += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size};
        $y += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size};
 
        my $i = 0;
        my $row = 1;
        my $x = $xl;    # start position of current element
        my @legends = @{$self->{legend}};
        my $i_step = 1;
         
        # If we are working in cumulate mode, then reverse the drawing order
        if( $self->{cumulate} ) {
                @legends = reverse @legends;
                $i = scalar(@legends);
                $i = $self->{_data}->num_sets if $self->{_data}->num_sets < $i;
                $i++;
                $i_step = -1;
        } # end if
         
        foreach my $legend (@legends)
        {
                $i += $i_step;
 
                # Legend for Pie goes over first set, and all points
                # Works in either direction
                last if $i > $self->{_data}->num_sets;
                last if $i < 1;
 
                my $xe = $x;    # position within an element
 
                next unless defined($legend) && $legend ne "";
 
                $self->draw_legend_marker($i, $xe, $y);
 
                $xe += $self->{legend_marker_width} + $self->{legend_spacing};
                my $ys = int($y + $self->{lg_el_height}/2 - $self->{lgfh}/2);
 
                $self->{gdta_legend}->set_text($legend);
                $self->{gdta_legend}->draw($xe, $ys);
 
                $x += $self->{lg_el_width};
 
                if (++$row > $self->{lg_cols})
                {
                        $row = 1;
                        $y += $self->{lg_el_height};
                        $x = $xl;
                }
        }
         
        # If there's a frame, draw it now
        if( $self->{legend_frame_size} ) {
                $x = $self->{lg_xs} + $self->{legend_spacing};
                $y = $self->{lg_ys} + $self->{legend_spacing} - 1;
                 
                for $i ( 0 .. $self->{legend_frame_size} - 1 ) {
                        $self->{graph}->rectangle(
                                $x + $i,
                                $y + $i,
                                $x + $self->{lg_x_size} + 2 * $self->{legend_frame_margin} - $i - 1,
                                $y + $self->{lg_y_size} + 2 * $self->{legend_frame_margin} - $i - 1,
                                $self->{acci},
                        );
                } # end for
        } # end if
         
}
 
 
 
# Inherit draw_legend_marker
 
1;

lib/GD/Graph/lines3d.pm  view on Meta::CPAN

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 1999SEP18 Created 3D line chart class (this module)                   JAW
# 1999SEP19 Finished overwrite 1 style                                  JAW
# 1999SEP19 Polygon'd linewidth rendering                               JAW
# 2000SEP19 Converted to a GD::Graph class                              JAW
# 2000APR18 Modified for compatibility with GD::Graph 1.30              JAW
# 2000APR24 Fixed a lot of rendering bugs                               JAW
# 2000AUG19 Changed render code so lines have consitent width           JAW
# 2000AUG21 Added 3d shading                                            JAW
# 2000AUG24 Fixed shading top/botttom vs. postive/negative slope        JAW
# 2000SEP04 For single point "lines" made a short segment               JAW
# 2000OCT09 Fixed bug in rendering of legend                            JAW
#==========================================================================
# TODO
#               ** The new mitred corners don't work well at data anomlies. Like
#                  the set (0,0,1,0,0,0,1,0,1) Looks really wrong!
#               * Write a draw_data_set that draws the line so they appear to pass
#                 through one another. This means drawing a border edge at each
#                 intersection of the data lines so the points of pass-through show.
#                 Probably want to draw all filled polygons, then run through the data
#                 again finding intersections of line segments and drawing those edges.
#==========================================================================

lib/GD/Graph/lines3d.pm  view on Meta::CPAN

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
        $poly->addPt( $this->{face}[0], $this->{face}[1] );
        $poly->addPt( $this->{face}[2], $this->{face}[3] );
        $poly->addPt( $prev->{face}[2], $prev->{face}[3] );
 
        $self->{graph}->filledPolygon( $poly, $style );
        $self->{graph}->polygon( $poly, $self->{fgci} );
 
} # end draw line
 
# ----------------------------------------------------------
# Sub: draw_legend_marker
#
# Args: $dsn, $x, $y
#       $dsn    The dataset number to draw the marker for
#       $x      The x position of the marker
#       $y      The y position of the marker
#
# Description: Draws the legend marker for the specified
# dataset number at the given coordinates
# ----------------------------------------------------------
# Date      Modification                              Author
# ----------------------------------------------------------
# 2000OCT06 Fixed rendering bugs                          JW
# ----------------------------------------------------------
sub draw_legend_marker
{
        my $self = shift;
        my ($n, $x, $y) = @_;
 
        my $ci = $self->set_clr($self->pick_data_clr($n));
        my $type = $self->pick_line_type($n);
 
        $y += int($self->{lg_el_height}/2);
 
        #  Joe Smith <jms@tardis.Tymnet.COM>
        local($self->{line_width}) = 2;    # Make these show up better
 
        $self->draw_line(
                { coords => [$x, $y] },
                { coords => [$x + $self->{legend_marker_width}, $y] },
                undef,
                $type,
                $ci
        );
 
} # end draw_legend_marker
 
1;

lib/GD/Graph/pie3d.pm  view on Meta::CPAN

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# This is merely a wrapper around GD::Graph::pie that forces
# the 3d option for pie charts.
#
# Created: 2000.Jan.19 by Jeremy Wadsack for Wadsack-Allen Digital Group
#       Copyright (C) 2000,2001 Wadsack-Allen. All rights reserved.
############################################################
# Date      Modification                               Author
# ----------------------------------------------------------
# 2000APR18 Modified to be compatible w/ GD::Graph 1.30   JW
# 2000APR24 Set default slice label color to black        JW
# 2001Feb16 Added support for a legend                    JW
############################################################
 
use strict;
use GD;
use GD::Graph::utils qw(:all);
use Carp;
 
@GD::Graph::pie3d::ISA = qw( GD::Graph::pie );
$GD::Graph::pie3d::VERSION = '0.63';
 
my %Defaults = (
        '3d'         => 1,
        axislabelclr => 'black',     # values on slices. black because default colors use dblue
 
        # Size of the legend markers
        legend_marker_height    => 8,
        legend_marker_width     => 12,
        legend_spacing                  => 4,
        legend_placement                => 'BC',             # '[BR][LCR]'
        lg_cols                                 => undef,
        legend_frame_margin     => 4,
        legend_frame_size               => undef,
);
 
# PRIVATE
# Have to include because this is a different %Defaults hash
sub _has_default {
        my $self = shift;
        my $attr = shift || return;
        exists $Defaults{$attr} || $self->SUPER::_has_default($attr);
}
 
sub initialise {
        my $self = shift;
        my $rc = $self->SUPER::initialise();
 
        while( my($key, $val) = each %Defaults ) {
                $self->{$key} = $val;
        } # end while
 
        $self->set_legend_font(GD::gdTinyFont);
        return $rc;
} # end initialise
 
# Add lengend calc and draw code
sub plot
{
        my $self = shift;
        my $data = shift;
 
        $self->check_data($data)             or return;
        $self->init_graph()                  or return;
        $self->setup_text()                          or return;
        $self->setup_legend();
        $self->setup_coords()                        or return;
        $self->{b_margin} += 4 if $self->{label};         # Kludge for descenders
        $self->draw_text()                           or return;
        $self->draw_pie()                            or return;
        $self->draw_data()                           or return;
        $self->draw_legend();
 
        return $self->{graph};
}
 
# Added legend stuff
sub setup_text
{
        my $self = shift;
 
        my $rc = $self->SUPER::setup_text( @_ );
         
        $self->{gdta_legend}->set(colour => $self->{legendci});
        $self->{gdta_legend}->set_align('top', 'left');
        $self->{lgfh} = $self->{gdta_legend}->get('height');
         
        return $rc
} # end setup_text
 
# Inherit everything else from GD::Graph::pie
 
 
# Legend Support. Added 16.Feb.2001 - JW/WADG
 
sub set_legend # List of legend keys
{
        my $self = shift;
        $self->{legend} = [@_];
}
 
sub set_legend_font # (font name)
{
        my $self = shift;
        $self->_set_font('gdta_legend', @_);
}
 
 
 
#
# Legend
#
sub setup_legend
{
        my $self = shift;
 
        return unless defined $self->{legend};
 
        my $maxlen = 0;
        my $num = 0;
 
        # Save some variables
        $self->{r_margin_abs} = $self->{r_margin};
        $self->{b_margin_abs} = $self->{b_margin};
 
        foreach my $legend (@{$self->{legend}})
        {
                if (defined($legend) and $legend ne "")
                {
                        $self->{gdta_legend}->set_text($legend);
                        my $len = $self->{gdta_legend}->get('width');
                        $maxlen = ($maxlen > $len) ? $maxlen : $len;
                        $num++;
                }
                # Legend for Pie goes over first set, and all points
                last if $num >= $self->{_data}->num_points;
        }
 
        $self->{lg_num} = $num;
 
        # calculate the height and width of each element
        my $legend_height = _max($self->{lgfh}, $self->{legend_marker_height});
 
        $self->{lg_el_width} =
                $maxlen + $self->{legend_marker_width} + 3 * $self->{legend_spacing};
        $self->{lg_el_height} = $legend_height + 2 * $self->{legend_spacing};
 
        my ($lg_pos, $lg_align) = split(//, $self->{legend_placement});
 
        if ($lg_pos eq 'R')
        {
                # Always work in one column
                $self->{lg_cols} = 1;
                $self->{lg_rows} = $num;
 
                # Just for completeness, might use this in later versions
                $self->{lg_x_size} = $self->{lg_cols} * $self->{lg_el_width};
                $self->{lg_y_size} = $self->{lg_rows} * $self->{lg_el_height};
 
                # Adjust the right margin for the rest of the graph
                $self->{r_margin} += $self->{lg_x_size};
 
                # Adjust for frame if defined
                if( $self->{legend_frame_size} ) {
                        $self->{r_margin} += 2 * ($self->{legend_frame_margin} + $self->{legend_frame_size});
                } # end if;
 
                # Set the x starting point
                $self->{lg_xs} = $self->{width} - $self->{r_margin};
 
                # Set the y starting point, depending on alignment
                if ($lg_align eq 'T')
                {
                        $self->{lg_ys} = $self->{t_margin};
                }

lib/GD/Graph/pie3d.pm  view on Meta::CPAN

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
$self->{lg_rows} =
        int($num / $self->{lg_cols}) + (($num % $self->{lg_cols}) ? 1 : 0);
 
$self->{lg_x_size} = $self->{lg_cols} * $self->{lg_el_width};
$self->{lg_y_size} = $self->{lg_rows} * $self->{lg_el_height};
 
# Adjust the bottom margin for the rest of the graph
$self->{b_margin} += $self->{lg_y_size};
# Adjust for frame if defined
if( $self->{legend_frame_size} ) {
        $self->{b_margin} += 2 * ($self->{legend_frame_margin} + $self->{legend_frame_size});
} # end if;
 
# Set the y starting point
$self->{lg_ys} = $self->{height} - $self->{b_margin};
 
# Set the x starting point, depending on alignment
if ($lg_align eq 'R')
{
        $self->{lg_xs} = $self->{width} - $self->{r_margin} -
                $self->{lg_x_size};

lib/GD/Graph/pie3d.pm  view on Meta::CPAN

231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
                        $self->{lg_xs} = $self->{l_margin};
                }
                else # default 'C'
                {
                        $self->{lg_xs} = 
                                int($self->{l_margin} + $width/2 - $self->{lg_x_size}/2);
                }
        }
}
 
sub draw_legend
{
        my $self = shift;
 
        return unless defined $self->{legend};
 
        my $xl = $self->{lg_xs} + $self->{legend_spacing};
        my $y  = $self->{lg_ys} + $self->{legend_spacing} - 1;
 
        # If there's a frame, offset by the size and margin
        $xl += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size};
        $y += $self->{legend_frame_margin} + $self->{legend_frame_size} if $self->{legend_frame_size};
 
        my $i = 0;
        my $row = 1;
        my $x = $xl;    # start position of current element
 
        foreach my $legend (@{$self->{legend}})
        {
                $i++;
                # Legend for Pie goes over first set, and all points
                last if $i > $self->{_data}->num_points;
 
                my $xe = $x;    # position within an element
 
                next unless defined($legend) && $legend ne "";
 
                $self->draw_legend_marker($i, $xe, $y);
 
                $xe += $self->{legend_marker_width} + $self->{legend_spacing};
                my $ys = int($y + $self->{lg_el_height}/2 - $self->{lgfh}/2);
 
                $self->{gdta_legend}->set_text($legend);
                $self->{gdta_legend}->draw($xe, $ys);
 
                $x += $self->{lg_el_width};
 
                if (++$row > $self->{lg_cols})
                {
                        $row = 1;
                        $y += $self->{lg_el_height};
                        $x = $xl;
                }
        }
         
        # If there's a frame, draw it now
        if( $self->{legend_frame_size} ) {
                $x = $self->{lg_xs} + $self->{legend_spacing};
                $y = $self->{lg_ys} + $self->{legend_spacing} - 1;
                 
                for $i ( 0 .. $self->{legend_frame_size} - 1 ) {
                        $self->{graph}->rectangle(
                                $x + $i,
                                $y + $i,
                                $x + $self->{lg_x_size} + 2 * $self->{legend_frame_margin} - $i - 1,
                                $y + $self->{lg_y_size} + 2 * $self->{legend_frame_margin} - $i - 1,
                                $self->{acci},
                        );
                } # end for
        } # end if
         
}
 
sub draw_legend_marker # data_set_number, x, y
{
        my $s = shift;
        my $n = shift;
        my $x = shift;
        my $y = shift;
 
        my $g = $s->{graph};
 
        my $ci = $s->set_clr($s->pick_data_clr($n));
 
        $y += int($s->{lg_el_height}/2 - $s->{legend_marker_height}/2);
 
        $g->filledRectangle(
                $x, $y,
                $x + $s->{legend_marker_width}, $y + $s->{legend_marker_height},
                $ci
        );
 
        $g->rectangle(
                $x, $y,
                $x + $s->{legend_marker_width}, $y + $s->{legend_marker_height},
                $s->{acci}
        );
}
 
 
1;

t/visual-test.pl  view on Meta::CPAN

175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
            y_label           => 'Number of hits',
            title             => 'Web Site Traffic',
            line_width        => 15,
            box_axis          => 1,
            boxclr            => '#FFFFCC',
);        
ok( compare( $graph->plot( \@data ), 'line.png' ) );
 
 
#--------------------------------------------------#
# Large 3d line graph with 5 datasets & legend     #
#--------------------------------------------------#
 
$graph = new GD::Graph::lines3d( 800, 400 );
 
@data = (
  [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49],
  [320,2447,1832,0,2411,1666,196,2072,833,2302,554,980,973,740,1218,1430,1124,79,763,1545,645,612,139,1537,506,2345,8,1492,950,1502,1188,839,2321,1725,2352,829,1288,1919,363,109,1021,1445,2401,2209,43,2114,250,35,810,187,906],
  [715,2170,645,1835,1511,618,2031,1134,1871,1338,1070,1631,372,1516,1164,2388,1983,1964,1441,1775,2620,992,1966,1754,1602,2170,800,2341,201,2617,1726,1013,749,2217,216,579,1997,400,1482,278,180,872,677,1118,1497,945,1575,228,454,851,1313],
  [2820,2546,2750,2692,2537,2903,2599,2618,2960,2997,2882,2943,2847,2965,2798,2571,2564,2502,2713,2586,2909,2859,2586,2503,2708,2992,2805,2897,2744,2906,2607,2574,2852,2932,2566,2662,2774,2976,2819,2759,2575,2992,2513,2551,2721,2694,2659,2503,2636,27...
  [1082,1295,1267,1101,1017,1188,1051,1219,1141,1045,1145,1053,1011,1166,1200,1216,1297,1016,1299,1209,1280,1071,1063,1113,1276,1080,1045,1089,1145,1292,1250,1110,1205,1087,1058,1137,1191,1268,1092,1180,1181,1151,1108,1141,1053,1215,1046,1086,1165,12...

t/visual-test.pl  view on Meta::CPAN

202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    y_label => 'Pocet pristupu',
    title => 'Pristupy k fakultnimu informacnimu systemu',
    y_max_value => 4500,
    y_tick_number => 18,
    y_label_skip => 2,
    x_label_skip => 1,
    x_all_ticks => 1,
    x_labels_vertical => 1,
    box_axis => 0,
    y_long_ticks => 1,
    legend_placement => 'RD',
    legend_spacing => 10,
    );
 
$graph->set_legend( 'Subset A', 'Subset B', 'Subset C', 'Subset D', 'Subset E',);
 
ok( compare( $graph->plot( \@data ), 'multiline.png' ) );
 
#--------------------------------------------------#
# 3d Lines with x-tick-number set                  #
#--------------------------------------------------#
$graph = new GD::Graph::lines3d();
 
@data = (
           [ 0 .. 24 ],

t/visual-test.pl  view on Meta::CPAN

277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
           [ '(Unknown)' ],
           [ 100 ]
        );
$graph->set(
            title             => 'Organisational Use',
);        
 
ok( compare( $graph->plot( \@data ), "pie100-$GD_Graph_VERSION.png" ) );
 
#--------------------------------------------------#
# Stacked bar chart with legend                    #
#--------------------------------------------------#
$graph = new GD::Graph::bars3d();
 
@data = (
           ["1".."7"],
           [ 37,  25,   9,  10,   1,  30,  34],
           [ 12,  25,  56,  23,  51,  12,   8],
           [ 42,  25,  18,  32,   8,  13,  20],
);
 
$graph->set(
    cumulate     => 1,
    x_label      => 'Number',
    y_label      => 'Usage',
    title        => 'Total usage',
    box_axis     => 0,
    y_long_ticks => 1,
         legend_placement => 'RC',
);
 
$graph->set_legend( 'Red', 'Green', 'Blue' );
 
ok( compare( $graph->plot( \@data ), 'stackbar-legend.png' ) );
 
 
 
exit 0;
 
##############################################################################
#                                END OF TESTS                                #
##############################################################################



( run in 0.255 second using v1.01-cache-2.11-cpan-454fe037f31 )