/*

/ Program      : rannomac.sas
/ Version      : 2.0
/ Author       : Roland Rashleigh-Berry
/ Date         : 02-Jan-2009
/ Purpose      : Compile Roland's annotate macros
/ SubMacros    : none
/ Notes        : This is Roland's version of the SI supplied macro %annomac that
/                makes available the annotate macros for use in a data step to
/                help create an annotate dataset.
/
/                Note that except for %drawline the macros defined below draw
/                shapes that lie parallel to the x-axis only hence all the
/                macros use a single "y" parameter but use two "x" parameters
/                "x1" and "x2" to indicate the start and end x coordinates
/                (except for the %text and %box macros which only have one x
/                coordinate).
/
/                This macro must be used like %annomac in that it should be
/                called outside a data step to compile the macros whose macros
/                definitions are contained within before they can be used in a
/                data step.
/
/                The macros defined below do not call any of the SI supplied
/                annotate macros but you are expected to mix use with the SI
/                supplied annotate macros as needed (see usage notes below).
/
/                All macro parameters are named parameters, unlike the SI
/                supplied annotate macros which use positional parameters.
/
/                The values supplied to the parameters can be VARIABLE NAMES in
/                all cases in which case you have to make sure they are of the
/                correct type (numeric or character) and if character then of
/                sufficient length. The variable names you supply and use to
/                hold the values should be named differently to the annotate
/                dataset variable names (see the %dclannovars macro below for
/                a list of these variable names).
/
/                In your annotate data step you must define a length for the
/                "HTML" character variable long enough to contain your longest
/                assignment (if you are using this variable for html
/                "hotspots"). Recommended is the maximum allowed length of
/                1024. This is automatically set in the %dclannovars macro if
/                you call that macro. This length should also be applied to
/                your own variables you set up whose values you will pass to
/                html= as a variable name. 
/
/                Note that the variable named HTML is strictly an output
/                variable to be used in the output annotate dataset. You must
/                not treat this as a working variable as the macros defined
/                below will often reset the value of HTML to a space to ensure
/                that the scope of the instructions contained in the HTML
/                variable are limited to only the intended function. You will
/                typically require a working html variable (maybe named
/                HTMLWORK) and it is likely you have another html variable
/                in a dataset you are using for input. You must not name this
/                variable HTML in your input dataset nor use the HTML variable
/                as a working variable. You should make sure you set the
/                length of these other html variables to something suitable.
/                The maximum allowed length of 1024 is recommended. Note that
/                the %dclannovars macro contains a "keep" statement that will
/                only keep true annotate variables. If you want to keep more
/                variables then you will have to add another "keep" statement
/                to do this.
/
/                Most of these macros draw polygons. The shape is drawn twice
/                to allow you to define a both a fill color and additionally a
/                fill pattern drawn in the same color as the outline. This is
/                to allow you to use both the fill color and the fill pattern
/                to mean different things. For example, fill colors of "yellow"
/                "green" and "red" might indicate the severity of an AE and
/                the fill pattern might indicate relationship to study drug.
/                For the %box macro you should be aware that in most cases the
/                box will be too small for the fill pattern to be visible.
/
/                The thickness (or fatness) of the shapes drawn is controlled
/                by the "height" parameter. A "width" parameter additionally
/                applies to the box shape drawn by the %box macro.
/
/                If you do not want a fill pattern then specify
/                fillpattern="mempty". Note that the fill patterns are "map"
/                fill patterns (they begin with an "m"). See the SAS
/                documentation for how to correctly specify these patterns.
/
/                Macros definitions contained in this macro are as follows:
/                %rannomac: Dummy macro that does nothing
/                %dclannovars:  Declare the annotate variables
/                %xyzhsys:  Macro to define coordinate system to use
/                %text:     Like %label except all parameters are named
/                %box:      Draw a small box that is centered
/                %rod:      Like %rect except you can fill it
/                %rarrow:   Right arrow (arrow head points right)
/                %larrow:   Left arrow (arrow head points left)
/                %dblarrow: Double arrow (arrow heads on both ends)
/                %drawline: Draw a line
/                %bigbox:   Draw a big (empty) box
/                %fillbar:  Draw a fill bar (solid color - no outline)
/
/                You should use %fillbar before you draw a shape in the area
/                it fills otherwise it will overwrite your shape.
/
/                Note that for the %text macro, color=' ' and font=' '. This
/                is so it can pick up these values from the goptions statement
/                and hence lead to a consistency of fonts and text colors.
/                For font it will use what you define to ftext= and for color
/                it will use ctext= and if this is not set then it will use
/                the first color defined to the color list color=(). Note that
/                for annotate datasets, you are limited to an eight character
/                color name, even if a goptions statement can work with a
/                longer color name so if color=' ' then it will only accept
/                what is defined in a goptions statement if the color name
/                used is eight characters or less. You can always use the RGB
/                version of a long color name. For example, if you enter the
/                command "regedit" in an interactive sas session you will be
/                able to look at the list of colors in
/                SAS_REGISTRY\COLORNAMES\HTML. AntiqueWhite is near the top
/                of the list and its hex codes are displayed as FA,EB,D7
/                which means you could define it in the goptions statement as
/                ctext=CXFAEBD7 (no quotes required) and the annotate dataset
/                could accept this as the default color for text. Also the
/                default for height is height=. so that it will use what is
/                defined to the goptions statement hsize= or if not set then
/                it will use the SAS default of "1 cell".
/
/                If you use the html variable with the %text macro then the
/                hotspot is only correctly aligned for left-aligned text. If
/                you use position='<' then the hotspot is to the immediate
/                left of the displayed text. If you use "+" the hotspot is to
/                the left of the exact center of the displayed text. This is
/                a SAS bug that exists in sas v8.2 and sas v9.1.3 but should
/                be fixed in sas v9.2 . In the meantime, you will just have
/                to remember where to put your mouse cursor to pick up the
/                hotspot. The sas bug is reported at
/                http://support.sas.com/kb/12/377.html
/
/                The intention is for you to use both the SI supplied annotate
/                macros plus Roland's annotate macros together as needed.
/                However, it should be possible to use only Roland's annotate
/                macros in simple cases where you are only displaying shapes
/                defined in macros below that lie parallel to the x axis. These
/                macros were specifically written for use with a graphical
/                patient profiler and to provide a complete set for this. If
/                the need for more macros for this purpose are identified then
/                the extra macros will be added. If you are using this set of
/                macros for graphical patient profiling and you identify more
/                macros that are needed then tell the author.
/
/                In the usage notes below you will see a typical situation
/                where you use goptions to create a "long" html page that you
/                would typically use for graphical patient profiling. The
/                number of xpixels and ypixels will give you that area for
/                graphics. This is only accepted by a few devices such as
/                dev=gif and dev=html. hpos and vpos effectively give you the
/                number of columns (hpos=horizontal positions) and the number
/                of rows (vpos=vertical positions). Since cell size is the
/                default coordinate system then the top y position will be 300
/                if vpos=300. In the example below the first line used is
/                y=298 which leaves a two-row gap at the top. If the figures
/                and text look too big then you can reduce the height of them
/                using the height= parameters. If you have done that but the
/                rows seem too far apart then increase the hpos and vpos
/                values to divide up the graphics area up into smaller cells.
/
/                Note that v8.2 of SAS does not handle hotspots correctly.
/                If you run the code below using SAS v8.2 then the 
/                "Third Box" hotspot will also be active for the second box.
/                This problem does not occur for SAS v9.1.3 so if you are
/                writing annotate datasets that use hotspots then you MUST
/                use SAS v9.1.3 or later.
/               
/ Usage        : filename webout "C:\spectre\";
/
/                goptions reset=all xpixels=1000 ypixels=6000 hpos=50 vpos=300
/                dev=gif gsfmode=replace transparency border
/                ftext='Arial' htext=1 cell ctext=CX483D8C; * DarkSlateBlue ;
/
/                ods listing close;
/                ods html path=webout body="annotest.html";
/
/                %rannomac
/
/                data test;
/                  %dclannovars
/                  %rarrow(y=298,x1=20,x2=48)
/                  %text(y=298,x=19,position='<',text="right-aligned text") 
/                  %rarrow(y=297,x1=20,x2=48,fillcolor='green',
/                          linecolor='black',fillpattern='mempty')
/                  %text(y=297,x=19,position='<',text="next line of text")
/                  %text(y=296,x=19,position='<',
/                        text="This has a hotspot but misaligned on the left",
/                        color='maroon',
/               html="alt='This hotspot is misaligned on the left of the text'")
/                  %box(y=295,x=25)
/                  %box(y=295,x=35)
/                  %box(y=295,x=45,html="alt='Third Box Hotspot'")
/                  %text(y=295,x=19,position='<',
/                        text="The third box ONLY should have a hotspot")
/                  %bigbox(x1=20,y1=294.5,x2=50,y2=298.5,linecolor="brown")
/                run;
/
/                *- Set description to a space to stop whole output area -;
/                *- from having a hotspot and give the gif the same name -;
/                *- as the html body file. -;
/                proc ganno annotate=test description=" " name="annotest";
/                run;
/
/                *- If you rerun this code then you need to delete the -;
/                *- "annotest" grseg member in work.gseg so it can be  -;
/                *- reused as a name in the "proc ganno" step.  -;
/                proc greplay igout=gseg nofs;
/                  delete annotest;
/                  run;
/                quit;
/
/                ods html close;
/                ods listing;
/
/===============================================================================
/ PARAMETERS:
/-------name------- -------------------------description------------------------
/ x1                x coordinate start value
/ x2                x coordinate end value
/ x                 x coordinate (%box and %text only)
/ y                 y coordinate value
/ y1                y coordinate start value (%drawline, %bigbox and %fillbar)
/ y2                y coordinate end value (%drawline, %bigbox and %fillbar)
/ fillcolor="green"   Color to fill the inside of the shape with (not used for
/                   %bigbox). Default is "beige" for %fillbar.
/ linecolor="black"   Color of line to use for the outline of the shape
/ linewidth=1       Width of the line used to draw the outline
/ height=0.4        Height or fatness of the shape drawn (not %bigbox)
/ width=0.2         Width of the box shape (only used for %box)
/ html=' '          Used to assign html hotspots for the shapes drawn (not
/                   %bigbox). The %dclannovars macro will assign it the maximum
/                   allowed length of $ 1024. Note that this is an output
/                   variable. You must not use it as a working variable.
/ headfactor=1.5    Used to define the length of the arrow head in relation to
/                   the shaft fatness (not used for %rod even though defined).
/ fillpattern="mempty"  Default "map" pattern used to fill the shape is to have
/                   no pattern. Other recommended patterns are "m5n135", "m5n45"
/                   and "m5x45".
/--------------- These parameters apply to the %text macro only ----------------
/ text=' '          Text to display
/ font=' '          Font to use for the text is by default missing so that it
/                   uses what is defined to ftext= in the goptions statement.
/                   (note that non-SAS fonts must be enclosed in single quotes.
/                   If supplied as a variable they must also be enclosed in
/                   single quotes so they would have to be defined to a variable
/                   something like userfont="'Arial'". To specify a modified
/                   font such as "bold" then specify the modifier after a slash
/                   such as "'Arial / Bold'").
/ rotate=0          Rotation angle for the line of text relative to being
/                   parallel to the x axis.
/ angle=0           Angle of rotation of every text letter relative to the 
/                   perpendicular of the line of text.
/ position='+'      Default position of the text is CENTERED relative to the x,y
/                   coordinate. Use "<" for right-aligned and ">" for left-
/                   aligned, if you use "+" for centered. If you change this
/                   from your required default then you must reset it back
/                   manually afterwards.
/-------------- These parameters apply to the %xyzhsys macro only --------------
/  (Note that the following default values are also assigned in %dclannovars)
/ xsys='4'          Default for x coordinate system is '4' which is for
/                   multiples of cell height.
/ ysys='4'          Default for y coordinate system is '4' which is for 
/                   multiples of cell height.
/ zsys='2'          Default z coordinate system is to use data values
/ hsys='4'          Default for height coordinate system is '4' which is for
/                   multiples of cell height.
/===============================================================================
/ AMENDMENT HISTORY:
/ init --date-- mod-id ----------------------description------------------------
/ rrb  03Mar08         Header update
/ rrb  04Mar08         "Keep" list added to %dclannovars macro
/ rrb  04Mar08         xsys='4', ysys='4', hsys='4' (cell based) now same as SAS
/                      defaults. Height changed to half cell height for shape
/                      thickness.
/ rrb  05Mar08         Header update. New usage example added that shows how to
/                      use ODS to create output.
/ rrb  05Mar08         Defaults changed to font=' ' and color=' ' for %text
/ rrb  05Mar08         Default changed to height=. for %text
/ rrb  06Mar08         Header example code updated
/ rrb  06Mar08         %drawline and %bigbox macros added and some defaults
/                      changed. Example code in header updated.
/ rrb  07Mar08         header tidy plus some defaults changed
/ rrb  11Mar08         %fillbar macro added and line=1 moved to "poly" obs
/ rrb  01Jan09         %text macro changed to accept a sas variable name for the
/                      font= parameter.
/ rrb  02Jan09         The %box macro now works the same way as the other filled
/                      shape macros in that it is a two-pass draw. All filled
/                      shape macros now do a two pass draw. These major changes
/                      implemented for version 2.0
/===============================================================================
/ This is public domain software. No guarantee as to suitability or accuracy is
/ given or implied. User uses this code entirely at their own risk.
/=============================================================================*/

