/****************************************************************
Author:
Cameron Rookley      rookley@aruba.ccit.arizona.edu
University of Arizona
Doctoral Candidate
Dept. of Economics/Dept. of Finance
Date: 24Nov96
Provided without guarantees for public, non-commercial use.
****************************************************************/
/* NICEXY.SRC
             Interactive procedure to nicely generate xy type graphs.

   Format:   nfmt=nicexy(data,ofmt,nfmt)

             Where:

        data is a Tx(k+1) matrix. It is assumed that the
             1st column gives the x values (support for the graphs) and
             the k columns from 2:k+1 contain the data to be graphed.

        ofmt is a string used to load old graph format information
             which has been saved in a numeric matrix and a character
             string. ^ofmt.fmt for num. formats, ^ofmt.fst for char.
             information.  If set to 0, then user is prompted for all
             information.

        nfmt is a string used to save final graph information into a
             numerical matrix ^nfmt.fmt and ^nfmt.fst.  If set to 0
             nothing will be saved.


   Note: Be sure to issue the statement library pgraph; before calling this
         routine.  Also if using previous format information make sure
         ^ofmt.fmt and ^ofmt.fst files are in the current directory.
         Other than that, simply follow the prompts to "nicely"
         generate and modify a graph which is presentable, without having
         to remember the 8 million global variables contained in pgraph.
         Further modification options are likely to be added to this in
         the future, contact rookley@aruba.ccit.arizona.edu if interested
         in updates.
*/
proc(1)=nicexy(rawdat,ofmt,nfmt);
local support,yvals,tit,xax,yax,resp2,minxval,maxxval,incsz,sdivx,resp3;
local minyval,maxyval,incszy,sdivy,resp4,resp6,resp7,fs,xc,yc,resp8,i;
local legtxt,resp9,mxc,myc,mfs,mestxt,resp9b,resp9c,ndpbs,resp10,mchoice,sf;
local ofile,cont,resp3b,resp4b;
local respchg;
local charinf,numinf,brkind,charout,numout;
local nmess,mess,r1,r7;
local resp1b,resp12,onm;
cls;
_pqgplay=0;
sf=1; /* scaling factor */
graphset;
support=rawdat[.,1];
yvals=rawdat[.,2:cols(rawdat)];
if ofmt $==0;
print "Nice graphing utility.";
print "Written by Cameron Rookley, University of Arizona, Dept of Finance";
print;
print "Please enter all information when prompted.";
print "Note: To superscript text use [text], to subscript text use ]text[";
print;
print "Enter title of this graph.";
tit=cons; print;
print "Enter title of x-axis";
xax=cons; print;
print "Enter title of y-axis";
yax=cons; print;
xlabel(xax);
ylabel(yax);
title(tit);
print "Print time and date in top-right corner? y/n";
resp2=cons; print;
if strsect(resp2,1,1) $=="y" or strsect(resp2,1,1,)$=="Y";
   _pdate="\201GAUSS   ";
else;
   _pdate=0;
endif;
cls;
minxval=0; maxxval=0; incsz=0; sdivx=0;
print "Would you like direct control over x axis?";
print "Type y for direct control, any other key for auto-scaling";
resp3=cons; print;
if strsect(resp3,1,1) $=="y" or strsect(resp3,1,1,)$=="Y";
   print "Current range of support:" minc(support)~maxc(support);
   print;print "Enter minimum x value"; minxval=con(1,1);
   print;print "Enter maximum x value"; maxxval=con(1,1);
   print;print "Max number of zeros following decimal:"; _pxpmax=con(1,1);
   print;print "Enter increment size between major x ticks"; incsz=con(1,1);
   print;print "Enter number of minor x sub-divisions"; sdivx=con(1,1);
   print;print
   xtics(minxval,maxxval,incsz,sdivx);
