*
;

 /****************************************************************/
 /*          S A S   S A M P L E   L I B R A R Y                 */
 /*                                                              */
 /*    NAME: ANNOMAC                                             */
 /*   TITLE: ANNOTATE SUPPORT MACROS                             */
 /* PRODUCT: GRAPH                                               */
 /*  SYSTEM: OS                                                  */
 /*    KEYS: MACRO GDEVICE                                       */
 /*   PROCS:                                                     */
 /*    DATA:                                                     */
 /*                                                              */
 /* SUPPORT: GRAPHICS STAFF              UPDATE: 16NOV84         */
 /*     REF:                                                     */
 /*    MISC: ON CMS--use annocms instead of annomac beacuse of   */
 /*          the length of the macro names.                      */
 /****************************************************************/

 /* option dquote; */


%MACRO  sequence( seq );
%*--------------------------------------------------------------------;
%* Definition of ANNOTATE generation sequence.                        ;
%*--------------------------------------------------------------------;
   IF UPCASE("&seq")='AFTER' OR UPCASE("&seq")=:'A'  THEN WHEN = "A";
                                                     ELSE WHEN = "B";
%MEND   sequence;



%MACRO  system( xs, ys, hs );
%*--------------------------------------------------------------------;
%* Definition of ANNOTATE reference systems.                          ;
%*--------------------------------------------------------------------;
   XSYS = "&xs";  YSYS = "&ys";  HSYS = "&hs";
%MEND   system;



%MACRO  comment( txt );
%*--------------------------------------------------------------------;
%* Places descriptive text string into ANNOTATE observation stream.   ;
%*                                                                    ;
%* NOTE: This function will cause a LENGTH to be assigned to the TEXT ;
%*       variable, due to the nature of the DATA step. Insert a       ;
%*                 LENGTH  TEXT $  nnn. ;                             ;
%*       statement into the DATA step if this is undesirable.         ;
%*                                                                    ;
%*--------------------------------------------------------------------;
   TEXT=&txt;
   FUNCTION = "COMMENT "; output;
   TEXT=" ";
%MEND   comment;



%MACRO  dclanno;
%*--------------------------------------------------------------------;
%* Set up required variable lengths.                                  ;
%* Assure X and Y variables are in the dataset.                       ;
%* Assure all variables in LENGTH statements are referenced.          ;
%*--------------------------------------------------------------------;
   LENGTH FUNCTION COLOR STYLE    $ 8;
   LENGTH XSYS YSYS HSYS          $ 1;
   LENGTH WHEN POSITION           $ 1;
   RETAIN XSYS YSYS HSYS;

   X = . ;
   Y = . ;
   STYLE    = " ";
   POSITION = "5";
   COLOR    = " ";
   FUNCTION = " ";

   %system( 4, 4, 4 );
   %sequence( BEFORE );

%MEND   dclanno;



%MACRO  move( x1, y1 );
%*--------------------------------------------------------------------;
%* MOVE to the requested ( X1,Y1 ) coordinate.                        ;
%*--------------------------------------------------------------------;
   X = &x1;
   Y = &y1;
   FUNCTION = "MOVE    "; output;
%MEND   move;



%MACRO  draw( x1, y1, colin, lintyp, width );
%*--------------------------------------------------------------------;
%* DRAW a line to the requested ( X1,Y1 ) coordinate.                 ;
%*--------------------------------------------------------------------;
  X = &x1;
  Y = &y1;
  LINE     = &lintyp;
  SIZE     = &width;
      IF "&colin" =: '*'  THEN ;  ELSE color = "&colin" ;
  FUNCTION = "DRAW    "; output;
%MEND   draw;



%MACRO  label( x1, y1, txt, coltxt, ang, rot, hgt, font, pos );
%*--------------------------------------------------------------------;
%* Place the TXT string at ( X1,Y1 ).                                 ;
%*                                                                    ;
%* NOTE: Literal text MUST be enclosed in quotes, otherwise the TEXT  ;
%*       variable will be assigned the value of the variable named in ;
%*       the symbolic macro parameter. DATA step errors will occur if ;
%*       one of these two conditions is not met.                      ;
%*--------------------------------------------------------------------;
   X = &x1;
   Y = &y1;
   ANGLE    = ∠
   ROTATE   = &rot;
   SIZE     = &hgt;
   STYLE    = "&font";
   TEXT     = &txt;
      IF "&pos" =: '*' THEN ; ELSE POSITION = "&pos" ;
         IF "&coltxt" =: '*' THEN ; ELSE color = "&coltxt";
   FUNCTION = "LABEL   "; output;
%MEND   label;



