home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Editores / Perl5 / perl / lib / site / Tk / Axis.pm < prev    next >
Encoding:
Perl POD Document  |  1997-08-10  |  6.4 KB  |  230 lines

  1. package Axis;
  2.  
  3. =head1 NAME 
  4.  
  5. Axis - Canvas with Axes
  6.  
  7. =head1 SYNOPSIS
  8.  
  9.   $mw = MainWindow->new;                                           
  10.   $t = $mw->Axis(-xmax => 10, -ymax => 10);                        
  11.   $t->create('line',$t->plx(2),$t->ply(3.1),$t->plx(4),$t->ply(4));
  12.  
  13. =head1 DESCRIPTION
  14.  
  15. This is an improved version of the axis widget. Changes with respect to the
  16. previous version are :
  17.  
  18. =over 4
  19.  
  20. =item * 
  21.  
  22. the 'pack' has been moved out the widget. One has to do his own packing
  23.  
  24. =item * 
  25.  
  26. it is now possible to work in the coordinates of the axis. The following
  27. piece of code draws a line between the points (2 , 3.1)  (4 , 4).
  28.  
  29. =back 
  30.  
  31. =head1 AUTHOR
  32.  
  33.  Kris Boulez        (Kris.Boulez@rug.ac.be)
  34.  Biomolecular NMR unit    <http://bionmr1.rug.ac.be/~kris>
  35.  University of Ghent, Belgium
  36.  
  37. =cut 
  38.  
  39. require 5.002;
  40. require Tk::Canvas;
  41. use Carp;
  42.  
  43. @ISA = qw(Tk::Derived Tk::Canvas);
  44.  
  45. Construct Tk::Widget 'Axis';
  46.  
  47.  
  48. # Added since v 0.1
  49. # -----------------
  50. # - plx en ply allow you to work in axis coordinates
  51. #       (eg. $t->create('line', $t->plx(.3), $t->ply(.4), $t->plx(3.2), 
  52. #                          $t->ply(5.3)); ) 
  53. # - pack is moved out.
  54. #
  55. # This is an Axis widget. It draws an XY axis on the screen and draws 
  56. # tickmarks. This is the first public version (v 0.2), all comments, 
  57. # crticism, ... are welcome (kris@bionmr1.rug.ac.be).
  58. #
  59. # I would like to thank the following people :
  60. # - Ton Rullmann (rull@nmr.chem.ruu.nl) who started my quest for a way to
  61. # draw 2D plot from within Perl
  62. # - Stephen O. Lidie (lusol@Turkey.CC.Lehigh.edu) who provided me with a 
  63. # 2D plot script. He also asked the question "why don't you write a new
  64. # widget for it ?"
  65. # - Nick Ing-Simmons (nik@tiuk.ti.com) without who there would be no ptk
  66. # and whose advice was invaluable while trying to create this widget
  67. #
  68. # It is used as follows
  69. #
  70. #   require Axis;
  71. #
  72. #   $AxisRef = $mw->Axis(
  73. #                -width => $width,
  74. #                -height => $height,
  75. #                -xmin   => $xmin,
  76. #                -xmax   => $xmax,
  77. #                -ymin   => $ymin,
  78. #                -ymax   => $ymax,
  79. #                -margin => $margin,
  80. #                -tick   => $tick,
  81. #                -tst    => $tst,
  82. #               );
  83. #
  84. #    mw      - a window reference (usually from a MainWindow->new call).
  85. #    height  - height of the window (Nick, what is the default for this ?)
  86. #    width   - width  ......
  87. #    xmin    - lowest x value we will display
  88. #    xmax    - highest .....
  89. #    ymin    - lowest y value .....
  90. #    ymax    - highest .....
  91. #    margin  - the number of pixels used as a margin around the plot
  92. #    tick    - the length (in pixels) of the tickmarks
  93. #    tst     - the step size for the tick marks
  94. #    tst[x|y]- step size for tick marks on the x (or y) axis
  95. #                (if not specified tst is used)
  96. #   $AxisRef->pack;
  97. #     (A Show method is supplied for compatibility with other widgets) 
  98.  
  99.  
  100. sub Populate    #using Populate from Tk::Derived
  101. {
  102.   my ($w,$args) = @_;
  103.   $w->SUPER::Populate($args);
  104.   $w->ConfigSpecs(
  105.           '-xmin'   => ['PASSIVE',undef,undef,0],
  106.           '-xmax'   => ['PASSIVE',undef,undef,undef],
  107.           '-ymin'   => ['PASSIVE',undef,undef,0],
  108.           '-ymax'   => ['PASSIVE',undef,undef,undef],
  109.           '-margin' => ['PASSIVE',undef,undef,25],
  110.           '-tick'   => ['PASSIVE',undef,undef,10],
  111.           '-tst'    => ['PASSIVE',undef,undef,5],
  112.           '-tstx'   => ['PASSIVE',undef,undef,undef],
  113.           '-tsty'   => ['PASSIVE',undef,undef,undef],
  114.          ); # these options are new for the widget, the last value is 
  115.                     # the default. 
  116. } #end of Populate
  117.  
  118.  
  119. sub ConfigChanged {
  120.   my ($w,$args)= @_;;
  121.  
  122.   my $xmin = $w->cget(-xmin);   # how expensive is a ->cget ?
  123.   my $xmax = $w->cget(-xmax);
  124.   my $cx = $w->cget(-width);
  125.   my $mar = $w->cget(-margin);
  126.   my $ymin = $w->cget(-ymin);
  127.   my $ymax = $w->cget(-ymax);
  128.   my $cy = $w->cget(-height);
  129.   my $tick = $w->cget(-tick);
  130.   my $tst = $w->cget(-tst);
  131.   my $tstx = $w->cget(-tstx);
  132.   my $tsty = $w->cget(-tsty);
  133.  
  134.   if (!defined ($xmax) || !defined ($ymax)) { # at least xmax and ymax needed
  135.     croak "Axis: `Show' method requires xmax and ymax";
  136.   }
  137.   if (!defined ($tstx)) {$tstx = $tst;}
  138.   if (!defined ($tsty)) {$tsty = $tst;}
  139.  
  140.   my ($zx,$zy,$t); # zx (zy) is the value (in window coordinates) where 
  141.                    # x (y) is 0 on the X (Y) axis
  142.   if (abs($xmin+$xmax) > abs($xmin-$xmax)) { # both values pos/neg
  143.     $zx=$mar;
  144.   }
  145.   else {
  146.     $zx = $w->plx(0);
  147.   }
  148.  
  149.   if (abs($ymin+$ymax) > abs($ymin-$ymax)) {
  150.     $zy=$cy-$mar;
  151.   }
  152.   else {   # $cy - $mar is lowest point where we will draw
  153.     $zy = $w->ply(0);
  154.   }  
  155.   
  156.  # X-axis 
  157.  # ------
  158.   $w->create('line',
  159.          $mar, $zy, $cx-$mar, $zy);
  160.   my (@t) = (); # @t contains the points where to draw tick marks
  161.   if ($zx ==  0) {
  162.     for ($t=$xmin; $t<=$xmax; $t+=$tstx) { push (@t,$t); }
  163.   }
  164.   else {
  165.     for ($t=0; $t<=$xmax; $t+=$tstx) { push (@t,$t); }
  166.     for ($t=-$tstx; $t>=$xmin; $t-=$tstx) { push(@t,$t);}
  167.   }
  168.  
  169.   for $t (@t) {
  170.     my $x = ($cx-2*$mar)*($t-$xmin)/abs($xmax-$xmin) + $mar;
  171.     $w->create('line',
  172.            $x, $zy, $x, $zy+$tick);
  173.     $w->create('text',
  174.            $x+5,$zy+20, text => $t, -anchor => 'sw');
  175.   }
  176.  
  177.  # Y-axis
  178.  # ------
  179.   $w->create('line',
  180.          $zx, $mar, $zx, $cy-$mar);
  181.   @t = ();
  182.   if ($zy ==  $cy-$mar) {     # only pos/neg values
  183.     for ($t=$ymin; $t<=$ymax; $t+=$tsty) { push (@t,$t); }
  184.   }
  185.   else {
  186.     for ($t=$tsty; $t<=$ymax; $t+=$tsty) { push (@t,$t); }
  187.     for ($t=-$tsty; $t>=$ymin; $t-=$tsty) { push(@t,$t);}
  188.   }
  189.  
  190.   for $t (@t) {
  191.     my $y = ($cy - $mar) - ($cy-2*$mar)*($t-$ymin)/abs($ymax-$ymin);
  192.     $w->create('line',
  193.            $zx, $y, $zx-$tick, $y);
  194.     $w->create('text',
  195.            $zx -15,$y+20, text => $t, -anchor => 'sw');
  196.   }
  197. } # end ConfigChanged
  198.  
  199. sub Show {   # all the drawing is allready done in ConfigChanged. Show is only
  200.              # supplied for compatibility with other widgets.
  201. } #end Show
  202.  
  203. sub plx {
  204.   my ($w,$args) = @_;
  205.   my $xmin = $w->cget(-xmin);   # how expensive is a ->cget ?
  206.   my $xmax = $w->cget(-xmax);
  207.   if (($args < $xmin)||($args>$xmax)) 
  208.     {die "PLX: Out of limits\nXmin: $xmin\t\tValue: $args\nXmax: $xmax\n\n";}
  209.   my $wi = $w->cget(-width);
  210.   my $ma = $w->cget(-margin);
  211.   return ((($wi-2*$ma)/abs($xmax-$xmin))*abs($args-$xmin) + $ma);
  212. } #end plx
  213.  
  214. sub ply {
  215.   my ($w,$args) = @_;
  216.   my $ymin = $w->cget(-ymin);   # how expensive is a ->cget ?
  217.   my $ymax = $w->cget(-ymax);
  218.   if (($args < $ymin)||($args>$ymax)) 
  219.     {die "PLY: Out of limits\nYmin: $ymin\t\tValue: $args\nYmax: $ymax\n\n";}
  220.   my $he = $w->cget(-height);
  221.   my $ma = $w->cget(-margin);
  222.   return ($he - $ma -(($he-2*$ma)/abs($ymax-$ymin))*abs($args-$ymin));
  223.  
  224. } #end plx
  225.  
  226. 1;
  227.  
  228. __END__
  229.  
  230.