C
C
C
$STORAGE:2
C
C
C
C=======================================================================
C
C       These routine are from the PRO-350 library, and include
C       all necessary to create screen plots
C
C=======================================================================
C
C
C
      SUBROUTINE PLTSCR(UNIT,TITLE,TLEN,TATTR,SUBT1,SUBT2)
CC
CC
CC    Created on  :  June 16, 1987
CC    Last Updated:  July 29, 1987
CC    Written by  :  Bruce W. Roeckel
CC
CC    Description :  This routine will draw a bar chart, using the VT100
CC                   graphic character set.  The screen is cleared from
CC                   line six and the plot is drawn using the rest of the
CC                   screen space.  The cursor is left at 'home' after
CC                   everything is done.
CC
CC                   UNIT is the unit# of an opened file were the data
CC                   resides.  If an error occurs during processing,
CC                   this variable will be set to -99.  The format the
CC                   data in the file should be in is:
CC
CC                           Format of data is: F12,F12,1X,A1,A1
CC                                               ^   ^      ^  ^
CC                                               |   |      |  |
CC                                  Data Point 1 '   |      |  |
CC                                  Data Point 2 ----'      |  |
CC                                  Horiz Axis Char's ------'--'
CC
CC                   TITLE is a 40 character variable that defines the
CC                   plots title.
CC
CC                   TLEN is the number of characters that make up the
CC                   titles actual length passed.
CC
CC                   TATTR is a code indicating the character attributes
CC                   to use when drawing the title.
CC
CC
CC                                0 = Normal Characters
CC                                1 = inverse video
CC                                2 = bold
CC                                3 = blink
CC                                4 = inverse video, bold
CC                                5 = inverse video, blink
CC                                6 = bold, blink
CC                                7 = inverse video, bold, blink
CC
CC
CC                   SUBT1 is the subtitle, or description, of data point
CC                   number 1.  It is 8 characters max.
CC
CC                   SUBT2 is the subtitle, or description, of data point
CC                   number 2.  It is 8 characters max.
CC
CC
CC    Update #    Name       Date          Comments
CC    --------  ---------  --------  ----------------------------------
CC      001     Roeckel    07/29/87  Added Average Line to Plot
CC
CC
      IMPLICIT INTEGER (A-Z)

      CHARACTER*1 TLC,TRC,VLINE(80),BLNK(80)
      CHARACTER RELOC*11,FMT1*40,TITLE*40,SUBT1*8,SUBT2*8

      REAL PDATA(68),MIN,MAX,AVE,INC
      CHARACTER*1 H1(34),H2(34)
C
C         READ DATA FROM FILE, CHECK FOR ERROR CONDITION
C
      CALL PLTDAT(UNIT,PDATA,H1,H2,IDATA,MIN,MAX,AVE,INC,OLAY)
      IF(UNIT.LE.0) GOTO 900
C
C         ALL DATA READ IN O.K., SO GO AHEAD AND
C         MOVE LINE DRAWING CHARACTER SET INTO "G1", AND PRELOAD DATA
C
      LUN=0
      CALL GCHAR(LUN)

      DO 50 K=1,80
      BLNK(K)=' '
      VLINE(K)='q'
   50 CONTINUE
C
C         BASED ON HOW MUCH DATA WAS READ IN, FIQURE OUT HOW WIDE THE
C         BARS SHOULD BE, AS WELL AS HOW FAR APART FROM ONE ANOTHER
C
      IF(IDATA.GT.22) THEN
         IWIDE=1
         ISKIP=2
         ITICK=0
      ELSEIF(IDATA.GT.11) THEN
         IWIDE=2
         ISKIP=3
         ITICK=1
      ELSE
         IWIDE=3
         ISKIP=6
         ITICK=1
      ENDIF
C
C         LETS SHOW SOME SCREEN ACTIVITY AND DRAW GRAPH BOUNDARY
C
      HEIGHT=17
      WIDTH=72
      HORZ=6
      VERT=6
      BXATTR=0
      IF(TATTR.LT.0 .OR. TATTR.GT.7) THEN
         TATT2=10
      ELSE
         TATT2=TATTR+10
      ENDIF
      CALL BOLD
      CALL BOX(HEIGHT,WIDTH,HORZ,VERT,TITLE,TLEN,TATT2,BXATTR)
      CALL UPTOP(1,6)
