[system] / trunk / pg / lib / WWPlot.pm Repository:
ViewVC logotype

View of /trunk/pg/lib/WWPlot.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6376 - (download) (as text) (annotate)
Sat Jul 17 19:42:05 2010 UTC (9 years, 7 months ago) by gage
File size: 18694 byte(s)
Updating VectorField.pm so that it works without AUTOLOAD

    1 
    2 #  this module holds the graph.  Several functions
    3 #  and labels may be plotted on
    4 #  the graph.
    5 
    6 # constructor   new WWPlot(300,400) constructs an image of width 300 by height 400 pixels
    7 # plot->imageName gives the image's name
    8 
    9 
   10 =head1 NAME
   11 
   12   WWPlot
   13 
   14 =head1 SYNPOSIS
   15 
   16     use Global;
   17   use Carp;
   18   use GD;
   19 
   20   $graph = new WWPlot(400,400); # creates a graph 400 pixels by 400 pixels
   21   $graph->fn($fun1, $fun2);     # installs functions $fun1 and $fun2 in $graph
   22   $image_binary = $graph->draw();  # creates the gif/png image of the functions installed in the graph
   23 
   24 =head1 DESCRIPTION
   25 
   26 This module creates a graph object -- a canvas on which to draw functions, labels, and other symbols.
   27 The graph can be drawn with an axis, with a grid, and/or with an axis with tick marks.
   28 The position of the axes and the granularity of the grid and tick marks can be specified.
   29 
   30 =head2 new
   31 
   32   $graph = new WWPlot(400,400);
   33 
   34 Creates a graph object 400 pixels by 400 pixels.  The size is required.
   35 
   36 
   37 
   38 
   39 =head2 Methods and properties
   40 
   41 =over 4
   42 
   43 =item xmin, xmax, ymin, ymax
   44 
   45 These determine the world co-ordinates of the graph. The constructions
   46 
   47   $new_xmin = $graph->xmin($new_xmin);
   48 and
   49   $current_xmin = $graph->xmin();
   50 
   51 set and read the values.
   52 
   53 =item fn, lb, stamps
   54 
   55 These arrays contain references to the functions (fn), the labels (lb) and the stamped images (stamps) such
   56 as open or closed circles which will drawn when the graph is asked to draw itself. Since each of these
   57 objects is expected to draw itself, there is not a strong difference between the different arrays of objects.
   58 The principle difference is the order in which they are drawn.  The axis and grids are drawn first, followed
   59 by the functions, then the labels, then the stamps.
   60 
   61 You can add a function with either of the commands
   62 
   63   @fn = $graph->fn($new_fun_ref1, $new_fun_ref2);
   64   @fn = $graph->install($new_fun_ref1, $new_fun_ref2);
   65 
   66 the constructions for labels and stamps are respectively:
   67 
   68   @labels = $graph->lb($new_label);
   69   @stamps = $graph->stamps($new_stamp);
   70 
   71 while
   72 
   73   @functions = $graph->fn();
   74 
   75 will give a list of the current functions (similary for labels and stamps).
   76 
   77 Either of the  commands
   78 
   79   $graph->fn('reset');
   80   $graph->fn('erase');
   81 
   82 will erase the array containing the functions and similary for the label and stamps arrays.
   83 
   84 
   85 =item h_axis, v_axis
   86 
   87   $h_axis_coordinate = $graph -> h_axis();
   88   $new_axis    =       $grpah -> h_axis($new_axis);
   89 
   90 Respectively read and set the vertical coordinate value in real world coordinates where the
   91 horizontal axis intersects the vertical one.  The same construction reads and sets the coordinate
   92 value for the vertical axis. The axis is drawn more darkly than the grids.
   93 
   94 =item h_ticks, v_ticks
   95 
   96   @h_ticks = $graph -> h_ticks();
   97   @h_ticks = $graph -> h_ticks( $tick1, $tick2, $tick3, $tick4   );
   98 
   99 reads and sets the coordinates for the tick marks along the horizontal axis.  The values
  100 $tick1, etc are the real world coordinate values for each of the tick marks.
  101 
  102 =item h_grid, v_grid
  103 
  104   @h_grid = $graph -> h_grid();
  105   @h_grid = $graph -> h_grid( $grid1, $grid2, $grid3, $grid4   );
  106 
  107 reads and sets the verical coordinates for the horizontal grid lines.  The values
  108 $grid1, etc are the real world coordinate values where the horizontal grid meets the
  109 vertical axis.
  110 
  111 =item draw
  112 
  113   $image = $graph ->draw();
  114 
  115 Draws the  image of the graph.
  116 
  117 =item size
  118 
  119   ($horizontal_pixels, $vertical_pixels)  = @{$graph ->size()};
  120 
  121 Reads the size of the graph image in pixels.  This cannot be reset. It is defined by
  122 the new constructor and cannot be changed.
  123 
  124 =item colors
  125 
  126   %colors =$graph->colors();
  127 
  128 Returns the hash containing the colors known to the graph.  The keys are the names of the
  129 colors and the values are the color indices used by the graph.
  130 
  131 =item new_color
  132 
  133   $graph->new_color('white', 255,255,255);
  134 
  135 defines a new color named white with red, green and blue densities 255.
  136 
  137 =item im
  138 
  139   $GD_image = $graph->im();
  140 
  141 Allows access to the GD image object contained in the graph object.  You can use this
  142 to access methods defined in GD but not supported directly by WWPlot. (See the documentation
  143 for GD.)
  144 
  145 =item moveTo, lineTo, arrowTo
  146 
  147   $graph->moveTo($x,$y);
  148   $graph->lineTo($x,$y,$color);
  149   $graph->lineTo($x,$y,$color,$thickness);
  150   $graph->lineTo($x,$y,$color,$thickness,'dashed');
  151   $graph->arrowTo($x,$y,$color);
  152   $graph->arrowTo($x,$y,$color,$thickness);
  153   $graph->arrowTo($x,$y,$color,$thickness,'dashed');
  154 
  155 Moves to the point ($x, $y) (defined in real world coordinates) or draws a line or arrow
  156 from the current position to the specified point ($x, $y) using the color $color.  $color
  157 is the name, e.g. 'white',  of the color, not an index value or RGB specification.
  158 $thickness gives the thickness of the line or arrow to draw.  If 'dashed' is specified,
  159 the line or arrow is rendered with a dashed line.  These are low level call
  160 back routines used by the function, label and stamp objects to draw themselves.
  161 
  162 =item ii, jj
  163 
  164 These functions translate from real world to pixel coordinates.
  165 
  166   $pixels_down_from_top = $graph -> jj($y);
  167 
  168 
  169 =back
  170 
  171 =cut
  172 
  173 BEGIN {
  174   be_strict(); # an alias for use strict.  This means that all global variable must contain main:: as a prefix.
  175 
  176 }
  177 package WWPlot;
  178 
  179 
  180 #use Exporter;
  181 #use DynaLoader;
  182 #use GD;
  183 
  184 @WWPlot::ISA=undef;
  185 $WWPlot::AUTOLOAD = undef;
  186 @WWPlot::ISA = qw(GD PGcore);
  187 
  188 
  189 if ( $GD::VERSION > '1.20' ) {
  190       $WWPlot::use_png = 1;  # in version 1.20 and later of GD, gif's are not supported by png files are
  191                              # This only affects the draw method.
  192 } else {
  193       $WWPlot::use_png = 0;
  194 }
  195 
  196 my  $last_image_number=0;    #class variable.  Keeps track of how many images have been made.
  197 
  198 
  199 
  200 my %fields = (  # initialization only!!!
  201   xmin      =>  -1,
  202   xmax      =>  1,
  203   ymin      =>  -1,
  204   ymax      =>  1,
  205   imageName =>  undef,
  206   position  =>  undef,  #used internally in the draw routine lineTo
  207 );
  208 
  209 
  210 
  211 sub new {
  212   my $class =shift;
  213   my @size = @_;   # the dimensions in pixels of the image
  214   my $self = { im     =>  new GD::Image(@size),
  215         %fields,
  216         size    =>  [@size],
  217         fn      =>  [],
  218         fillRegion      =>      [],
  219         lb      =>  [],
  220         stamps    =>  [],
  221         colors    =>  {},
  222         hticks    =>  [],
  223         vticks      =>  [],
  224         hgrid   =>  [],
  225         vgrid   =>  [],
  226         haxis       =>  [],
  227         vaxis       =>  [],
  228 
  229 
  230   };
  231 
  232   bless $self, $class;
  233   $self ->  _initialize;
  234   return $self;
  235 }
  236 
  237 # access methods for function list, label list and image
  238 sub fn {
  239   my $self =  shift;
  240 
  241   if (@_ == 0) {
  242     # do nothing if input is empty
  243   } elsif ($_[0] eq 'reset' or $_[0] eq 'erase' ) {
  244     $self->{fn} = [];
  245   } else {
  246     push(@{$self->{fn}},@_) if @_;
  247   }
  248   @{$self->{fn}};
  249 }
  250 # access methods for fillRegion list, label list and image
  251 sub fillRegion {
  252   my $self =  shift;
  253 
  254   if (@_ == 0) {
  255     # do nothing if input is empty
  256   } elsif ($_[0] eq 'reset' or $_[0] eq 'erase' ) {
  257     $self->{fillRegion} = [];
  258   } else {
  259     push(@{$self->{fillRegion}},@_) if @_;
  260   }
  261   @{$self->{fillRegion}};
  262 }
  263 
  264 sub install {  # synonym for  installing a function
  265   fn(@_);
  266 }
  267 
  268 sub lb {
  269   my $self =  shift;
  270   if (@_ == 0) {
  271     # do nothing if input is empty
  272   } elsif ($_[0] eq 'reset' or $_[0] eq 'erase' ) {
  273     $self->{lb} = [];
  274   } else {
  275     push(@{$self->{lb}},@_) if @_;
  276   }
  277 
  278   @{$self->{lb}};
  279 }
  280 
  281 sub stamps {
  282   my $self =  shift;
  283   if (@_ == 0) {
  284     # do nothing if input is empty
  285   } elsif ($_[0] eq 'reset' or $_[0] eq 'erase' ) {
  286     $self->{stamps} = [];
  287   } else {
  288     push(@{$self->{stamps}},@_) if @_;
  289   }
  290 
  291   @{$self->{stamps}};
  292 }
  293 sub colors {
  294   my $self = shift;
  295   $self -> {colors} ;
  296 }
  297 
  298 sub new_color {
  299   my $self = shift;
  300   my ($color,$r,$g,$b) = @_;
  301   $self->{'colors'}{$color}   =   $self->im->colorAllocate($r, $g, $b);
  302 }
  303 sub im {
  304   my $self = shift;
  305   $self->{im};
  306 }
  307 sub gifName {              # This is yields backwards compatibility.
  308     my $self = shift;
  309   $self->imageName(@_);
  310 }
  311 sub pngName {              # It is better to use the method imageName.
  312     my $self = shift;
  313   $self->imageName(@_);
  314 }
  315 sub size {
  316   my $self = shift;
  317   $self ->{size};
  318 }
  319 
  320 sub _initialize {
  321   my $self      = shift;
  322       $self->{position}    = [0,0];
  323 # $self->{width}      = $self->{'size'}[0];    # original height and width tags match pixel dimensions
  324 # $self->{height}     = $self->{'size'}[1];    # of the image
  325   # allocate some colors
  326       $self->{'colors'}{'background_color'}   =   $self->im->colorAllocate(255,255,255);
  327       $self->{'colors'}{'default_color'}  =   $self->im->colorAllocate(0,0,0);
  328       $self->{'colors'}{'white'}  =   $self->im->colorAllocate(255,255,255);
  329       $self->{'colors'}{'black'}  =   $self->im->colorAllocate(0,0,0);
  330       $self->{'colors'}{'red'}  =   $self->im->colorAllocate(255,0,0);
  331       $self->{'colors'}{'green'}  =   $self->im->colorAllocate(0,255,0);
  332       $self->{'colors'}{'blue'}   =   $self->im->colorAllocate(0,0,255);
  333       $self->{'colors'}{'yellow'} = $self->im->colorAllocate(255,255,0);
  334       $self->{'colors'}{'orange'} = $self->im->colorAllocate(255,100,0);
  335       $self->{'colors'}{'gray'} = $self->im->colorAllocate(180,180,180);
  336       $self->{'colors'}{'nearwhite'}  = $self->im->colorAllocate(254,254,254);
  337    # obtain a new imageNumber;
  338        $self->{imageNumber} = ++$last_image_number;
  339 }
  340 
  341 # reference shapes
  342 # closed circle
  343 # open circle
  344 
  345 # The translation subroutines.
  346 
  347 sub ii {
  348   my $self = shift;
  349   my $x = shift;
  350   return undef unless defined($x);
  351   my $xmax = $self-> xmax ;
  352   my $xmin = $self-> xmin ;
  353   int( ($x - $xmin)*(@{$self->size}[0]) / ($xmax - $xmin) );
  354 }
  355 
  356 sub jj {
  357   my $self = shift;
  358   my $y = shift;
  359   return undef unless defined($y);
  360   my $ymax = $self->ymax;
  361   my $ymin = $self->ymin;
  362   #print "ymax=$ymax y=$y ymin=$ymin size=",${$self->size}[1],"<BR><BR><BR><BR>";
  363   int( ($ymax - $y)*${$self->size}[1]/($ymax-$ymin) );
  364 }
  365 
  366 #  The move and draw subroutines.  Arguments are in real world coordinates.
  367 
  368 sub lineTo {
  369   my $self = shift;
  370   my ($x,$y,$color, $w, $d) = @_;
  371   $w = 1 if ! defined( $w );
  372   $d = 0 if ! defined( $d );  ## draw a dashed line?
  373 
  374   $x=$self->ii($x);
  375   $y=$self->jj($y);
  376   $color = $self->{'colors'}{$color} if $color=~/[A-Za-z]+/ && defined($self->{'colors'}{$color}) ; # colors referenced by name works here.
  377   $color = $self->{'colors'}{'default_color'} unless defined($color);
  378 
  379   $self->im->setThickness( $w );
  380   if ( $d ) {
  381     my @dashing = ( $color )x(4*$w*$w);
  382     my @spacing = ( GD::gdTransparent )x(3*$w*$w);
  383     $self->im->setStyle( @dashing, @spacing );
  384     $self->im->line(@{$self->position},$x,$y,GD::gdStyled);
  385   } else {
  386     $self->im->line(@{$self->position},$x,$y,$color);
  387   }
  388   $self->im->setThickness( 1 );
  389    #warn "color is $color";
  390   @{$self->position} = ($x,$y);
  391 }
  392 
  393 sub moveTo {
  394   my $self = shift;
  395   my $x=shift;
  396   my $y=shift;
  397   $x=$self->ii($x);
  398   $y=$self->jj($y);
  399   #print "moving to $x,$y<BR>";
  400   @{$self->position} = ( $x,$y );
  401 }
  402 
  403 sub arrowTo {
  404   my $self = shift;
  405   my ( $x1, $y1, $color, $w, $d ) = @_;
  406   $w = 1 if ! defined( $w );
  407   $d = 0 if ! defined( $d );
  408   my $width = ( $w == 1 ) ? 2 : $w;
  409 
  410   $x1 = $self->ii($x1);
  411   $y1 = $self->jj($y1);
  412   $color = $self->{'colors'}{$color} if $color=~/[A-Za-z]+/ && defined($self->{'colors'}{$color}) ;
  413   $color = $self->{'colors'}{'default_color'} unless defined($color);
  414 
  415   ## set thickness
  416   $self->im->setThickness($w);
  417 
  418   my ($x0, $y0) = @{$self->position};
  419   my $dx = $x1 - $x0;
  420   my $dy = $y1 - $y0;
  421   my $len = sqrt($dx*$dx + $dy*$dy);
  422   my $ux = $dx/$len;  ## a unit vector in the direction of the arrow
  423   my $uy = $dy/$len;
  424   my $px = -1*$uy;    ## a unit vector perpendicular
  425   my $py = $ux;
  426   my $hbx = $x1 - 5*$width*$ux;  ## the base of the arrowhead
  427   my $hby = $y1 - 5*$width*$uy;
  428   my $head = new GD::Polygon;
  429   $head->addPt($x1,$y1);
  430   $head->addPt($hbx + 2*$width*$px, $hby + 2*$width*$py);
  431   $head->addPt($hbx - 2*$width*$px, $hby - 2*$width*$py);
  432   $self->im->filledPolygon( $head, $color );
  433   if ( $d ) {
  434     my @dashing = ( $color )x(4*$w*$w);
  435     my @spacing = ( GD::gdTransparent )x(3*$w*$w);
  436     $self->im->setStyle( @dashing, @spacing );
  437     $self->im->line( $x0,$y0,$x1,$y1,GD::gdStyled);
  438   } else {
  439     $self->im->line( $x0,$y0,$x1,$y1,$color );
  440   }
  441 
  442   @{$self->position} = ( $x1, $y1 );
  443 
  444   ## reset thickness
  445   $self->im->setThickness(1);
  446 }
  447 
  448 
  449 sub v_axis {
  450   my $self = shift;
  451   @{$self->{vaxis}}=@_; # y_value, color
  452 }
  453 sub h_axis {
  454   my $self = shift;
  455   @{$self->{haxis}}=@_; # x_value, color
  456 }
  457 sub h_ticks {
  458   my $self = shift;
  459   my $nudge =2;
  460   push(@{$self->{hticks}},$nudge,@_); # y-value, color, tick x-values.  see save_image subroutine
  461 
  462 }
  463 sub v_ticks {
  464   my $self = shift;
  465   my $nudge =2;
  466   push(@{$self->{vticks}},$nudge,@_); # x-value, color, tick y-values.  see save_image subroutine
  467 
  468 }
  469 sub h_grid {
  470   my $self = shift;
  471   push(@{$self->{hgrid}}, @_ ); #color,  grid y values
  472 }
  473 sub v_grid {
  474   my $self = shift;
  475   push(@{$self->{vgrid}},@_ );  #color, grid x values
  476 }
  477 
  478 
  479 
  480 sub draw {
  481     my $self = shift;
  482     my $im =$self->{'im'};
  483     my @size = @{$self->size};
  484     my %colors =%{$self->colors};
  485 
  486 # make the background transparent and interlaced
  487 #     $im->transparent($colors{'white'});
  488       $im->interlaced('true');
  489 
  490       # Put a black frame around the picture
  491       $im->rectangle(0,0,$size[0]-1,$size[1]-1,$colors{'black'});
  492 
  493       # draw functions
  494 
  495         foreach my $f ($self->fn) {
  496       #$self->draw_function($f);
  497       $f->draw($self);  # the graph is passed to the function so that the label can call back as needed.
  498     }
  499      # and fill the regions
  500     foreach my $r ($self->fillRegion) {
  501       my ($x,$y,$color_name) = @{$r};
  502       my $color = ${$self->colors}{$color_name};
  503       $self->im->fill($self->ii($x),$self->jj($y),$color);
  504     }
  505 
  506     #draw hticks
  507     my $tk;
  508     my @ticks = @{$self->{hticks}};
  509     if (@ticks) {
  510       my $nudge = shift(@ticks);
  511       my $j     = $self->jj(shift(@ticks));
  512       my $tk_clr= $self->{'colors'}{shift(@ticks)};
  513 
  514       foreach $tk (@ticks) {
  515         $tk = $self->ii($tk);
  516         # print "tk=$tk\n";
  517         $self->im->line($tk,$j+int($nudge),$tk,$j-int($nudge),$tk_clr);
  518       }
  519     }
  520     #draw vticks
  521     @ticks = @{$self->{vticks}};
  522     if (@ticks) {
  523       my $nudge = shift(@ticks);
  524       my $i     = $self->ii(shift(@ticks));
  525       my $tk_clr= $self->{'colors'}{shift(@ticks)};
  526 
  527       foreach $tk (@ticks) {
  528         $tk = $self->jj($tk);
  529         # print "tk=$tk\n";
  530         $self->im->line($i+int($nudge),$tk,$i-int($nudge),$tk,$tk_clr);
  531       }
  532     }
  533     #draw vgrid
  534 
  535     my @grid = @{$self->{vgrid}};
  536     if (@grid)  {
  537       my $x_value;
  538       my $grid_clr= $self->{'colors'}{shift(@grid)};
  539 
  540       foreach $x_value (@grid) {
  541         $x_value = $self->ii($x_value); # scale
  542         #print "grid_line=$grid_line\n";
  543         $self->im->dashedLine($x_value,0,$x_value,$self->{'size'}[1],$grid_clr);
  544       }
  545     }
  546     #draw hgrid
  547     @grid = @{$self->{hgrid}};
  548     if (@grid) {
  549       my $grid_clr= $self->{'colors'}{shift(@grid)};
  550           my $y_value;
  551       foreach $y_value (@grid) {
  552         $y_value = $self->jj($y_value);
  553         #print "y_value=$y_value\n";
  554         #print "width= $self->{width}\n";
  555         $self->im->dashedLine(0,$y_value,$self->{'size'}[0],$y_value,$grid_clr);
  556       }
  557     }
  558     # draw axes
  559     if (defined ${$self->{vaxis}}[0]) {
  560       my ($x, $color_name) = @{$self->{vaxis}};
  561       my $color = ${$self->colors}{$color_name};
  562       $self->moveTo($x,$self->ymin);
  563       $self->lineTo($x,$self->ymax,$color);
  564       #print "draw vaxis", @{$self->{vaxis}},"\n";
  565       #$self->im->line(0,0,300,300,$color);
  566     }
  567     if (defined $self->{haxis}[0]) {
  568       my ($y, $color_name) = @{$self->{haxis}};
  569       my $color = ${$self->colors}{$color_name};
  570       $self->moveTo($self->xmin,$y);
  571       $self->lineTo($self->xmax,$y,$color);
  572         #print "draw haxis", @{$self->{haxis}},"\n";
  573     }
  574     # draw functions again
  575 
  576     foreach my $f ($self->fn) {
  577       #$self->draw_function($f);
  578       $f->draw($self);  # the graph is passed to the function so that the label can call back as needed.
  579     }
  580 
  581 
  582     #draw labels
  583     my $lb;
  584     foreach $lb ($self->lb) {
  585       $lb->draw($self);  # the graph is passed to the label so that the label can call back as needed.
  586     }
  587     #draw stamps
  588     my $stamp;
  589     foreach $stamp ($self->stamps) {
  590       $stamp->draw($self); # the graph is passed to the label so that the label can call back as needed.
  591     }
  592         my $out;
  593         if ($WWPlot::use_png) {
  594           $out = $im->png;
  595         } else {
  596           $out = $im->gif;
  597         }
  598         $out;
  599 
  600 }
  601 
  602 
  603 
  604 # sub AUTOLOAD {
  605 #   my $self = shift;
  606 #   my $type = ref($self) || die "$self is not an object";
  607 #   my $name = $WWPlot::AUTOLOAD;
  608 #   $name =~ s/.*://;  # strip fully-qualified portion
  609 #   unless (exists $self->{'_permitted'}->{$name} ) {
  610 #     die "Can't find '$name' field in object of class $type";
  611 #   }
  612 #   if (@_) {
  613 #     return $self->{$name} = shift;
  614 #   } else {
  615 #     return $self->{$name};
  616 #   }
  617 #
  618 # }
  619 ##########################
  620 # Access methods
  621 ##########################
  622 sub ymin {
  623   my $self = shift;
  624   my $type = ref($self) || die "$self is not an object";
  625   unless (exists $self->{ymin} ) {
  626     die "Can't find ymin field in object of class $type";
  627   }
  628 
  629   if (@_) {
  630     return $self->{ymin} = shift;
  631   } else {
  632     return $self->{ymin}
  633   }
  634 }
  635 
  636 sub xmin {
  637   my $self = shift;
  638   my $type = ref($self) || die "$self is not an object";
  639   unless (exists $self->{xmin} ) {
  640     die "Can't find xmin field in object of class $type";
  641   }
  642 
  643   if (@_) {
  644     return $self->{xmin} = shift;
  645   } else {
  646     return $self->{xmin}
  647   }
  648 }
  649 
  650 sub xmax {
  651   my $self = shift;
  652   my $type = ref($self) || die "$self is not an object";
  653   unless (exists $self->{xmax} ) {
  654     die "Can't find xmax field in object of class $type";
  655   }
  656 
  657   if (@_) {
  658     return $self->{xmax} = shift;
  659   } else {
  660     return $self->{xmax}
  661   }
  662 }
  663 
  664 sub ymin {
  665   my $self = shift;
  666   my $type = ref($self) || die "$self is not an object";
  667   unless (exists $self->{ymin} ) {
  668     die "Can't find ymin field in object of class $type";
  669   }
  670 
  671   if (@_) {
  672     return $self->{ymin} = shift;
  673   } else {
  674     return $self->{ymin}
  675   }
  676 }
  677 
  678 sub ymax {
  679   my $self = shift;
  680   my $type = ref($self) || die "$self is not an object";
  681   unless (exists $self->{ymax} ) {
  682     die "Can't find ymax field in object of class $type";
  683   }
  684 
  685   if (@_) {
  686     return $self->{ymax} = shift;
  687   } else {
  688     return $self->{ymax}
  689   }
  690 }
  691 
  692 sub imageName {
  693   my $self = shift;
  694   my $type = ref($self) || die "$self is not an object";
  695   unless (exists $self->{imageName} ) {
  696     die "Can't find imageName field in object of class $type";
  697   }
  698 
  699   if (@_) {
  700     return $self->{imageName} = shift;
  701   } else {
  702     return $self->{imageName}
  703   }
  704 }
  705 
  706 sub position {
  707   my $self = shift;
  708   my $type = ref($self) || die "$self is not an object";
  709   unless (exists $self->{position} ) {
  710     die "Can't find position field in object of class $type";
  711   }
  712 
  713   if (@_) {
  714     return $self->{position} = shift;
  715   } else {
  716     return $self->{position}
  717   }
  718 }
  719 sub DESTROY {
  720   # doing nothing about destruction, hope that isn't dangerous
  721 }
  722 
  723 sub save_image {
  724     my $self = shift;
  725   warn "The method save_image is no longer supported. Use insertGraph(\$graph)";
  726   "The method save_image is no longer supported. Use insertGraph(\$graph)";
  727 }
  728 
  729 
  730 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9