%put MACRO CALLED: rannomac v2.0;

%macro rannomac;
%mend rannomac;



              /*------------------------------------------*
                        declare annotate variables
               *------------------------------------------*/

%macro dclannovars;

  LENGTH html $ 1024 text $ 200;
  LENGTH function color $ 8;
  LENGTH style $ 32;
  LENGTH xsys ysys zsys hsys $ 1;
  LENGTH when position $ 1;

  LENGTH line size angle rotate x y z 8;

  RETAIN xsys '4' ysys '4' zsys '2' hsys '4';
  RETAIN position '+' when 'B';

  line=1;
  size=1;
  angle=0;
  rotate=0;
  x=0;
  y=0;
  z=0;
  html=' ';
  text=' ';
  function=' ';
  color=' ';

  KEEP html text function color style xsys ysys zsys hsys when position
       line size angle rotate x y z;

%mend dclannovars;



              /*------------------------------------------*
                        xyzhsys macro definition
               *------------------------------------------*/

%macro xyzhsys(xsys='4',
               ysys='4',
               zsys='2',
               hsys='4');
  xsys=&xsys;
  ysys=&ysys;
  zsys=&zsys;
  hsys=&hsys;

%mend xyzhsys;



              /*------------------------------------------*
                         drawline macro definition
               *------------------------------------------*/