%MACRO  rect( x1, y1, x2, y2, colin, lintyp, width );
%*--------------------------------------------------------------------;
%* Draw a rectangle. Non-fillable definition.                         ;
%*                                                                    ;
%* NOTE:  ( X1,Y1 ) and ( X2,Y2 ) are opposing corners.               ;
%*--------------------------------------------------------------------;
  %move ( &x1, &y1 );
  %draw ( &x2, &y1, &colin, &lintyp, &width );
  %draw ( &x2, &y2, &colin, &lintyp, &width );
  %draw ( &x1, &y2, &colin, &lintyp, &width );
  %draw ( &x1, &y1, &colin, &lintyp, &width );
%MEND   rect;



%MACRO  bar( x1, y1, x2, y2, color, bartyp, pattern );
%*--------------------------------------------------------------------;
%* Draw a rectangle. Fillable definition.                             ;
%*                                                                    ;
%* NOTE:  ( X1,Y1 ) and ( X2,Y2 ) are opposing corners.               ;
%*--------------------------------------------------------------------;
  %move ( &x1, &y1 );
   X = &x2;
   Y = &y2;
   LINE     = &bartyp;
   STYLE    = "&pattern";
      IF "&color" =: '*'  THEN ; ELSE color = "&color" ;
   FUNCTION = "BAR     "; output;
%MEND   bar;



%MACRO  circle( x1, y1, rad, colin );
%*--------------------------------------------------------------------;
%* Draw a circle with center at ( X1,Y1 ) of radius RAD.              ;
%*--------------------------------------------------------------------;
   X = &x1;
   Y = &y1;
   LINE     = 0;
   ANGLE    = 0.00;
   ROTATE   = 360.00;
   SIZE     = &rad;
   STYLE    = "EMPTY";
      IF "&colin" =: '*' THEN ; ELSE  color = "&colin";
   FUNCTION = "PIE"; output;
%MEND   circle;



%MACRO  slice( x1, y1, ang, rot, rad, color, pattern, ltyp );
%*--------------------------------------------------------------------;
%* Define a pie slice.                                                ;
%* Center at ( X1,Y1 ), radius of RAD, starting angle of ANG, with a  ;
%* traverse angle of ROT. LTYP defines type of boundary to draw.      ;
%*                                                                    ;
%* NOTE:  LTYP must be defined by literal strings as listed below     ;
%*                                                                    ;
%*        Setting LTYP to WHOLE is a special case in the macro,       ;
%*        and causes the overriding of specified ANG and ROT values.  ;
%*                                                                    ;
%*        See documentation for special ANG/ROT value handling.       ;
%*                                                                    ;
%*--------------------------------------------------------------------;
%LET  lntp= %UPCASE("<yp");
      %IF %INDEX(&lntp,WHOLE) > 0 %THEN %STR(   LINE    = 0;) ;
%ELSE %IF %INDEX(&lntp,LEAD)  > 0 %THEN %STR(   LINE    = 1;) ;
%ELSE %IF %INDEX(&lntp,TRAIL) > 0 %THEN %STR(   LINE    = 2;) ;
%ELSE %IF %INDEX(&lntp,BOTH)  > 0 %THEN %STR(   LINE    = 3;) ;
%ELSE %IF %INDEX(&lntp,NONE)  > 0 %THEN %STR(   LINE    = 0;) ;
%ELSE                                   %STR(   LINE    = 3;) ;

   X = &x1;
   Y = &y1;

   %IF %INDEX(&lntp,WHOLE) > 0
   %THEN %DO;
      %STR(   ANGLE    =   0; );
      %STR(   ROTATE   = 360; );
      %END;
   %ELSE %DO;
      %STR(   ANGLE    = ∠ );
      %STR(   ROTATE   = &rot; );
      %END;

   SIZE     = &rad;
   STYLE    = "&pattern";
      IF "&color" =: '*' THEN ; ELSE color = "&color";
   FUNCTION = "PIE     "; output;
%MEND   slice;



%MACRO  piexy( ang, mul );
%*--------------------------------------------------------------------;
%* Return coordinates along the radius of a previously defined pie.   ;
%*--------------------------------------------------------------------;
   X = .;
   Y = .;
   SIZE     = &mul;
   ANGLE    = ∠
   FUNCTION = "PIEXY   ";  output;
%MEND   piexy;



%MACRO  poly ( x1, y1, color, pattern, lintyp );
%*--------------------------------------------------------------------;
%* Begin definition of a polygon.                                     ;
%*--------------------------------------------------------------------;
   X = &x1;
   Y = &y1;
   LINE     = &lintyp;
   STYLE    = "&pattern";
      IF "&color" =: '*' THEN ; ELSE color = "&color" ;
   FUNCTION = "POLY    "; output;
%MEND   poly;