endif;
minyval=0; maxyval=0; incszy=0; sdivy=0;
print "Would you like direct control over y axis?";
print "Type y for direct control, any other key for auto-scaling";
resp4=cons; print;
if strsect(resp4,1,1) $=="y" or strsect(resp4,1,1,)$=="Y";
   print "Current ranges of all series" minc(yvals)~maxc(yvals);
   print;print "Enter minimum y value"; minyval=con(1,1);
   print;print "Enter maximum y value"; maxyval=con(1,1);
   print;print "Max number of zeros following decimal:"; _pypmax=con(1,1);
   print;print "Enter increment between major y ticks"; incszy=con(1,1);
   print;print "Enter number of minor y sub-divisions"; sdivy=con(1,1);
   ytics(minyval,maxyval,incszy,sdivy);
endif;
cls;
print;
print "Create an tkf output file?";
resp7=cons; print;
if resp7$=="y" or resp7$=="Y";
   print "Enter name of graph file WITH A .tkf extension";
   ofile=cons;
   _ptek=ofile;
endif;
cls;
fs=0; xc=0; yc=0;
print "Create a legend? y/n";
resp8=cons; print;
if resp8$=="y" or resp8$=="Y";
   print "Note the typical page size is 9x6.85";
   print "Enter font size for legend (# 1-9)";
   fs=con(1,1); print;
   print "Enter x coordinate for lower left corner of legend.";
   print "This number must be reasonable enough for legend to fit in plot size";
   xc=con(1,1); print;
   print "Enter y coordinate for lower left corner of legend (in inches 0-9)";
   yc=con(1,1); print;
   _plegctl=2|fs|xc|yc;
   i=1;
   do while i le cols(yvals);
      print "Enter legend text for series" i;
      legtxt=cons; print;
      if i==1;
         _plegstr=legtxt;
      else;
         _plegstr=_plegstr$+"\000"$+legtxt;
      endif;
      i=i+1;
   endo;
endif;
cls;
mxc=0; myc=0; mfs=0;
nmess=0;
print "Would you like to add any extra messages or notes to your graph? y/n";
resp9=cons; print;
if resp9$=="y" or resp9$=="Y";
   print "How many messages would you like to add to the graph?";
   nmess=con(1,1);
   mess=1;
   do while mess le nmess;
    cls; print "ENTER INFORMATION FOR MESSAGE #:" mess; print;
    print "Enter font size IN INCHES (typical value=0.125) ";
    mfs=con(1,1); print;
    print "Enter x coordinate for lower left corner of message (in inches 0-9)";
    print "This number must be reasonable enough for message to fit on page";
    mxc=con(1,1); print;
    print "Enter y coordinate for lower left corner of message (in inches 0-6.85)
           ";
    myc=con(1,1); print;
    if mess==1;
      _pmsgctl=mxc~myc~mfs~0~2~10~0;
    else;
      _pmsgctl=_pmsgctl|(mxc~myc~mfs~0~2~10~0);
    endif;
    print "Enter message text.";
    mestxt=cons; print;
    if mess==1;
      _pmsgstr=mestxt;
    else;
      _pmsgstr=_pmsgstr $+ "\000" $+ mestxt;
    endif;
    mess=mess+1;
   endo;
endif;
cls;
print "Would you like to use line symbols for this graph? y/n";
resp9b=cons; print;
if resp9b$=="y" or resp9b$=="Y";
   print "Would you like lines & symbols (y) or symbols only (any other key)";
   resp9c=cons; print;
   print "Enter the number of data points between each symbol";
   ndpbs=con(1,1);
   if resp9c$=="y" or resp9c$=="Y";
     _plctrl=ndpbs;
   else;
     _plctrl=-ndpbs;
   endif;
   print "Enter the size for line symbols. Typical value=1.5:";
   _psymsiz=con(1,1); print;
