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 REM RENT,550,1 REM 2 REM FOOD,450,2 REM 3 REM CAR,225,3 REM 4 REM OTHER,750,4 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