00001 00002 c 00003 c Copyright (c) 1986,1987,1988,1989,1990,1991,1992,1993, 00004 c by Steve McMillan, Drexel University, Philadelphia, PA. 00005 c 00006 c All rights reserved. 00007 c 00008 c Redistribution and use in source and binary forms are permitted 00009 c provided that the above copyright notice and this paragraph are 00010 c duplicated in all such forms and that any documentation, 00011 c advertising materials, and other materials related to such 00012 c distribution and use acknowledge that the software was developed 00013 c by the author named above. 00014 c 00015 c THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 00016 c IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 00017 c WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00018 c 00019 subroutine fr lnxdr(y,x1,x2,dxs,dxm,dxl, 00020 $ iax,ilab,nlab,ndec,lpow) 00021 save 00022 c 00023 c Draw x-axis, tick marks and numbers for linear case (ndec nonzero), 00024 c and major tick marks and numbers for the logarithmic case (ndec = 0). 00025 c 00026 c iax = 1 for bottom axis, 2 for top. 00027 c ilab = 0 for no labels, 1 for labels 00028 c nlab = estimated number of spaces for labels 00029 c 00030 c ndec = -1 ==> integer format 00031 c ndec = 0 ==> log axes, want to plot 10^n 00032 c ndec > 0: number of places to right of decimal point 00033 c lpow = 0 ==> F format, E format (lpow = exponent) otherwise 00034 c 00035 c No numbers are drawn for nonzero lmode, regardless of ilab. 00036 c 00037 dimension dx(3) 00038 common/scales/xl,xr,dinchx,ybot,ytop,dinchy,rlen,slen 00039 common/dev status/idevon,idevpen,idevwt 00040 common/fr hts/htl,htn/fr wts/iwts(4) 00041 common/fr ticks/tiks(3),tikl 00042 common/fr xnums/xnumbot 00043 c 00044 common/fr bare/ibare 00045 common/fr lbx/lmode 00046 common/fr tik level/jtik level 00047 c 00048 character*80 string 00049 parameter (TOL = 1.e-6, WTOL = 0.75) 00050 c 00051 data mode/1/jtik level/1/ 00052 c 00053 data theta/0./ 00054 c 00055 cinch(xa,xs,di)=(xa-xs)*di 00056 c 00057 dx(1)=dxs 00058 dx(2)=dxm 00059 dx(3)=dxl 00060 sax=cinch(y,ybot,dinchy) 00061 r1=cinch(x1,xl,dinchx) 00062 r2=cinch(x2,xl,dinchx) 00063 c 00064 if (iwts(1).gt.0) then 00065 jwt=idevwt 00066 call weight(iwts(1)) 00067 end if 00068 c 00069 call plot(r1,sax,3) 00070 call plot(r2,sax,2) 00071 c 00072 ds=1. 00073 if (iax.eq.2) ds=-1. 00074 c 00075 c Draw the tick marks: j = 1, 2, 3 correspond to small, medium and 00076 c large tick marks, respectively. Tick sizes are set in eframe. 00077 c 00078 do j=jtik level,3 00079 if (dx(j).ne.0) then 00080 stik=sax+ds*tiks(j) 00081 c 00082 call fr lnfnc(x1,x2,dx(j),mode,firstx,nx) 00083 c 00084 dr=dx(j)*dinchx 00085 r=cinch(firstx,xl,dinchx) 00086 do i=1,nx 00087 call plot(r,sax,3) 00088 call plot(r,stik,2) 00089 r=r+dr 00090 end do 00091 end if 00092 end do 00093 c 00094 if (iwts(1).gt.0) call weight(jwt) 00095 if (ilab.eq.0.or.lmode.ne.0) return 00096 c 00097 c Now add the numbers. 00098 c ------------------- 00099 c 00100 c Numbers will be placed at intervals of dx1, starting at firstx. 00101 c Offset is above or below the axis, depending on iax. 00102 c Amount of offset scales with htn. 00103 c 00104 c Determine placement above or below the axis... 00105 c 00106 htnsave = htn 00107 c 00108 x=firstx 00109 r=cinch(firstx,xl,dinchx) 00110 c 00111 c First determine the width of a "typical" number string... 00112 c 00113 if (ibare.eq.1.or.(ndec.ne.0.and.lpow.eq.0)) then 00114 if (ibare.eq.1) then 00115 c 00116 c Just use the nominal width of the number string. 00117 c 00118 wid=.85*htn*(nlab+.5) 00119 else 00120 call numsym(x1,ndec,string,nsym) 00121 call sim size(htn,string,nsym,wid,dum) 00122 call numsym(x2,ndec,string,nsym) 00123 call sim size(htn,string,nsym,wid2,dum) 00124 if (wid2.gt.wid) wid = wid2 00125 end if 00126 c 00127 else 00128 if (ndec.eq.0) then 00129 c 00130 c Nominal dimensions: 00131 c 00132 c wid = .85*2.5*htn 00133 c 00134 c Better: 00135 c 00136 call sim size(htn,'10^+n',5,wid,dum) 00137 c 00138 else 00139 call exp_string(x1,ndec,string,nsym,1) 00140 call sim size(htn,string,nsym,wid,dum) 00141 call exp_string(x2,ndec,string,nsym,1) 00142 call sim size(htn,string,nsym,wid2,dum) 00143 if (wid2.gt.wid) wid = wid2 00144 end if 00145 end if 00146 c 00147 c Reduce the scale if the estimated size is too great. 00148 c 00149 if (wid.gt.WTOL*dr) htn=htn*WTOL*dr/wid 00150 c 00151 c ...then determine the vertical offset... 00152 c 00153 if (ibare.eq.1.or.(ndec.ne.0.and.lpow.eq.0)) then 00154 if (iax.eq.1) then 00155 s=sax-1.5*htn 00156 else 00157 s=sax+.5*htn 00158 end if 00159 else 00160 if (iax.eq.1) then 00161 s=sax-1.75*htn 00162 else 00163 s=sax+.5*htn 00164 end if 00165 end if 00166 c 00167 c ...and update the data on the bottom of the number field. 00168 c 00169 if (iax.eq.1)then 00170 xnumbot=s 00171 if (ndec.ne.0) xnumbot=xnumbot-.5*htn 00172 end if 00173 c 00174 if (iwts(2).gt.0)then 00175 jwt=idevwt 00176 call weight(iwts(2)) 00177 end if 00178 c 00179 c Plot the numbers. 00180 c 00181 call pushstr 00182 call strpos(.5,0.) 00183 c 00184 rleft=cinch(x1,xl,dinchx) 00185 rright=cinch(x2,xl,dinchx) 00186 if (rleft.gt.rright) then 00187 temp = rleft 00188 rleft = rright 00189 rright = temp 00190 end if 00191 c 00192 xscale = max(abs(x1),abs(x2)) 00193 do i=1,nx 00194 if (lpow.eq.0.or.ibare.eq.1 00195 $ .or.(ndec.ne.0.and.abs(x)/xscale .lt. TOL)) then 00196 call fr numbr(r,s,htn,x,theta,ndec) 00197 else 00198 if (ndec.eq.0) then 00199 c 00200 c Logarithmic plot. 00201 c 00202 c First see if we need any intermediate labels. 00203 c Note that there will still be cases where no labels 00204 c appear (narrow ranges in logarithmic plots...). 00205 c 00206 if (nx.le.3.and.abs(dxl-1.).lt..01) then 00207 r3 = r-.5229*dr 00208 if (r3.ge.rleft) then 00209 call format_string(10.**(x-.5*dxl),-1, 00210 $ string,nsym,1) 00211 call simbol(r3,s,htn,string,theta,nsym) 00212 end if 00213 if (i.eq.nx) then 00214 r3 = r+.4771*dr 00215 if (r3.le.rright) then 00216 call format_string(10.**(x+.5*dxl),-1, 00217 $ string,nsym,1) 00218 call simbol(r3,s,htn,string,theta,nsym) 00219 end if 00220 end if 00221 end if 00222 c 00223 call format_string(10.**x,ndec,string,nsym,0) 00224 call simbol(r,s,htn,string,theta,nsym) 00225 c 00226 else 00227 c 00228 c Exponential format on a linear plot. 00229 c 00230 call exp_string(x,ndec,string,nsym,1) 00231 end if 00232 c 00233 call simbol(r,s,htn,string,theta,nsym) 00234 c 00235 end if 00236 r=r+dr 00237 x=x+dxl 00238 end do 00239 c 00240 call popstr 00241 c 00242 if (iwts(2).gt.0) call weight(jwt) 00243 c 00244 c DON'T restore the height here if we want changes to propogate 00245 c to the y-axis labels. 00246 c 00247 call getyfollowsx(iy) 00248 if (iy.eq.0) htn = htnsave 00249 c 00250 end 00251 00252 00253 subroutine setyfollowsx(iy) 00254 c 00255 c If ixy = 0, then the y number sizes will be INDEPENDENT of 00256 c changes made by frlnxdr. If ixy = 1, changes in the x-axis 00257 c number sizes will propogate to the y axis. 00258 c 00259 save 00260 common /yfollowsx/ixy 00261 data ixy/1/ 00262 c 00263 ixy = iy 00264 if (ixy.ne.0) ixy = 1 00265 return 00266 c 00267 entry getyfollowsx(iy) 00268 iy = ixy 00269 end 00270 00271 00272 subroutine format_string(x,ndec,string,nsym,icoef) 00273 character*(*) string 00274 parameter (TOL = 0.1) 00275 c 00276 common /fr plain/ iplain 00277 c 00278 c Call exp_string, but check for special cases first. 00279 c 00280 isp = 1 00281 if (abs(x/.01-1.).lt.TOL) then 00282 string = '0.01' 00283 nsym = 4 00284 else if (abs(x/.03-1.).lt.TOL) then 00285 string = '0.03' 00286 nsym = 4 00287 else if (abs(x/.1-1.).lt.TOL) then 00288 string = '0.1' 00289 nsym = 3 00290 else if (abs(x/.3-1.).lt.TOL) then 00291 string = '0.3' 00292 nsym = 3 00293 else if (abs(x/1.-1.).lt.TOL) then 00294 string = '1' 00295 nsym = 1 00296 else if (abs(x/3.-1.).lt.TOL) then 00297 string = '3' 00298 nsym = 1 00299 else if (abs(x/10.-1.).lt.TOL) then 00300 string = '10' 00301 nsym = 2 00302 else if (abs(x/30.-1.).lt.TOL) then 00303 string = '30' 00304 nsym = 2 00305 else if (abs(x/100.-1.).lt.TOL) then 00306 string = '100' 00307 nsym = 3 00308 else if (abs(x/300-1.).lt.TOL) then 00309 string = '300' 00310 nsym = 3 00311 else 00312 isp = 0 00313 call exp_string(x,ndec,string,nsym,icoef) 00314 end if 00315 c 00316 if (isp.eq.1.and.iplain.eq.1) 00317 $ call convert_to_plain(string, nsym) 00318 c 00319 end 00320 00321 00322 subroutine exp_string(x,ndec,string,nsym,icoef) 00323 character*(*)string 00324 character*10 is 00325 c 00326 common /fr plain/ iplain 00327 c 00328 c Convert x into a "simbol" string in exponential format. 00329 c Skip the leading exponent if icoef = 0. 00330 c 00331 call compoz(x,f,n) 00332 c 00333 if (icoef.eq.0) then 00334 string(1:2) = '10' 00335 nsym = 2 00336 else 00337 c 00338 c We probably don't want exponential format if n = -1, 0, or 1. 00339 c 00340 if (abs(n).le.1) then 00341 c 00342 c May need to add or remove decimal digits to maintain 00343 c precision in this case. 00344 c 00345 call numsym(x,ndec-n,string,nsym) 00346 else 00347 call numsym(f,ndec,string,nsym) 00348 nt = 11 00349 string(nsym+1:nsym+nt) = '%@%@ %@@*10' 00350 nsym = nsym + nt 00351 end if 00352 end if 00353 c 00354 if (icoef.eq.0.or.abs(n).gt.1) then 00355 write(is,'(i10)')n 00356 do i=1,10 00357 if (is(i:i).gt.' ') then 00358 string(nsym+1:nsym+1) = '^' 00359 string(nsym+2:nsym+2) = is(i:i) 00360 nsym = nsym + 2 00361 end if 00362 end do 00363 end if 00364 c 00365 if (iplain.eq.1) call convert_to_plain(string, nsym) 00366 c 00367 c write(6,*)'x, str = ',x,' ',string(1:nsym) 00368 c 00369 end 00370 00371 00372 subroutine convert_to_plain(string, nsym) 00373 character*(*) string 00374 character*80 strtmp 00375 c 00376 c Make digits plain font. 00377 c 00378 ns = nsym 00379 strtmp = string 00380 nsym = 0 00381 do i=1,ns 00382 if (strtmp(i:i).lt.'0'.or.strtmp(i:i).gt.'9') then 00383 nsym = nsym + 1 00384 string(nsym:nsym) = strtmp(i:i) 00385 else 00386 nsym = nsym + 1 00387 string(nsym:nsym) = '@' 00388 nsym = nsym + 1 00389 string(nsym:nsym) = strtmp(i:i) 00390 end if 00391 end do 00392 c 00393 end