endif;
elseif ofmt $/= 0;
 loads charinf=^ofmt;
 loadm numinf=^ofmt;
 /* scan through charinf and extract necessary information, which has
    been separated with a "><" combination */
 brkind=strindx(charinf,"><",1);
 tit=strsect(charinf,1,brkind-1);
 charinf=strsect(charinf,brkind+2,strlen(charinf)-(brkind+1));
 brkind=strindx(charinf,"><",1);
 xax=strsect(charinf,1,brkind-1);
 charinf=strsect(charinf,brkind+2,strlen(charinf)-(brkind+1));
 brkind=strindx(charinf,"><",1);
 yax=strsect(charinf,1,brkind-1);
 charinf=strsect(charinf,brkind+2,strlen(charinf)-(brkind+1));
 brkind=strindx(charinf,"><",1);
 _pdate=strsect(charinf,1,brkind-1);
 charinf=strsect(charinf,brkind+2,strlen(charinf)-(brkind+1));
 brkind=strindx(charinf,"><",1);
 _ptek=strsect(charinf,1,brkind-1);
 charinf=strsect(charinf,brkind+2,strlen(charinf)-(brkind+1));
 brkind=strindx(charinf,"><",1);
 _plegstr=strsect(charinf,1,brkind-1);
 charinf=strsect(charinf,brkind+2,strlen(charinf)-(brkind+1));
 brkind=strindx(charinf,"><",1);
 _pmsgstr=strsect(charinf,1,brkind-1);
 title(tit);
 xlabel(xax);
 ylabel(yax);
 minxval=numinf[1];
 maxxval=numinf[2];
 incsz=numinf[3];
 sdivx=numinf[4];
 if (minxval+maxxval+incsz+sdivx) ne 0;
    xtics(minxval,maxxval,incsz,sdivx);
 endif;
 minyval=numinf[5];
 maxyval=numinf[6];
 incszy=numinf[7];
 sdivy=numinf[8];
 if (minyval+maxyval+incszy+sdivy) ne 0;
    ytics(minyval,maxyval,incszy,sdivy);
 endif;
 fs=numinf[9];
 xc=numinf[10];
 yc=numinf[11];
 if (fs+xc+yc)>0;
   _plegctl=2|fs|xc|yc;
 else;
   _plegctl=0;
 endif;
 nmess=numinf[12];
 r1=13; r7=19;
 if nmess>0;
    i=1;
    do while i le nmess;
      if i==1;
       _pmsgctl=numinf[r1:r7]';
       r1=r1+7; r7=r7+7;
      else;
       _pmsgctl=_pmsgctl|numinf[r1:r7]';
      endif;
      i=i+1;
    endo;
 endif;
 _plctrl=numinf[r1];
 _psymsiz=numinf[r1+1];
 _pxsci=numinf[r1+2];
 _pysci=numinf[r1+3];
 sf=numinf[r1+4]; support=support.*sf;
 print "Change name of tkf file? (y/n) Current name:" _ptek;
 respchg=cons;
 if respchg$=="y" or respchg$=="Y";
    print "Enter new file name, being sure to use tkf extension:"; _ptek=cons;
    print;
 endif;
 print "Change contents of legend now? (y/n)";
 respchg=cons;
 if respchg$=="y" or respchg$=="Y";
    i=1;
    do while i le cols(yvals);
       print "Enter legend text for series" i;
       legtxt=cons; print;
       if i==1;
          _plegstr=legtxt;
       else;
          _plegstr=_plegstr$+"\000"$+legtxt;
       endif;
       i=i+1;
    endo;
 endif;