%macro drawline(x1=,
                x2=,
                y1=,
                y2=,
         linecolor='black',
         linewidth=1);

x=&x1;y=&y1;line=1;color=&linecolor;size=&linewidth;function="move";output;
x=&x2;y=&y2;function="draw";output;

%mend drawline;



              /*------------------------------------------*
                         fillbar macro definition
               *------------------------------------------*/

%macro fillbar(x1=,
               x2=,
               y1=,
               y2=,
        fillcolor='beige');

x=&x1;y=&y1;line=3;color=&fillcolor;style="solid";function="move";output;
x=&x2;y=&y2;function="bar";output;
line=1;

%mend fillbar;



              /*------------------------------------------*
                           text macro definition
               *------------------------------------------*/

%macro text(x=,
            y=,
         text=' ',
        color=' ',
         font=' ',
       height=.,
         html=' ',
        angle=0,
       rotate=0,
     position='+');

  html=&html;
  x=&x;y=&y;color=&color;style=&font;text=&text;size=&height;
  angle=∠rotate=&rotate;position=&position;function="label";output;
  html=' ';

%mend text;



              /*------------------------------------------*
                          bigbox macro definition
               *------------------------------------------*/

%macro bigbox(x1=,
              x2=,
              y1=,
              y2=,
       linecolor='black',
       linewidth=1);

    x=&x1;y=&y1;function="poly";style="mempty";size=&linewidth;line=1;output;
    y=&y2;color=&linecolor;function="polycont";output;
    x=&x2;function="polycont";output;
    y=&y1;function="polycont";output;
    x=&x1;function="polycont";output;

