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
00020 subroutine fr lnydr(x,y1,y2,dys,dym,dyl,
00021 $ iax,ilab,nlab,ndec,lpow)
00022 save
00023 c
00024 c As for frlnxdr, but for the y-axis
00025 c
00026 c Draw y-axis, tick marks and numbers for linear case (ndec nonzero),
00027 c and major tick marks and numbers for the logarithmic case (ndec = 0).
00028 c
00029 c iax = 1 for bottom axis, 2 for top.
00030 c ilab = 0 for no labels, 1 for labels
00031 c nlab = estimated number of spaces for labels
00032 c
00033 c ndec = -1 ==> integer format
00034 c ndec = 0 ==> log axes, want to plot 10^n
00035 c ndec > 0: number of places to right of decimal point
00036 c lpow = 0 ==> F format, E format (lpow = exponent) otherwise
00037 c
00038 c No numbers are drawn for nonzero lmode, regardless of ilab.
00039 c N.B. Variable "ilab" is redundant, now.
00040 c
00041 character*80 device
00042 common/plot device/device,aspect,idev
00043 common/scales/xl,xr,dinchx,ybot,ytop,dinchy,rlen,slen
00044 common/dev status/idevon,idevpen,idevwt
00045 common/fr hts/htl,htn/fr wts/iwts(4)/fr rotn/irot
00046 common/fr ticks/tiks(3),tikl/fr int/iframe
00047 common/fr conf/scent,rnuml,rnumr,snumt,snumb,dsnums,jrot,stopnum
00048 common/fr tik level/jtik level
00049 common/fr bare/ibare
00050 common/fontc1/dum2(5),rrmax,rrmin,ssmax,ssmin
00051 common/fr setax/kax,lax
00052 c
00053 dimension dy(3)
00054 character*80 string
00055 c
00056 common/fr lby/lmode
00057 data mode/1/
00058 c
00059 cinch(xa,xs,di) = (xa-xs)*di
00060 c
00061 if (lax.lt.0) return
00062 c
00063 c Draw axes.
00064 c ---------
00065 c
00066 dy(1) = dys
00067 dy(2) = dym
00068 dy(3) = dyl
00069 rax = cinch(x,xl,dinchx)
00070 s1 = cinch(y1,ybot,dinchy)
00071 s2 = cinch(y2,ybot,dinchy)
00072 if (iwts(1).gt.0) then
00073 jwt = idevwt
00074 call weight(iwts(1))
00075 end if
00076 call plot(rax,s1,3)
00077 call plot(rax,s2,2)
00078 c
00079 if (lax.eq.1.and.iax.eq.2) return
00080 if (lax.eq.2.and.iax.eq.1) return
00081 c
00082 c Draw tick marks.
00083 c ---------------
00084 c
00085 dr = 1.
00086 if (iax.eq.2) dr = -1.
00087 do j = jtik level,3
00088 if (dy(j).ne.0.) then
00089 rtik = rax+dr*tiks(j)
00090 call fr lnfnc(y1,y2,dy(j),mode,firsty,ny)
00091 ds = dy(j)*dinchy
00092 s = cinch(firsty,ybot,dinchy)
00093 do i = 1,ny
00094 call plot(rax,s,3)
00095 call plot(rtik,s,2)
00096 s = s+ds
00097 end do
00098 end if
00099 end do
00100 if (iwts(1).gt.0) call weight(jwt)
00101 jrot = irot
00102 c
00103 if (lmode.ne.0) return
00104 if (lax.eq.0.and.iax.eq.2) return
00105 if (lax.eq.3.and.iax.eq.1) return
00106 c
00107 c Add numeric labels.
00108 c ------------------
00109 c
00110 yscale = max(abs(y1),abs(y2))
00111 c
00112 c Labels are horizontal (left to right) if jrot = 0, horizontal otherwise.
00113 c
00114 dsnums = ds
00115 c
00116 c Get the actual length of the numbers for use below.
00117 c
00118 c Definitions: the maximum width of the numeric labels is xlnum
00119 c the maximum height of the numeric labels is dsnum
00120 c
00121 if (ibare.eq.1) then
00122 c
00123 c A device-specific number-drawing routine will be used, so
00124 c pretty output is not expected. Just estimate the space
00125 c requirements.
00126 c
00127 if (ndec.ne.0) then
00128 nnum = 0
00129 if (firsty.lt.0.) nnum = 1
00130 if (ndec.gt.0) nnum = nnum+ndec
00131 mm = 0
00132 do k = 1,ny
00133 y = firsty+(k-1.)*dyl
00134 if (abs(y).lt.1.) then
00135 nn = 1
00136 else
00137 nn = log10(abs(y))+1
00138 end if
00139 if (nn.gt.mm) mm = nn
00140 end do
00141 nnum = nnum+mm
00142 xlnum = htn*(nnum+.5)
00143 else
00144 xlnum = 2.*htn
00145 mm = 0
00146 do k = 1,ny
00147 y = firsty+(k-1.)*dyl
00148 nn = 0
00149 if (y.lt.0.) nn = 1
00150 if (abs(y).ge.1.) nn = nn+1+log10(abs(y))
00151 mm = max(mm,nn)
00152 end do
00153 xlnum = xlnum+.5333*mm*htn
00154 end if
00155 else
00156 c
00157 c Simbol will be used, so we can determine the sizes exactly.
00158 c
00159 xlnum = 0.
00160 do k=1,ny
00161 y = firsty + (k-1.)*dyl
00162 call make_number_string(y,ndec,lpow,string,nsym,yscale)
00163 call sim size(htn,string,nsym,dx,dum)
00164 xlnum = max(xlnum, dx)
00165 end do
00166 if (idev.eq.7.or.idev.eq.8) xlnum = 1.1*xlnum
00167 c
00168 c Modify xlnum in case of extra labels in the logarithmic case:
00169 c
00170 if (ndec.eq.0.and.nx.le.3) xlnum = 2.*xlnum
00171 end if
00172 c
00173 c Nominal symbol height:
00174 c
00175 dsnum = 1.5*htn
00176 if (jrot.ne.0) dsnum = 1.3*xlnum
00177 c
00178 c Check that the number size is OK.
00179 c
00180 100 if (dsnum.gt.ds) then
00181 c
00182 c Label is too tall.
00183 c
00184 fac = ds/dsnum
00185 if (jrot.ne.0.and.fac.lt..4) then
00186 jrot = 0
00187 dsnum = 1.5*htn
00188 go to 100
00189 end if
00190 htn = htn*fac
00191 xlnum = xlnum*fac
00192 dsnum = ds
00193 end if
00194 c
00195 if (iax.eq.1) then
00196 call getlhe(space)
00197 space = -space - htl
00198 else
00199 call getrhe(space)
00200 space = space - x - htl
00201 end if
00202 c
00203 if (space.gt.0.and.jrot.eq.0.and.xlnum.gt..9*space) then
00204 c
00205 c Too wide...
00206 c
00207 htn = htn*.9*space/xlnum
00208 xlnum = .9*space
00209 end if
00210 c
00211 c See if the first label should be moved up.
00212 c -----------------------------------------
00213 c
00214 c (There is a lot of repeated code here--there is probably a much
00215 c better way of writing this.)
00216 c
00217 y = firsty
00218 s1 = cinch(firsty,ybot,dinchy)
00219 half = .5*htn
00220 strlen = xlnum
00221 strlen2 = .5*strlen
00222 c
00223 call pushstr
00224 if (jrot.eq.0) then
00225 if (iax.eq.1) then
00226 call strpos(1.,.5)
00227 else
00228 call strpos(0.,.5)
00229 end if
00230 else
00231 if (iax.eq.1) then
00232 call strpos(.5,0.)
00233 else
00234 call strpos(.5,1.)
00235 end if
00236 end if
00237 c
00238 if (jrot.eq.0) then
00239 th = 0.
00240 if (iax.eq.1) then
00241 r = rax-half
00242 else
00243 r = rax+half
00244 end if
00245 else
00246 th = 90.
00247 if (iax.eq.1) then
00248 r = rax-htn
00249 else
00250 r = rax+htn
00251 end if
00252 end if
00253 s = s1
00254 c
00255 smin = half ! Only offset the first y-axis
00256 if (th.eq.90.) smin = strlen2 ! label if it really would
00257 if (s1.lt.smin) s = s+smin ! extend below the x-axis.
00258 c
00259 c Reference point for first number is (r, s).
00260 c
00261 if (iwts(2).gt.0) then
00262 jwt = idevwt
00263 call weight(iwts(2))
00264 end if
00265 c
00266 if (iax.eq.2) th = -th
00267 c
00268 c Draw the number and initialize bookkeeping.
00269 c
00270 if (ibare.eq.1) then
00271 if (ndec.eq.0) then
00272 call lognum(r,s,htn,y,th,-1)
00273 rnummin = r
00274 else
00275 call fr numbr(r,s,htn,y,th,ndec)
00276 rnummin = rrmin
00277 end if
00278 else
00279 call make_number_string(y,ndec,lpow,string,nsym,yscale)
00280 call simbol(r,s,htn,string,th,nsym)
00281 end if
00282 c
00283 rnummax = rnummin + xlnum
00284 c
00285 snumb = 0.
00286 snumt = slen
00287 rnuml = 0.
00288 rnumr = 0.
00289 inumset = 0
00290 c
00291 if (jrot.eq.0) then
00292 sref = s - half
00293 else
00294 sref = s - strlen2
00295 end if
00296 c
00297 c sref is the level of the bottom of the current numerical label.
00298 c
00299 dstrue = ds
00300 if (ndec.eq.0.and.ny.le.3.and.abs(dyl-1.).lt..01) then
00301 c
00302 c In this case, we must take into account the fact that
00303 c intermediate numbers are being inserted, and that the bottom
00304 c label could be above the centerline...
00305 c
00306 dstrue = .5*ds
00307 isign = 1
00308 if (sref.gt.scent) isign = -1
00309 end if
00310 c
00311 if ( (sref-scent) * (sref+isign*dstrue-scent) .le. 0. ) then
00312 c
00313 c This number and the next straddle the centerline.
00314 c The vertical whitespace for the label lies between snumb
00315 c and snumt. The y-label will be centered there.
00316 c
00317 inumset = 1
00318 c
00319 snumt = sref+dstrue
00320 c
00321 if (jrot.ne.0) then
00322 rnuml = r-htn
00323 rnumr = r
00324 snumb = s+strlen2
00325 else
00326 rnuml = r-strlen
00327 rnumr = r
00328 if (ndec.eq.0) then
00329 snumb = sref+1.2*htn
00330 else
00331 snumb = sref+htn
00332 end if
00333 end if
00334 end if
00335 c
00336 c Draw the remaining numbers.
00337 c --------------------------
00338 c
00339 c Undo any offset:
00340 c
00341 if (s1.lt.smin) s = s-smin
00342 c
00343 do i = 2,ny
00344 s = s+ds
00345 y = y+dyl
00346 c
00347 if (ibare.eq.1) then
00348 if (ndec.eq.0) then
00349 call lognum(r,s,htn,y,th,-1)
00350 rnummin = min(rnummin,r)
00351 rnummax = max(rnummax,r+strlen)
00352 else
00353 call fr numbr(r,s,htn,y,th,ndec)
00354 rnummin = min(rnummin,rrmin)
00355 rnummax = max(rnummax,rrmax)
00356 end if
00357 else
00358 call make_number_string(y,ndec,lpow,string,nsym,yscale)
00359 call simbol(r,s,htn,string,th,nsym)
00360 c
00361 c Still have to deal with intermediates...
00362 c
00363 if (ndec.eq.0.and.ny.le.3.and.abs(dyl-1.).lt..01) then
00364 s3 = s-.5229*ds
00365 if (s3.ge.s1) then
00366 call format_string(10.**(y-.5*dyl),-1,
00367 $ string,nsym,1)
00368 call simbol(r,s3,htn,string,th,nsym)
00369 end if
00370 c
00371 if (i.eq.2) then
00372 s3 = s-1.5229*ds
00373 if (s3.ge.s1) then
00374 call format_string(10.**(y-1.5*dyl),-1,
00375 $ string,nsym,1)
00376 call simbol(r,s3,htn,string,th,nsym)
00377 end if
00378 end if
00379 c
00380 if (i.eq.ny) then
00381 s3 = s+.4771*ds
00382 if (s3.le.s2) then
00383 call format_string(10.**(y+.5*dyl),-1,
00384 $ string,nsym,1)
00385 call simbol(r,s3,htn,string,th,nsym)
00386 end if
00387 end if
00388 end if
00389 c
00390 rnummin = min(rnummin,rrmin)
00391 rnummax = max(rnummax,rrmax)
00392 end if
00393 c
00394 c Bookeeping (same as before):
00395 c
00396 if (inumset.eq.0) then
00397 if (jrot.eq.0) then
00398 sref = s - half
00399 else
00400 sref = s - strlen2
00401 end if
00402 c
00403 if (sref.le.scent.and.sref+dstrue.gt.scent) then
00404 inumset = 1
00405 c
00406 snumt = sref+dstrue
00407 c
00408 if (jrot.ne.0) then
00409 rnuml = r-htn
00410 rnumr = r
00411 snumb = s+strlen2
00412 else
00413 rnuml = r-strlen
00414 rnumr = r
00415 snumb = sref+htn
00416 c
00417 c Old version:
00418 c
00419 c if (ndec.eq.0) then
00420 c snumb = sref+1.2*htn
00421 c else
00422 c snumb = sref+htn
00423 c end if
00424 c
00425 end if
00426 end if
00427 end if
00428 end do
00429 c
00430 c Restore settings.
00431 c
00432 if (iwts(2).gt.0) call weight(jwt)
00433 iframe = 1
00434 call popstr
00435 c
00436 rnuml = rnummin
00437 rnumr = max(rnummax,rnuml+htn*jrot+strlen*(1-jrot))
00438 c
00439 snumb = max(0.,snumb)
00440 snumt = min(slen,snumt)
00441 stopnum = s
00442 c
00443 c Force the label to be above the centerline.
00444 c
00445 if (.5*(snumb+snumt).lt.scent) then
00446 snumb = snumb + dstrue
00447 snumt = snumt + dstrue
00448 end if
00449 c
00450 end
00451
00452
00453 subroutine make_number_string(y,ndec,lpow,string,nsym,yscale)
00454 character*(*) string
00455 common /fr plain/ iplain
00456 c
00457 parameter (TOL = 1.e-6)
00458 c
00459 if (lpow.eq.0.or.(ndec.ne.0.and.abs(y)/yscale.lt.TOL)) then
00460 call numsym(y,ndec,string,nsym)
00461 if (iplain.eq.1) call convert_to_plain(string, nsym)
00462 else
00463 if (ndec.eq.0) then
00464 call format_string(10.**y,ndec,string,nsym,0)
00465 else
00466 call exp_string(y,ndec,string,nsym,1)
00467 end if
00468 end if
00469 c
00470 end