C
C         ADD THE VERTICAL SCALE NUMBERS AND VERTICAL REFERENCE LINES
C
      I=INT(MIN)
      CALL GPHON(LUN)
      CALL BOLD

      DO 100 IV=20,8,-2
      CALL LOCATE(1,IV,RELOC)
      WRITE(*,'(A11,I4,1X,A1)') RELOC,I,117
      I = I + INT(INC*2.0)
  100 CONTINUE
      CALL OFF

      DO 150 IV=20,8,-2
      CALL LOCATE(7,IV,RELOC)
      WRITE(*,'(A11,70A1)') RELOC,(VLINE(L),L=1,70)
  150 CONTINUE

      IV=22-NINT(AVE)
      CALL LOCATE(7,IV,RELOC)
      CALL BOLD
      WRITE(*,'(A11,69A1,A3)') RELOC,(VLINE(L),L=1,69),'AVE'
      CALL OFF
      CALL GPHOFF(LUN)
C
C         BASED UPON HOW MUCH DATA WAS ENTERED AND HOW WIDE EACH BAR
C         WILL BE, CENTER THE GRAPH IN THE MIDDLE OF THE BOX.
C
      HORZ = 8 + ((68 - (ISKIP*IDATA))/2)
C
C         START DISPLAYING EACH DATA POINT ............................
C         THE FIRST 34 ENTRIES IN THE ARRAY 'PDATA' ARE THE OVERLAY
C         DATAPOINTS AND WILL BE DISPLAYED USING A HOLLOW BAR.
C         THE REMAINING 34 ENTRIES (35-68) ARE THE BASE POINTS
C         AND THEY WILL BE DISPLAYED AS A SOLID BAR.
C
C         IF OVERLAY DATA WAS FOUND, THEN DRAW THAT STUFF FIRST
C
      IF(OLAY.EQ.1) THEN

         IH=HORZ-1
         CALL BOLD
         CALL GPHON(LUN)
         WRITE(FMT1,'(A8,I2.2,A5)') '(A11,A1,',IWIDE,'X,A1)'

         DO 600 K=1,IDATA
         HEIGHT=NINT(PDATA(K))
         IF(HEIGHT.LE.0) THEN
            OLDTOP=0
            IH=IH+ISKIP
            GOTO 600
         ENDIF
         IV=22-HEIGHT
C
C          ... BASED UPON THE WIDTH AND SEPERATION OF EACH BAR,
C              DEFINE THE GRAPHICS CHARACTERS TO BE USED
C
         IF(ISKIP.LT.4 .AND. K.GT.1) THEN
            IF(NINT(PDATA(K-1)).EQ.NINT(PDATA(K))) THEN
               TLC='w'
            ELSEIF(NINT(PDATA(K-1)).GT.NINT(PDATA(K))) THEN
               TLC='t'
            ELSE
               TLC='l'
            ENDIF
         ELSE
            TLC='l'
         ENDIF

         IF(ISKIP.LT.4 .AND. K.LT.IDATA) THEN
            IF(NINT(PDATA(K+1)).EQ.NINT(PDATA(K))) THEN
               TRC='w'
            ELSEIF(NINT(PDATA(K+1)).GT.NINT(PDATA(K))) THEN
               TRC='u'
            ELSE
               TRC='k'
            ENDIF
         ELSE
            TRC='k'
         ENDIF
C
C          ... STARTING AT THE LEFT HAND CORNER, DRAW THE TOP
C
         CALL LOCATE(IH,IV,RELOC)
         WRITE(*,300) RELOC,TLC,(VLINE(L),L=1,IWIDE),TRC
  300    FORMAT(A11,80A1,$)
C
C          ... NOW START DOWN THE SIDES
C
         DO 400 I=1,HEIGHT-1
         CALL LOCATE(IH,IV+I,RELOC)
         IF(ISKIP.LT.4 .AND. K.GT.1) THEN
            IF(NINT(PDATA(K-1)).LT.NINT(PDATA(K))
     A      .AND. (IV+I).EQ.OLDTOP) THEN
               WRITE(*,FMT1) RELOC,'u','x'
            ELSE
               WRITE(*,FMT1) RELOC,'x','x'
            ENDIF
         ELSE
            WRITE(*,FMT1) RELOC,'x','x'
         ENDIF
  400    CONTINUE
