321 lines
9.0 KiB
QBasic
321 lines
9.0 KiB
QBasic
|
REM THIS IS A DEMONSTRATION PROGRAM FOR DRAWING
|
|||
|
REM PIE AND BAR CHARTS.
|
|||
|
REM
|
|||
|
REM PROGRAM NAME: GRAPHR.BAS
|
|||
|
REM
|
|||
|
%INCLUDE GRAPHCOM.BAS
|
|||
|
GRAPHIC OPEN 1
|
|||
|
CLEAR
|
|||
|
|
|||
|
REM If the device supports color fill, MAT FILL
|
|||
|
REM statements are used. Otherwise, MAT PLOT
|
|||
|
REM is used to draw figures.
|
|||
|
|
|||
|
IN.FL: INPUT "DOES THIS DEVICE SUPPORT COLOR FILL? Y/N: ";FILL.FLG$
|
|||
|
IF FILL.FLG$ = "Y" OR FILL.FLG$ = "N" THEN GOTO OK.FL
|
|||
|
PRINT "ENTER Y OR N, PLEASE"
|
|||
|
GOTO IN.FL
|
|||
|
OK.FL: PRINT "THANK-YOU"
|
|||
|
|
|||
|
REM Initialize the arrays used for drawing the
|
|||
|
REM slices in the pie chart. Two 100 element arrays
|
|||
|
REM are constructed for drawing a full circle. Each
|
|||
|
REM point in the arrays then represents one percent.
|
|||
|
|
|||
|
PRINT "CALCULATING OCCURRING --- PLEASE WAIT"
|
|||
|
DIM X.ARRAY(100)
|
|||
|
DIM Y.ARRAY(100)
|
|||
|
DIM A.ARRAY(72)
|
|||
|
DIM B.ARRAY(72)
|
|||
|
A.ARRAY(0) = .5
|
|||
|
B.ARRAY(0) = .5
|
|||
|
L.CIR = 0
|
|||
|
FOR I.ANGLE = 0 TO 6.28-.0628 STEP .0628
|
|||
|
X.ARRAY(L.CIR) = .5 + (.5 * COS(I.ANGLE))
|
|||
|
Y.ARRAY(L.CIR) = .5 + (.5 * SIN(I.ANGLE))
|
|||
|
L.CIR = L.CIR + 1
|
|||
|
NEXT I.ANGLE
|
|||
|
|
|||
|
REM Close the circle
|
|||
|
|
|||
|
X.ARRAY(L.CIR) = X.ARRAY(0)
|
|||
|
Y.ARRAY(L.CIR) = Y.ARRAY(0)
|
|||
|
GOTO START.IT
|
|||
|
|
|||
|
REM This function draws a slice beginning at the
|
|||
|
REM point represented by BEG.PER and extending
|
|||
|
REM through PER.CENT points. The color is set to
|
|||
|
REM COL.OR and the ASCII.ID prints as an identifier
|
|||
|
REM for the slice.
|
|||
|
|
|||
|
REM The function extracts the points from X.ARRAY
|
|||
|
REM and Y.ARRAY and places them in A.ARRAY and
|
|||
|
REM B.ARRAY. MAT FILL and MAT PLOT always begin
|
|||
|
REM drawing at the first elements of the arrays, so
|
|||
|
REM the slice must be extracted from the arrays.
|
|||
|
|
|||
|
REM The function makes provision for slices that
|
|||
|
REM exceed 71 points. MAT FILL and MAT PLOT allow
|
|||
|
REM a maximum element number of 72.
|
|||
|
|
|||
|
DEF DRAW.SLICE (BEG.PER,PER.CENT,COL.OR,ASCII.ID)
|
|||
|
REAL BEG.PER,PER.CENT,COL.OR
|
|||
|
STRING ASCII.ID
|
|||
|
L.CIR = 1
|
|||
|
SET COLOR COL.OR
|
|||
|
OVR.FLOW = 0
|
|||
|
|
|||
|
REM Setup for slices greater than 71 percent.
|
|||
|
|
|||
|
IF PER.CENT > 71 THEN SAVE.PER = 71:OVR.FLOW = 1\
|
|||
|
ELSE SAVE.PER = PER.CENT
|
|||
|
|
|||
|
REM Extract points from circle array.
|
|||
|
|
|||
|
BAK.UP: FOR CNT.ER = BEG.PER TO BEG.PER + SAVE.PER
|
|||
|
IN.DEX = CNT.ER
|
|||
|
IF CNT.ER > 100 THEN IN.DEX = CNT.ER - 100
|
|||
|
A.ARRAY(L.CIR) = X.ARRAY(IN.DEX)
|
|||
|
B.ARRAY(L.CIR) = Y.ARRAY(IN.DEX)
|
|||
|
L.CIR = L.CIR + 1
|
|||
|
NEXT CNT.ER
|
|||
|
|
|||
|
REM OVER.FLOW is 1 for a more than 71 percent slice.
|
|||
|
|
|||
|
IF OVR.FLOW <> 1 THEN GOTO OVER.A
|
|||
|
|
|||
|
REM FILL.FLG$ is "N" for non-color-fill devices.
|
|||
|
|
|||
|
IF FILL.FLG$ = "N" THEN MAT PLOT L.CIR-1: A.ARRAY,B.ARRAY\
|
|||
|
ELSE MAT FILL L.CIR-1: A.ARRAY,B.ARRAY
|
|||
|
OVR.FLOW = 0
|
|||
|
BEG.PER = BEG.PER + 71
|
|||
|
SAVE.PER = PER.CENT - 71
|
|||
|
IF FILL.FLG$ = "N" THEN L.CIR = 0 ELSE L.CIR = 1
|
|||
|
GOTO BAK.UP
|
|||
|
OVER.A: A.ARRAY(0) = .5
|
|||
|
B.ARRAY(0) = .5
|
|||
|
|
|||
|
REM The slice must be closed for MAT PLOT. MAT FILL
|
|||
|
REM closes automatically.
|
|||
|
|
|||
|
IF FILL.FLG$ = "N" THEN\
|
|||
|
A.ARRAY(L.CIR) = .5: \
|
|||
|
B.ARRAY(L.CIR) = .5: \
|
|||
|
MAT PLOT L.CIR: A.ARRAY,B.ARRAY \
|
|||
|
ELSE \
|
|||
|
MAT FILL L.CIR-1: A.ARRAY,B.ARRAY
|
|||
|
|
|||
|
REM Expand the viewport for printing the slice ID.
|
|||
|
REM The minimum character height is used to adjust
|
|||
|
REM the window so the slice ID will appear outside
|
|||
|
REM the slice perimeter.
|
|||
|
|
|||
|
SET VIEWPORT 1.0-Y.AXIS,1,0,1
|
|||
|
ADJ.IT = MIN.HGT/1.45
|
|||
|
SET WINDOW -ADJ.IT,1+ADJ.IT,-ADJ.IT,1+ADJ.IT
|
|||
|
|
|||
|
REM MID.PT is the center elements in the slice. This
|
|||
|
REM is the position where the ID is printed.
|
|||
|
|
|||
|
MID.PT = INT(BEG.PER+(PER.CENT/2))
|
|||
|
X.AXIS = X.ARRAY(MID.PT)
|
|||
|
Y.AXIS = Y.ARRAY(MID.PT)
|
|||
|
GRAPHIC PRINT AT (X.AXIS,Y.AXIS): ASCII.ID
|
|||
|
SET WINDOW 0,1,0,1
|
|||
|
RETURN
|
|||
|
FEND
|
|||
|
|
|||
|
REM The first portion of the program allows entry
|
|||
|
REM of up to 9 slices. Enter the item number (1-9)
|
|||
|
REM and press the return key. Then type the slice
|
|||
|
REM description (up to 6 characters), the dollar
|
|||
|
REM value of the slice, and the color code for
|
|||
|
REM the slice.
|
|||
|
|
|||
|
REM The following entries are a good sample:
|
|||
|
|
|||
|
REM 1 <return>
|
|||
|
REM RENT,550,1 <return>
|
|||
|
REM 2 <return>
|
|||
|
REM FOOD,450,2 <return>
|
|||
|
REM 3 <return>
|
|||
|
REM CAR,225,3 <return>
|
|||
|
REM 4 <return>
|
|||
|
REM OTHER,750,4 <return>
|
|||
|
|
|||
|
REM This sets up a graph of four items--rent of
|
|||
|
REM $550 in color 1, food for $450 in color 2, etc.
|
|||
|
|
|||
|
REM Terminate the input by typing 0 in response
|
|||
|
REM to the ITEM NUMBER(0 TO FINISH): prompt.
|
|||
|
|
|||
|
REM After the 0 entry, the program calculates the
|
|||
|
REM percentages and prints a listing of the entries.
|
|||
|
|
|||
|
REM Corrections may be made by entering the
|
|||
|
REM item number to be corrected and inputting
|
|||
|
REM the correct data.
|
|||
|
|
|||
|
START.IT: PRINT
|
|||
|
DIM ITM.DESC$(9)
|
|||
|
DIM ITM.VALUE(9)
|
|||
|
DIM ITM.COLOR(9)
|
|||
|
DIM ITM.PERC(9)
|
|||
|
GO.A: PRINT "ENTER AN ITEM NUMBER FROM 1 TO 9 TO ADD OR CHANGE"
|
|||
|
PRINT
|
|||
|
PRINT "THEN ENTER--DESCRIPTION,AMOUNT,COLOR,RETURN"
|
|||
|
PRINT
|
|||
|
PRINT " DESCRIPTION IS THE SLICE DESCRIPTION"
|
|||
|
PRINT " AMOUNT IS THE QUANTITY/AMOUNT OF THE SLICE"
|
|||
|
PRINT " COLOR IS THE COLOR NUMBER TO USE FOR THE SLICE"
|
|||
|
PRINT " RETURN MEANS TO PRESS THE RETURN KEY"
|
|||
|
PRINT
|
|||
|
PRINT "THE FIELDS ARE SEPARATED BY COMMAS"
|
|||
|
PRINT
|
|||
|
IN.IT: INPUT "ITEM NUMBER(0 TO FINISH): "; ITM.NUMBER%
|
|||
|
IF ITM.NUMBER% = 0 THEN GOTO PRT.EM
|
|||
|
IF ITM.NUMBER% > 0 AND ITM.NUMBER% < 10 THEN GOTO OKAY.IN
|
|||
|
PRINT "THE ITEM NUMBER MUST BE FROM 1 TO 9"
|
|||
|
GOTO IN.IT
|
|||
|
OKAY.IN: IF ITM.VALUE(ITM.NUMBER%) = 0 THEN GOTO NEW.IN
|
|||
|
PRINT ITM.DESC$(ITM.NUMBER%),ITM.VALUE(ITM.NUMBER%),
|
|||
|
PRINT ITM.COLOR(ITM.NUMBER%)
|
|||
|
NEW.IN: INPUT "DESC,AMOUNT,COLOR: ";DESC.IN$,VAL.IN,CLR.IN%
|
|||
|
ITM.DESC$(ITM.NUMBER%) = DESC.IN$
|
|||
|
ITM.VALUE(ITM.NUMBER%) = VAL.IN
|
|||
|
ITM.COLOR(ITM.NUMBER%) = CLR.IN%
|
|||
|
PRINT
|
|||
|
GOTO IN.IT
|
|||
|
PRT.EM: TOT.VAL = 0
|
|||
|
|
|||
|
REM Calculate the total for percentages.
|
|||
|
|
|||
|
FOR CNT.R = 1 TO 9
|
|||
|
TOT.VAL = TOT.VAL + ITM.VALUE(CNT.R)
|
|||
|
NEXT CNT.R
|
|||
|
PRINT
|
|||
|
|
|||
|
REM Print the item list with percentages.
|
|||
|
|
|||
|
FOR CNT.R = 1 TO 9
|
|||
|
IF ITM.VALUE(CNT.R) <> 0 THEN\
|
|||
|
ITM.PERC(CNT.R) = ITM.VALUE(CNT.R)/TOT.VAL:\
|
|||
|
ITM.PERC(CNT.R) = INT((100*ITM.PERC(CNT.R))+.5):\
|
|||
|
PRINT CNT.R;"-";ITM.DESC$(CNT.R),ITM.VALUE(CNT.R),:\
|
|||
|
PRINT ITM.COLOR(CNT.R);" ";ITM.PERC(CNT.R);"%"
|
|||
|
NEXT CNT.R
|
|||
|
PRINT:PRINT "TOTAL VALUE: ";TOT.VAL
|
|||
|
PRINT:INPUT "DRAW THE GRAPH? ";Y.N$
|
|||
|
IF Y.N$ <> "Y" THEN GOTO IN.IT
|
|||
|
CLEAR
|
|||
|
BEG.PER = 0
|
|||
|
|
|||
|
REM THE MINIMUM CHARACTER HEIGHT FOR THE DEVICE
|
|||
|
REM IS USED TO ESTABLISH A BORDER AROUND THE CIRCLE
|
|||
|
REM WHERE THE SLICE ID (THE ITEM NUMBER) CAN BE
|
|||
|
REM PRINTED.
|
|||
|
|
|||
|
SET CHARACTER HEIGHT 0
|
|||
|
ASK CHARACTER HEIGHT MIN.HGT
|
|||
|
MIN.HGT = 2 * MIN.HGT
|
|||
|
FOR CNT.R = 1 TO 9
|
|||
|
IF ITM.VALUE(CNT.R) = 0 THEN GOTO NXT.CNT
|
|||
|
|
|||
|
REM Determine the aspect ratio and square the device.
|
|||
|
REM A border is left around the viewport for the
|
|||
|
REM slice ID. The viewport is set to the right
|
|||
|
REM of the device.
|
|||
|
|
|||
|
ASK DEVICE X.AXIS,Y.AXIS
|
|||
|
SET VIEWPORT 1-Y.AXIS+MIN.HGT,1-MIN.HGT,MIN.HGT,1-MIN.HGT
|
|||
|
DESC.IN$ = ITM.DESC$(CNT.R)
|
|||
|
VAL.IN = ITM.VALUE(CNT.R)
|
|||
|
CLR.IN% = ITM.COLOR(CNT.R)
|
|||
|
PER.CENT = ITM.PERC(CNT.R)
|
|||
|
CALL DRAW.SLICE (BEG.PER,PER.CENT,CLR.IN%,STR$(CNT.R))
|
|||
|
BEG.PER = BEG.PER + PER.CENT
|
|||
|
SET VIEWPORT 0,1,0,1
|
|||
|
S.1$ = DESC.IN$+" "+STR$(PER.CENT)+"%"
|
|||
|
GRAPHIC PRINT AT (0,1-(CNT.R/10)):S.1$
|
|||
|
NXT.CNT: NEXT CNT.R
|
|||
|
|
|||
|
REM Is the graph filled? The percentage calculation
|
|||
|
REM can be less than 100 percent due to roundoff.
|
|||
|
|
|||
|
IF BEG.PER >= 100 THEN GOTO BAR.A
|
|||
|
PER.CENT = 100 - BEG.PER
|
|||
|
DESC.IN$ = " "
|
|||
|
ASK DEVICE X.AXIS,Y.AXIS
|
|||
|
SET VIEWPORT 1-Y.AXIS+MIN.HGT,1-MIN.HGT,MIN.HGT,1-MIN.HGT
|
|||
|
CALL DRAW.SLICE (BEG.PER,PER.CENT,CLR.IN%,DESC.IN$)
|
|||
|
|
|||
|
REM This routine draws a simple bar chart of the
|
|||
|
REM data. The window range is set to 1/3 greater
|
|||
|
REM than the largest item in the array. This
|
|||
|
REM technique makes the largest bar draw across
|
|||
|
REM 75% of the viewport.
|
|||
|
|
|||
|
BAR.A: KEY%=CONCHAR%
|
|||
|
DIM BAR.X(4)
|
|||
|
DIM BAR.Y(4)
|
|||
|
SET VIEWPORT 0,1,0,1
|
|||
|
SET WINDOW 0,1,0,1
|
|||
|
SET CHARACTER HEIGHT 0
|
|||
|
ASK CHARACTER HEIGHT MIN.HGT
|
|||
|
CLEAR
|
|||
|
SET JUSTIFY .5,0
|
|||
|
SET COLOR 1
|
|||
|
GRAPHIC PRINT AT (.5,.99-MIN.HGT):"BAR CHART"
|
|||
|
SET JUSTIFY 0,0
|
|||
|
MAX.VAL = 0
|
|||
|
|
|||
|
REM Determine the maximum percentage.
|
|||
|
|
|||
|
FOR CNT.R = 1 TO 9
|
|||
|
IF MAX.VAL < ITM.PERC(CNT.R) THEN\
|
|||
|
MAX.VAL = ITM.PERC(CNT.R)
|
|||
|
NEXT CNT.R
|
|||
|
MAX.VAL = 1.33 * MAX.VAL
|
|||
|
|
|||
|
REM Scale the window. The X axis is 1/3 larger
|
|||
|
REM than the largest item to be graphed.
|
|||
|
REM The Y axis is scaled to 10 lines.
|
|||
|
|
|||
|
SET WINDOW 0,MAX.VAL,0,10
|
|||
|
SET CHARACTER HEIGHT 0
|
|||
|
ASK CHARACTER HEIGHT MIN.HGT
|
|||
|
|
|||
|
REM Draw the items.
|
|||
|
|
|||
|
FOR CNT.R = 1 TO 9
|
|||
|
IF ITM.VALUE(CNT.R) = 0 THEN GOTO NXT.A
|
|||
|
SET COLOR ITM.COLOR(CNT.R)
|
|||
|
P.LINE = 10 - CNT.R
|
|||
|
S.1$ = ITM.DESC$(CNT.R)+"-"+STR$(ITM.PERC(CNT.R))+"%"
|
|||
|
IF ITM.VALUE(CNT.R) <> ITM.PERC(CNT.R) THEN\
|
|||
|
S.1$ = S.1$+" $"+STR$(ITM.VALUE(CNT.R))
|
|||
|
GRAPHIC PRINT AT (0,P.LINE): S.1$
|
|||
|
|
|||
|
REM Setup the BAR.X and BAR.Y arrays to draw the
|
|||
|
REM bar. MAX.VAL is the percentage for the item.
|
|||
|
REM The window scaling automatically scales the
|
|||
|
REM bar. No special calculations are required.
|
|||
|
|
|||
|
MAX.VAL = ITM.PERC(CNT.R)
|
|||
|
TOP = P.LINE - .1
|
|||
|
BOT = TOP - .4
|
|||
|
BAR.Y(0) = BOT
|
|||
|
BAR.Y(1) = TOP
|
|||
|
BAR.X(2) = MAX.VAL
|
|||
|
BAR.Y(2) = TOP
|
|||
|
BAR.X(3) = MAX.VAL
|
|||
|
BAR.Y(3) = BOT
|
|||
|
BAR.Y(4) = BOT
|
|||
|
IF FILL.FLG$ = "N" THEN MAT PLOT 4: BAR.X,BAR.Y\
|
|||
|
ELSE MAT FILL 3: BAR.X,BAR.Y
|
|||
|
NXT.A: NEXT CNT.R
|
|||
|
KEY% = CONCHAR%
|
|||
|
STOP
|
|||
|
END
|
|||
|
|