%mend bigbox;



              /*------------------------------------------*
                           box macro definition
               *------------------------------------------*/

%macro box(x=,
           y=,
   fillcolor='green',
   linecolor='black',
   linewidth=1,
      height=0.4,
        html=' ',
       width=0.2,
 fillpattern="mempty");


  *- First time draw using "fillcolor" -;
  html=' ';
  x=&x-&width/2;y=&y-&height/2;function="poly";color=&fillcolor;style="msolid";size=&linewidth;output;
  x=&x+&width/2;line=1;color=&linecolor;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x-&width/2;function="polycont";output;
  y=&y-&height/2;function="polycont";output;

  *- Second time draw using "fillpattern" with pattern color same as line color. -;
  *- If you dont want a fill pattern then use fillpattern="mempty" -;
  html=&html;
  x=&x-&width/2;y=&y-&height/2;function="poly";color=&linecolor;style=&fillpattern;line=1;output;
  html=' ';
  x=&x+&width/2;color=&linecolor;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x-&width/2;function="polycont";output;
  y=&y-&height/2;function="polycont";output;

%mend box;



              /*------------------------------------------*
                           rod macro definition
               *------------------------------------------*/

%macro rod(y=,
          x1=,
          x2=,
   fillcolor="green",
   linecolor="black",
   linewidth=1,
      height=0.4,
        html=' ',
  headfactor=1.5,
 fillpattern="mempty");

  *- First time draw using "fillcolor" -;
  html=' ';
  x=&x1;y=&y-&height/2;function="poly";color=&fillcolor;style="msolid";size=&linewidth;output;
  x=&x2;line=1;color=&linecolor;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1;function="polycont";output;
  y=&y-&height/2;function="polycont";output;

  *- Second time draw using "fillpattern" with pattern color same as line color. -;
  *- If you dont want a fill pattern then use fillpattern="mempty" -;
  html=&html;
  x=&x1;y=&y-&height/2;function="poly";color=&linecolor;style=&fillpattern;line=1;output;
  html=' ';
  x=&x2;color=&linecolor;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1;function="polycont";output;
  y=&y-&height/2;function="polycont";output;