endif;
xy(support,yvals);
cls;
print "Would you like to make any modifications to this graph? (y/n)";
resp10=cons;
if resp10$=="y" or resp10$=="Y";
 cont=1;
 do while cont==1;
 cls;
 print "ENTER THE NUMBER FOR ANY ITEMS YOU WOULD LIKE TO MODIFY.";
 print "AFTER EACH MODIFICATION IS MADE, THE GRAPH WILL BE REPLOTTED.";
 print;
 print " 0: Done modifying, happy with current graph.";
 print " 1: Modify main title or axis titles.";
 print " 2: Modify either x or y tick mark scheme.";
 print " 3: Modify location and/or size of legend. See 99.";
 print " 4: Modify contents of legend.";
 print " 5: Modify location and/or size of extra messages. See 99.";
 print " 6: Modify contents of extra messages.";
 print " 7: Modify line symbols.";
 print " 8: Rescale support.";
 print " 9: Control use of scientific notation.";
 print "10: Add another message";
 print "11: Change line thickness of main curves.";
 print "12: Make export ready. ie. avoid faint lines for .pic files";
 print "99: Observe a temporary coordinate grid with current graph";

 print; mchoice=con(1,1);
 if mchoice==1;
    cont=1;
    do while cont==1;
     cls;
     print "What would you like to change?";
     print;
     print "0: Nothing. Happy with current titles";
     print "1: Main Title:" tit;
     print "2: X-axis title:" xax;
     print "3: Y-axis title:" yax;
     print "4: Gauss time stamp:" _pdate;
     resp1b=con(1,1);
     if resp1b==1;
        print "Enter title of this graph.";
        tit=cons; print;
     elseif resp1b==2;
        print "Enter title of x-axis";
        xax=cons; print;
     elseif resp1b==3;
        print "Enter title of y-axis";
        yax=cons; print;
     elseif resp1b==4;
        print "Print time and date in top-left corner with Gauss stamp? y/n";
        resp2=cons; print;
        if strsect(resp2,1,1) $=="y" or strsect(resp2,1,1,)$=="Y";
          _pdate="\201GAUSS   ";
        else;
          _pdate=0;
        endif;
     elseif resp1b==0;
        cont=0;
     else;
        print "Invalid choice, pausing for 2 seconds" pause(2);
     endif;
    endo;
    cont=1;
    xlabel(xax);
    ylabel(yax);
    title(tit);
    cls;
 elseif mchoice==2;
    cls;
    print "Would you like to modify x axis tick marks? (y/n)";
    resp3b=cons; print;
    if strsect(resp3b,1,1) $=="y" or strsect(resp3b,1,1,)$=="Y";
      print "Current range of support:" minc(support)~maxc(support);
      print;print "Enter minimum x value"; minxval=con(1,1);
      print;print "Enter maximum x value"; maxxval=con(1,1);
      print;print "Max number of zeros following decimal:"; _pxpmax=con(1,1);
      print;print "Enter increment between major x ticks"; incsz=con(1,1);
      print;print "Enter number of minor x sub-divisions"; sdivx=con(1,1);
      print;print
      xtics(minxval,maxxval,incsz,sdivx);
    endif;
    cls;
    print "Would you like to modify y axis tick marks? (y/n)";
    resp4b=cons; print;
    if strsect(resp4b,1,1) $=="y" or strsect(resp4b,1,1,)$=="Y";
       print "Current ranges of all series" minc(yvals)~maxc(yvals);
       print;print "Enter minimum y value"; minyval=con(1,1);
       print;print "Max number of zeros following decimal:"; _pypmax=con(1,1);
       print;print "Enter maximum y value"; maxyval=con(1,1);
       print;print "Enter increment between major y ticks"; incszy=con(1,1);
       print;print "Enter number of minor y sub-divisions"; sdivy=con(1,1);
       ytics(minyval,maxyval,incszy,sdivy);
    endif;
    cls;
 elseif mchoice==3;
    print "Enter font size for legend (# 1-9), current value:" fs;
    fs=con(1,1); print;
    print "Enter x coordinate for lower left corner of legend, current value:"
           xc;
    xc=con(1,1); print;
    print "Enter y coordinate for lower left corner of legend, current value:"
           yc;
    yc=con(1,1); print;
    _plegctl=2|fs|xc|yc;
 elseif mchoice==4;
   i=1;
   do while i le cols(yvals);
      print "Enter legend text for series" i;
      legtxt=cons; print;
      if i==1;
         _plegstr=legtxt;
      else;
         _plegstr=_plegstr$+"\000"$+legtxt;
      endif;
      i=i+1;
   endo;
 elseif mchoice==5;
   cls;
   if nmess>1;
     print "Modify location of which message?";
     print "Current message string (each message separated by null)";
     print _pmsgstr;
     mess=con(1,1);
     mfs=_pmsgctl[mess,3]; mxc=_pmsgctl[mess,1]; myc=_pmsgctl[mess,2];
   elseif nmess==1;
     mess=1;
     mfs=_pmsgctl[1,3]; mxc=_pmsgctl[1,1]; myc=_pmsgctl[1,2];
   endif;
   if nmess>0;
    print;
    print "Enter font size for message IN INCHES. Current value:" mfs;
    mfs=con(1,1); print;
    print "Enter x coordinate for lower left corner of message (in inches 0-9)";
    print "Current value is:" mxc;
    mxc=con(1,1); print;
 print "Enter y coordinate for lower left corner of message (in inches 0-6.85)";
    print "Current value is:" myc;
    myc=con(1,1); print;
    _pmsgctl[mess,3]=mfs; _pmsgctl[mess,1]=mxc; _pmsgctl[mess,2]=myc;
   else;
    print "Use option 10 to add a new message. Pausing for 2 seconds.";
    pause(2);
   endif;
 elseif mchoice==6;
    mess=1;
    do while mess le nmess;
    print "Enter text for message" mess;
    mestxt=cons; print;
    if mess==1;
      _pmsgstr=mestxt;
    else;
      _pmsgstr=_pmsgstr $+ "\000" $+ mestxt;
    endif;
    mess=mess+1;
   endo;
 elseif mchoice==7;
  print "Would you like to use line symbols for this graph? y/n";
  resp9b=cons; print;
  if resp9b$=="y" or resp9b$=="Y";
   print "Would you like lines & symbols (y) or symbols only (any other key)";
   resp9c=cons; print;
   print "Enter the number of data points between each symbol";
   ndpbs=con(1,1);
   if resp9c$=="y" or resp9c$=="Y";
     _plctrl=ndpbs;
   else;
     _plctrl=-ndpbs;
   endif;
   print "Enter the size for line symbols. Current value:" _psymsiz;
     _psymsiz=con(1,1);
  else;
     _plctrl=0;
  endif;
 elseif mchoice==8;
  print "Enter the scaling factor for support.  Support will be multiplied";
  print "by this scaling factor.  You may need to modify xtics if you choose";
  print "this option.";
  sf=sf*con(1,1);
  support=sf.*support;
 elseif mchoice==9;
  print "Threshold at which to use scientific notation on x-axis?";
  print "Current value is:" _pxsci;
  print; _pxsci=con(1,1);
  print "Threshold at which to use scientific notation on y-axis?";
  print "Current value is:" _pysci;
  print; _pysci=con(1,1);
 elseif mchoice==10;
  print "How many messages would you like to add to the graph?";
  onm=nmess;
  nmess=nmess+con(1,1);
  mess=onm+1;
  do while mess le nmess;
    cls; print "ENTER INFORMATION FOR MESSAGE #:" mess; print;
    print "Enter font size IN INCHES (typical value=0.125) ";
    mfs=con(1,1); print;
    print "Enter x coordinate for lower left corner of message (in inches 0-9)";
    print "This number must be reasonable enough for message to fit on page";
    mxc=con(1,1); print;
    print "Enter y coordinate for lower left corner of message (in inches 0-6.85)
           ";
    myc=con(1,1); print;
    if mess==1;
      _pmsgctl=mxc~myc~mfs~0~2~10~0;
    else;
      _pmsgctl=_pmsgctl|(mxc~myc~mfs~0~2~10~0);
    endif;
    print "Enter message text.";
    mestxt=cons; print;
    if mess==1;
      _pmsgstr=mestxt;
    else;
      _pmsgstr=_pmsgstr $+ "\000" $+ mestxt;
    endif;
    mess=mess+1;
   endo;
 elseif mchoice==11;
    cls;
    print "Change line thickness of main curves.  This is useful for";
    print "Exporting graph into other software (eg. Wordperfect) as a";
    print "Lotus .pic file.";
    print "Current value:" _plwidth;
    print;
    print "Enter new value:";
    _plwidth=con(1,1);
 elseif mchoice==12;
    cls;
    print "Make graph export ready? (y/n)";
    print;
    print "Note this option will set color of all curves to white and";
    print "avoid the use of dot-type line patterns which often appear";
    print "faint when exported.";
    print ;
    resp12=cons;
    if resp12 $== "y" or resp12$=="Y";
       _pltype=6~1~3~5;
       _pltype=reshape(_pltype,1,cols(yvals));
       _pcolor=15;
    endif;
 elseif mchoice==99;
    call gridco(support,yvals);
 elseif mchoice==0;
    cont=0;
 else;
    print "INVALID CHOICE!!! pausing for 2 seconds."; pause(2);
 endif;
 if mchoice ne 99;
    xy(support,yvals);
 endif;