%MACRO  polycont ( x1, y1, colin );
%*--------------------------------------------------------------------;
%* Continue definition of a polygon.                                  ;
%*--------------------------------------------------------------------;
   X = &x1;
   Y = &y1;
      IF "&colin" =: '*' THEN ;  ELSE color = "&colin";
   FUNCTION = "POLYCONT"; output;
%MEND   polycont;



%MACRO  frame ( colin, lintyp, width, pattern );
%*--------------------------------------------------------------------;
%* Continue definition of a polygon.                                  ;
%*--------------------------------------------------------------------;
   X = . ;
   Y = . ;
      IF "&colin" =: '*' THEN ;  ELSE color = "&colin";
   STYLE = "&pattern";
   LINE= &lintyp;
   SIZE= &width;
   FUNCTION = "FRAME   "; output;
%MEND   frame;



%MACRO scale( ptx,pty, xmin,ymin, xmax,ymax, vxmin,vymin, vxmax,vymax );
%*--------------------------------------------------------------------;
%*                                                                    ;
%* scales input coordinates ( ptx,pty ) into a requested range        ;
%*                                                                    ;
%*      vxmin,vymin   are the output range minimums ( target )        ;
%*      vxmax,vymax   are the output range maximums ( target )        ;
%*                                                                    ;
%*      xmin,ymin     are the input range minimums  ( source )        ;
%*      xmax,ymax     are the input range maximums  ( source )        ;
%*                                                                    ;
%* NOTE:  ABS(minimum) MAY NOT EQUAL ABS(maximum).                    ;
%*                                                                    ;
%*        NO OBSERVATION IS OUTPUT BY THIS MACRO.                     ;
%*                                                                    ;
%*--------------------------------------------------------------------;
%LET f1 = ( (&vxmax-&vxmin) / (&xmax-&xmin) );
%LET f2 = ( (&vymax-&vymin) / (&ymax-&ymin) );
     X  = &f1 * (&ptx-&xmin);
     Y  = &f2 * (&pty-&ymin);
%MEND  scale;



%MACRO  push;
%*--------------------------------------------------------------------;
%* PUSH values (XLAST,YLAST),(XLSTT,YLSTT) onto a LIFO system stack.  ;
%*--------------------------------------------------------------------;
   X = . ;
   Y = . ;
   FUNCTION="PUSH    ";  output;
%MEND   push;



%MACRO  pop;
%*--------------------------------------------------------------------;
%* POP values (XLAST,YLAST),(XLSTT,YLSTT) from the LIFO system stack. ;
%*--------------------------------------------------------------------;
   X = . ;
   Y = . ;
   FUNCTION="POP     ";  output;
%MEND   pop;



%MACRO  swap;
%*--------------------------------------------------------------------;
%* SWAP values (XLAST,YLAST) and (XLSTT,YLSTT).                       ;
%* Does NOT affect values on LIFO system stack.                       ;
%*--------------------------------------------------------------------;
   X = . ;
   Y = . ;
   FUNCTION="SWAP    ";  output;
%MEND   swap;



%MACRO  txt2cntl;
%*--------------------------------------------------------------------;
%* COPY values (XLSTT,YLSTT) into (XLAST,YLAST).                      ;
%* Does NOT affect values on LIFO system stack.                       ;
%*--------------------------------------------------------------------;
   X = . ;
   Y = . ;
   FUNCTION = "TXT2CNTL";  output;
%MEND   txt2cntl;



%MACRO  cntl2txt;
%*--------------------------------------------------------------------;
%* COPY values (XLAST,YLAST) into (XLSTT,YLSTT).                      ;
%* Does NOT affect values on LIFO system stack.                       ;
%*--------------------------------------------------------------------;
   X = . ;
   Y = . ;
   FUNCTION = "CNTL2TXT";  output;
%MEND   cntl2txt;



%MACRO  draw2txt ( colin, lintyp, width );
%*--------------------------------------------------------------------;
%* DRAW a line from (XLAST,YLAST) to (XLSTT,YLSTT).                   ;
%* Does NOT affect values on LIFO system stack.                       ;
%*--------------------------------------------------------------------;
   X = . ;
   Y = . ;
   SIZE     = &width;
   LINE     = &lintyp;
      IF "&colin" =: '*' THEN ;  ELSE color = "&colin" ;
   FUNCTION = "DRAW2TXT";  output;
%MEND   draw2txt;



%MACRO  line( x1, y1, x2, y2, colin, lintyp, width );
%*--------------------------------------------------------------------;
%* DRAW a line from (X1,Y1) to (X2,Y2).                               ;
%* Simplified version supplying the invisible move instruction.       ;
%*--------------------------------------------------------------------;
  %move( &x1, &y1 );
  %draw( &x2, &y2, &colin, &lintyp, &width );
%MEND   line;

*
;