C
C        .... AND FINALLY DRAW THE BOTTOM
C
         CALL LOCATE(IH,IV+HEIGHT,RELOC)
         WRITE(*,300) RELOC,'v',(VLINE(L),L=1,IWIDE),'v'

         OLDTOP=IV
         IH=IH+ISKIP
  600    CONTINUE

         CALL GPHOFF(LUN)
         CALL OFF

      ENDIF
C
C           NOW GO AHEAD AND DRAW THE SOLID BAR INFO
C
      CALL UPTOP(1,6)
      IV=0
      IH=HORZ
      WRITE(FMT1,'(A11,I2.2,A9)') '(A11,A1,A4,',IWIDE,'A1,A1,A2)'

      DO 750 K=35,IDATA+34
      HEIGHT=NINT(PDATA(K))
      IF(HEIGHT.LE.0) THEN
          IH=IH+ISKIP
          GOTO 750
      ENDIF
      IV=22-HEIGHT

         DO 700 I=1,HEIGHT
         CALL LOCATE(IH,IV+I-1,RELOC)
         WRITE(*,FMT1) RELOC,155,'1;7m',(BLNK(L),L=1,IWIDE),155,'0m'
  700    CONTINUE

      IH=IH+ISKIP
  750 CONTINUE
      CALL UPTOP(1,6)
C
C         NOW DRAW THE HORIZONTAL LABELS
C
      IH=HORZ+ITICK
      CALL GPHON(LUN)
      CALL BOLD

      DO 800 I=1,IDATA
      CALL LOCATE(IH,22,RELOC)
      WRITE(*,'(A11,A1)') RELOC,'w'
      IH=IH+ISKIP
  800 CONTINUE
      CALL GPHOFF(LUN)

      IH=HORZ+ITICK
      DO 850 I=1,IDATA
      CALL LOCATE(IH-1,23,RELOC)
      WRITE(*,'(A11,2A1)') RELOC,H1(I),H2(I)
      IH=IH+ISKIP
  850 CONTINUE
      CALL OFF
C
C          NOW DRAW THE REFERENCE KEY, USING THE POINT SUBTITLES.
C
      CALL PLTKEY(PDATA,IDATA,HORZ,OLAY,ISKIP,SUBT1,SUBT2)
      CALL UPTOP(1,6)

  900 CONTINUE
      RETURN
      END
C
C
C
      SUBROUTINE PLTKEY(PDATA,IDATA,FIRST,OLAY,SKIP,SUBT1,SUBT2)
CC
CC        Plotting Subroutine
CC
CC           This routine will locate a clear spot in the
CC           plot area and draw the reference 'key'
CC
CC
      IMPLICIT INTEGER (A-Z)
      REAL PDATA(68),PONE,PTWO
      CHARACTER TITLE*40,RELOC*11
      CHARACTER*8 SUBT1,SUBT2
C
C        FIND A 4X16 AREA OF THE PLOT TO DRAW THE KEY SO
C        AS NOT TO DISTURB ANY DATA
C
C        .... FIRST, LOAD VARIABLES BASED ON WERE FIRST BAR WAS PLOTTED
C
      I=1
      HORZ=8
      VERT=9
      LNUM=FIRST-8
C
C        .... IF THE BARS ARE LESS THEN HALF WAY UP THE SCALE
C             THEN WE COULD PLACE THE KEY ABOVE THEM
C
  100 CONTINUE
      PONE=PDATA(I)
      PTWO=PDATA(I+34)
      IF(OLAY.EQ.0) PONE=PTWO
      IF(PONE.LT.7.0 .AND. PTWO.LT.7.0) THEN
         IF(LNUM.LE.0) HORZ=FIRST + (I-1)*SKIP
         LNUM=LNUM+SKIP
         IF(LNUM.GE.16) GOTO 200
      ELSE
         LNUM=0
      ENDIF
      I=I+1
      IF(I.LE.IDATA) GOTO 100
C
C        .... IF WE HAVENT FOUND A SPOT AFTER SEARCHING ALL POINTS
C             THEN LETS FIND A SPOT TO DRAW OVER THE BARS
C
      I=1
      HORZ=8
      VERT=17
      LNUM=FIRST-8
