*! version 1.0 STB-45 gr29 /*----------------------------------------------------------------------- labgraph Extension to (two-way) graph command allowing placement of text labels at x, y coordinates. All (two-way) graph options supported. Two new options: labtext(string[;string]...) labxy(x,y[;x,y]...) These give a semi-colon delimited list of labels and a semi-colon list of x,y pairs for locating the labels. Must be the same number of each. One modified graph option: trim In graph, trim defaults to 8. In labgraph it defaults to the minimum of 32 and the length of the longest label string. Jon Faust alteration log: June 17, 1998 first production version ----------------------------------------------------------------------*/ pro def labgraph quietly{ version 3.1 if "%_*"=="" { noi di in red "invalid syntax -- see help labvar" exit 198 } mac def _varlist "req ex min(2)" mac def _if "opt" mac def _in "opt" mac def _options "TRim(integer 0) Connect(string) Symbol(string) labxy(string) labtext(string) *" parse "%_*" /* assign _xvar, last var in list */ /* and _yvars, the other variables */ parse "%_varlist", parse(" ") mac def _yvars "" while("%_1"!="") { mac def _v %_1 mac shift if ("%_1"!="") { mac def _yvars "%_yvars %_v" } else mac def _xvar "%_v" } parse "%_labtext", parse(";") /* parse the text for the lables */ mac def _s "" /* put in e.g. _text for nth label */ mac def _c "" /* build: */ mac def _v "" /* _s supplement to the symbol string */ mac def _n =0 /* _c supplement to the connect string */ mac def _maxlen=0 /* _v supplement to the varlist string */ while("%_1"!="") { /* _n number of lables */ mac def _n = %_n+1 /* _maxlen for calculating trim option */ mac def _s "[__lstr`%_n]%_s" mac def _c ".%_c" mac def _v "_lstr`%_n %_v" mac def _txt`%_n=ltrim(rtrim("%_1")) mac def _len = length("%`_txt`%_n") if(%_len>%_maxlen) { mac def _maxlen = %_len } mac shift mac shift /* eat the parse char */ } /* if trim not set, set to */ if(%_trim==0) { /* min(32, %_maxlen) */ mac def _trim = min(%_maxlen,32) } /* parse x,y coord's for labels */ /* & build relevant variables */ mac def _nn=1 parse "%_labxy", parse(",;") while(%_nn<=%_n) { mac def _x %_1 mac shift mac shift mac def _y %_1 mac shift mac shift noi _gen_var %_xvar, z(_lstr`%_nn) x(%_x) y(%_y) t(%`_txt`%_nn) mac def _nn=%_nn+1 } noi graph %_v %_yvars %_xvar %_if %_in,connect(%_c`%_connect) s(%_s`%_symbol) trim(%_trim) %_options cap drop _lstr* /* clean up */ cap drop __lstr* } end /* _gen_var build one numeric variable and one string variable for placing the label. We graph the numeric variable using the text variable as the graph symbol */ pro def _gen_var quietly{ version 3.1 mac def _varlist "req ex min(1) max(1)" mac def _options "x(real 0) y(real 0) t(string) z(string)" parse "%_*" cap drop _lstrx /* _varlist is the _xvar for the graph */ /* find value of _xvar closest to _x */ sum %_varlist if %_varlist >= %_x mac def _up=_result(5) sum %_varlist if %_varlist <= %_x mac def _dn=_result(6) if (%_x - %_dn < %_up - %_x) { /* set _x equal to this closest value */ mac def _x = %_dn } if (%_x - %_dn >= %_up - %_x) { /* set _x equal to this closest value */ mac def _x = %_up } cap drop %_z /* build _z, the numeric variable */ cap drop _`%_z /* with value _y whenever _varlist=_x */ gen %_z = . /* missing otherwise */ replace %_z = %_y if abs(%_varlist-%_x)<%_x*.00000001 li x %_z gen _lstrx=0 /* to find first occurance of */ replace _lstrx=1 if %_z!=. /* non-missing _z */ replace _lstrx=sum(_lstrx) mac def _len=length("%_t") /* gen __z, string variable */ if (%_len>32) { /* missing except at first nonmissing */ mac def _len=32 /* _z */ mac def _t = substr("%_t",1,32) } mac def _len = %_len+1 gen str`%_len _`%_z = "" replace _`%_z = "%_t" if _lstrx==1 & ((_lstrx[_n-1]==0)|(_n==1)) cap drop _lstrx /* clean up & go */ } end