endo;
endif;

charout=tit $+ "><" $+ xax $+ "><" $+ yax $+ "><" $+ _pdate;
charout=charout $+ "><" $+ _ptek $+ "><" $+ _plegstr $+ "><" $+ _pmsgstr;
charout=charout $+ "><";

numout=minxval|maxxval|incsz|sdivx;
numout=numout|minyval|maxyval;
numout=numout|incszy|sdivy|_pqgplay|fs|xc|yc;
numout=numout|nmess;
/* write each row of _pmsgctl 1 by 1 */
if nmess>0;
i=1;
do while i le nmess;
   numout=numout|(_pmsgctl[i,.]');
   i=i+1;
endo;
endif;
numout=numout|_plctrl|_psymsiz|_pxsci|_pysci|sf;
if nfmt $/= 0;
   save charout, ^nfmt=charout;
   save numout, ^nfmt=numout;
endif;
retp(nfmt);
endp;

proc gridco(sup,yvals);
  local gridmat,r;
  cls;
  print "Your current graph with a set of coorinate points will now";
  print "be drawn.  Please make a note of these coordinates so that";
  print "you can efficiently add whatever is necessary to your graph.";
  print "Note the 1st line on the far left is inch 1 in x.";
  print "The 1st line from the bottom is inch 1 in y.";
  print "Hit return to continue"; cons;
  gridmat=zeros(14,9);
  gridmat[.,1]=2.*ones(14,1); /* line */
  gridmat[.,2]=ones(14,1);    /* solid */
  /* horizontal lines   */
  gridmat[9:14,3]=zeros(6,1);/* x strt*/
  gridmat[9:14,4]=seqa(1,1,6);/* y strt*/
  gridmat[9:14,5]=9.*ones(6,1);/* x end */
  gridmat[9:14,6]=seqa(1,1,6);/* y end */
  /* vertical lines    */
  gridmat[1:8,3]=seqa(1,1,8);    /* x strt*/
  gridmat[1:8,5]=seqa(1,1,8);    /* x end */
  r=1;
  do while r le 7;
   gridmat[r,4]=0;  gridmat[r,6]=6.85;    /* y strt*/
   gridmat[r+1,4]=6.85; gridmat[r+1,6]=0; /* y end */
   r=r+2;
  endo;
  gridmat[.,7]=ones(14,1);
  gridmat[.,8]=4.*ones(14,1);
  gridmat[.,9]=1.*ones(14,1);
  _pline=gridmat;
  xy(sup,yvals);
  _pline=0;
  retp(0);
endp;