C
C        .... IF THE DATA IS MORE THAN HALF WAY UP THE PLOT,
C             THEN WE CAN DRAW THE KEY OVER THE BOTTOM OF THE BARS
C
  150 CONTINUE
      PONE=PDATA(I)
      PTWO=PDATA(I+34)
      IF(OLAY.EQ.0) PONE=PTWO
      IF(PONE.GT.7.0 .AND. PTWO.GT.7.0) THEN
         IF(LNUM.LE.0) HORZ=FIRST + (I-1)*SKIP
         LNUM=LNUM+SKIP
         IF(LNUM.GE.16) GOTO 200
      ELSE
         LNUM=0
      ENDIF
      I=I+1
      IF(I.LE.IDATA) GOTO 150
C
C        IF WE FELL THROUGH TO THIS SPOT, THAT MEANS WE COULD NOT
C        FIND A GOOD PLACE.  DEFAULT TO THE LOWER RIGHT CORNER
C
       HORZ=60
       VERT=17
C
C        NOW DRAW THE BOX FOR THE KEY
C
  200 CONTINUE
      IF(HORZ.GT.60 .OR. HORZ.LT.8) HORZ=60
      IF(VERT.GT.17 .OR. VERT.LT.8) VERT=17
      HEIGHT=4
      WIDTH=16
      TITLE='Key'
      TLEN=5
      TATTR=2
      BATTR=0
      CALL BOLD
      CALL BOX(HEIGHT,WIDTH,HORZ,VERT,TITLE,TLEN,TATTR,BATTR)
C
C        CLEAR OUT THE CENTER OF THE BOX
C
      LUN=0
      CALL LOCATE(HORZ+1,VERT+1,RELOC)
      WRITE(LUN,'(A11,A14)') RELOC,'              '
      CALL LOCATE(HORZ+1,VERT+2,RELOC)
      WRITE(LUN,'(A11,A14)') RELOC,'              '
C
C       DRAW THE GRAPH SYMBOLS AND LABELS INSIDE THE BOX
C
      IF(OLAY.EQ.1) THEN
         CALL LOCATE(HORZ+2,VERT+1,RELOC)
         CALL BOLD
         CALL GPHON(LUN)
            WRITE(LUN,'(A11,A3,\)') RELOC,'lqk'
         CALL GPHOFF(LUN)
         CALL OFF
         CALL LOCATE(HORZ+6,VERT+1,RELOC)
         WRITE(LUN,'(A11,A8,\)') RELOC,SUBT1
      ENDIF

      CALL LOCATE(HORZ+3,VERT+2,RELOC)
      WRITE(LUN,500) RELOC,155,'1;7m',' ',155,'0m',SUBT2
  500 FORMAT(A11,A1,A4,A1,A1,A2,2X,A8,\)

      RETURN
      END
C
C
C
      SUBROUTINE PLTDAT(UNIT,PDATA,H1,H2,IDATA,MIN,MAX,AVE,INC,OLAY)
CC
CC         Ploting Subroutine
CC
CC            This routine reads in the data from the file and
CC            determines the minimum, maximum and average values.
CC            In addition, the scale increment is also calculated.
CC
CC            UNIT ---- Unit # of opened file
CC            PDATA --- Array (real, dim of 68) of data read in
CC            H1,H2 --- Horizontal Scale Labels (char*1, DIM 34)
CC            IDATA --- # of data points read in
CC            MIN ----- Minimum value of all data points
CC            MAX ----- Maximum value of all data points
CC            AVE ----- Average of all data points
CC            INC ----- Vertical Scale increment
CC            OLAY ---- Switch indicating if overlay data was found
CC
      IMPLICIT INTEGER (A-Z)
      CHARACTER*1 H1(34),H2(34)
      REAL PDATA(68),MIN,MAX,AVE,INC,TTL,VALINC(20)

      DATA VALINC/1.0,2.0,5.0,10.0,15.0,20.0,25.0,50.0,75.0,100.0,
     A            150.0,200.0,250.0,300.0,350.0,400.0,450.0,500.0,
     A            550.0,600.0/