%mend rod;



              /*------------------------------------------*
                   rarrow (right arrow) macro definition
               *------------------------------------------*/
 
%macro rarrow(y=,
             x1=,
             x2=,
      fillcolor="green",
      linecolor="black",
      linewidth=1,
         height=0.4,
           html=' ',
     headfactor=1.5,
    fillpattern="mempty");

  *- First time draw using "fillcolor" -;
  html=' ';
  x=&x1;y=&y-&height/2;function="poly";color=&fillcolor;style="msolid";
  size=&linewidth;line=1;output;
  x=&x2-&height*&headfactor;color=&linecolor;function="polycont";output;
  y=&y-&height;function="polycont";output;
  x=&x2;y=&y;function="polycont";output;
  x=&x2-&height*&headfactor;y=&y+&height;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1;function="polycont";output;
  y=&y-&height/2;function="polycont";output;

  *- Second time draw using "fillpattern" with pattern color same as line color. -;
  *- If you dont want a fill pattern then use fillpattern="mempty" -;
  html=&html;
  x=&x1;y=&y-&height/2;function="poly";color=&linecolor;style=&fillpattern;line=1;output;
  html=' ';
  x=&x2-&height*&headfactor;color=&linecolor;function="polycont";output;
  y=&y-&height;function="polycont";output;
  x=&x2;y=&y;function="polycont";output;
  x=&x2-&height*&headfactor;y=&y+&height;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1;function="polycont";output;
  y=&y-&height/2;function="polycont";output;

%mend rarrow;



              /*------------------------------------------*
                   larrow (left arrow) macro definition
               *------------------------------------------*/
 
%macro larrow(y=,
             x1=,
             x2=,
      fillcolor="green",
      linecolor="black",
      linewidth=1,
         height=0.4,
           html=' ',
     headfactor=1.5,
    fillpattern="mempty");


  *- First time draw using "fillcolor" -;
  html=' ';
  x=&x1;y=&y;function="poly";style="msolid";color=&fillcolor;size=&linewidth;line=1;output;
  x=&x1+&height*&headfactor;y=&y-&height;color=&linecolor;function="polycont";output;
  y=&y-&height/2;function="polycont";output;
  x=&x2;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1+&height*&headfactor;function="polycont";output;
  y=&y+&height;function="polycont";output;
  x=&x1;y=&y;function="polycont";output;
  
  *- Second time draw using "fillpattern" with pattern color same as line color. -;
  *- If you dont want a fill pattern then use fillpattern="mempty" -;
  html=&html;
  x=&x1;y=&y;function="poly";color=&linecolor;style=&fillpattern;line=1;output;
  html=' ';
  x=&x1+&height*&headfactor;y=&y-&height;color=&linecolor;function="polycont";output;
  y=&y-&height/2;function="polycont";output;
  x=&x2;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1+&height*&headfactor;function="polycont";output;
  y=&y+&height;function="polycont";output;
  x=&x1;y=&y;function="polycont";output;

%mend larrow;



              /*------------------------------------------*
                 dblarrow (double arrow) macro definition
               *------------------------------------------*/
 
%macro dblarrow(y=,
               x1=,
               x2=,
        fillcolor="green",
        linecolor="black",
        linewidth=1,
           height=0.4,
             html=' ',
       headfactor=1.5,
      fillpattern="mempty");


  *- First time draw using "fillcolor" -;
  html=' ';
  x=&x1;y=&y;function="poly";style="msolid";color=&fillcolor;size=&linewidth;line=1;output;
  x=&x1+&height*&headfactor;y=&y-&height;color=&linecolor;function="polycont";output;
  y=&y-&height/2;function="polycont";output;
  x=&x2-&height*&headfactor;function="polycont";output;
  y=&y-&height;function="polycont";output;
  x=&x2;y=&y;function="polycont";output;
  x=&x2-&height*&headfactor;y=&y+&height;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1+&height*&headfactor;function="polycont";output;
  y=&y+&height;function="polycont";output;
  x=&x1;y=&y;function="polycont";output;

  *- Second time draw using "fillpattern" with pattern color same as line color. -;
  *- If you dont want a fill pattern then use fillpattern="mempty" -;
  html=&html;
  x=&x1;y=&y;function="poly";color=&linecolor;style=&fillpattern;line=1;output;
  html=' ';
  x=&x1+&height*&headfactor;y=&y-&height;color=&linecolor;function="polycont";output;
  y=&y-&height/2;function="polycont";output;
  x=&x2-&height*&headfactor;function="polycont";output;
  y=&y-&height;function="polycont";output;
  x=&x2;y=&y;function="polycont";output;
  x=&x2-&height*&headfactor;y=&y+&height;function="polycont";output;
  y=&y+&height/2;function="polycont";output;
  x=&x1+&height*&headfactor;function="polycont";output;
  y=&y+&height;function="polycont";output;
  x=&x1;y=&y;function="polycont";output;

%mend dblarrow;