C   *************************   START PROCESSING   ********************
C
C         READ IN DATA, ABORT IF ERROR OCCURS
C
      I=0
      OLAY=0
      REWIND UNIT
  100 CONTINUE
         I=I+1
         IF(I.GT.34) GOTO 200
         READ(UNIT,150,END=200,ERR=175) PDATA(I),PDATA(I+34),
     A                                  H1(I),H2(I)
  150    FORMAT(F12.0,F12.0,1X,A1,A1)
         IF(PDATA(I).GT.0.0) OLAY=1
      GOTO 100
C
C          IF READ ERROR OCCURS, RETURN WITH FLAG SET
C
  175 CONTINUE
      UNIT=-99
      GOTO 900
C
C         IF NO READ ERROR THEN CHECK FOR DATA BOUNDS, RETURN IF ERROR
C
  200 CONTINUE
      IDATA=I-1
      IF(IDATA.LE.0) THEN
         UNIT=-99
         GOTO 900
      ENDIF
C
C         FIND THE AVERAGE, MINIMUM AND MAXIMUM VALUES OF THE DATA
C
      TTL=0.0
      AVE=0.0
      MAX=0.0
      MIN=9999.0

      DO 300 I=1,IDATA
      TTL=TTL+PDATA(I)+PDATA(I+34)
      IF(PDATA(I).GT.MAX) MAX=PDATA(I)
      IF(PDATA(I+34).GT.MAX) MAX=PDATA(I+34)
      IF(PDATA(I).NE.0.0 .AND. PDATA(I).LT.MIN) MIN=PDATA(I)
      IF(PDATA(I+34).NE.0.0 .AND. PDATA(I+34).LT.MIN) MIN=PDATA(I+34)
  300 CONTINUE
      IF(OLAY.EQ.1) THEN
         AVE=TTL/REAL(IDATA*2)
      ELSE
         AVE=TTL/REAL(IDATA)
      ENDIF
C
C          CHECK FOR DATA VALIDITY
C
      IF((MAX.LE.0.0) .OR. (MIN.GE.9999.0)) THEN
         UNIT=-99
         GOTO 900
      ENDIF
C
C          CALCULATE THE VERTICAL INCREMENTS BY DIVIDING THE MAXIMUM VALUE
C          BY 12 (THE NUMBER OF AVAILABLE TICKS) AND THEN MOVING TO THE NEXT
C          HIGHEST WHOLE NUMBER (I.E. CHECK FOR REMAINDER) I KNOW THERE MUST
C          BE A SIMPLER WAY TO DO THIS, BUT THIS WORKS.
C
      INC = (MAX-MIN) / 12.0
      TTL = INC - INT(INC)
      IF(TTL.GT.0) THEN
         INC = INT(INC) + 1.0
      ELSE
         INC = INT(INC)
      ENDIF
C
C         FIND THE CLOSEST 'VALID' INCREMENT IN TABLE
C         IF VALID INCREMENTS ARE NOT BIG ENOUGH, CALCULATE ONE
C
      DO 400 I=1,20
      IF(INC.LE.VALINC(I)) THEN
         INC = VALINC(I)
         GOTO 500
      ENDIF
  400 CONTINUE

  450 CONTINUE
      IF(MAX.GT.(12.0*INC)) THEN
         INC = INC + 50.0
         GOTO 450
      ENDIF
C
C          SCALE DOWN THE DATA TO FIT THE BOUNDS OF THE SCREEN
C          SINCE I WILL MAKE THE MINIMUM VALUE BE THE FIRST
C          VERTICAL TICK MARK, ADD TWO TO ALL VALUES
C
  500 CONTINUE
      MAX=((MAX-MIN)/INC) + 2.0
      AVE=((AVE-MIN)/INC) + 2.0
C
      DO 600 J=1,IDATA
      IF(PDATA(J).GE.MIN) THEN
         PDATA(J) = ((PDATA(J)-MIN) / INC) + 2.0
      ELSE
         PDATA(J)=0.0
      ENDIF
      IF(PDATA(J+34).GE.MIN) THEN
         PDATA(J+34) = ((PDATA(J+34)-MIN) / INC) + 2.0
      ELSE
         PDATA(J+34)=0.0
      ENDIF
  600 CONTINUE
C
C        THAT ALL FOR NOW FOLKS !!!
C
  900 CONTINUE
      RETURN
      END
