Pie Chart

Developer(s): Ryan Gray
Date: 1984
Type: Program
Platform(s): TS 2068

This program draws a pie chart on screen using BASIC combined with TASWIDE — a utility that switches the display to a 64-column wide text mode. The user inputs the number of slices, a percentage and label for each, and a flag to “pull” (offset) individual slices outward from the centre. Drawing uses PLOT and DRAW with the three-argument arc form (DRAW dx,dy,-angle) to render each sector. Labels are positioned using trigonometry to place them outside the circle, with a horizontal nudge applied for slices in the left half of the chart. The program also formats percentage output with conditional string concatenation to ensure consistent decimal display (e.g. appending “.00” or “0” as needed).


Program Structure

The program is organised into a linear sequence of phases:

  1. Lines 1–8: Header REMs, display initialisation, and a guard warning the user to load the TASWIDE machine-code utility before continuing.
  2. Lines 10–34: Data entry loop — number of slices, percentage, “pull” flag, and label for each slice; a running total is shown at line 21.
  3. Line 35: Rounds each percentage to two decimal places using INT(e(a)*100+.5)/100.
  4. Lines 43–46: Collects chart titles, then calls the TASWIDE routine and switches to 64-column mode via PRINT CHR$ 3.
  5. Lines 50–70: Main drawing loop — computes angles, places labels, and draws each pie sector.
  6. Lines 80–91: Prints the percentage legend and titles.
  7. Lines 100–130: Post-display menu: copy to printer (COPY), start a new graph (RUN), or loop.

Machine Code Usage

RANDOMIZE USR 64300 is called twice (lines 46 and 91). This invokes TASWIDE, a machine-code extension resident at address 64300 in RAM. The first call (line 46) presumably switches the display to 64-column mode; PRINT CHR$ 3 immediately after is a control code interpreted by TASWIDE. The second call (line 91) re-enters the 64-column mode, followed by PRINT CHR$ 2, likely switching back to 32-column mode for the main title at line 0. Without TASWIDE present, RANDOMIZE USR 64300 would crash or produce undefined behaviour — hence the prominent warning at lines 6–8.

Pie Sector Drawing

Each slice occupies an angular span A3 = PI/50 * E(A). This maps 100% to 2π (a full circle), since PI/50 × 100 = 2π. Each sector is drawn as two radial lines and an arc:

  • Line 60: PLOT to centre (optionally offset by the pull vector), DRAW the leading radius.
  • Line 61: PLOT to the same centre, DRAW the trailing radius.
  • Line 62: DRAW arc closing the sector using the three-argument DRAW dx,dy,-A3 form, where the third argument is the arc angle in radians (negative = clockwise).

The centre is at pixel coordinates (132, 83) and the radius is 50 pixels. Pulled slices are offset by 10 pixels along the midpoint angle vector using the AND trick: 10*g1 AND P(A) evaluates to 10*g1 if P(A) is non-zero, or 0 otherwise.

Label Positioning

Line 52 positions each label outside the circle using PRINT AT row,col computed from the midpoint angle A2:

  • Row: 11 - (60 + (10 AND P(A))) * g2 / 8 — scales the sine of the midpoint angle into character rows.
  • Column: 32 + (60 + (10 AND P(A))) * g1 / 4 - (9 AND a2 > PI/2 AND a2 < 3*PI/2) — the subtraction of 9 nudges labels in the left semicircle leftward, compensating for text extending rightward from the AT position.

The use of boolean expressions as numeric values (e.g. 9 AND condition) is a classic Spectrum BASIC idiom where a true condition yields the left operand and false yields 0.

Percentage Formatting

Line 80 uses conditional string concatenation to produce consistent decimal output:

  • " " AND e(a)<10 — prepends a space for single-digit values to align the legend.
  • ".00" AND e(a)=INT e(a) — appends .00 if the value is a whole number.
  • "0" AND e(a)*10=INT(e(a)*10) AND e(a)<>INT e(a) — appends a trailing 0 if there is exactly one decimal digit.

Notable Techniques and Idioms

TechniqueLocationPurpose
AND as conditional multiplierLines 52, 60, 61Applies pull offset only when P(A) is set
Three-argument DRAW (arc)Line 62Draws curved sector boundary
PAUSE 0 keypress waitLine 8Halts until any key is pressed
STR$ in INPUT promptLine 30Embeds the loop counter in the prompt string dynamically
RUN (no line number)Line 120Restarts from line 1 for a new graph, clearing variables

Content

Appears On

This tape is a compilation of programs from user group members (Robert Burton, David Baulch, Frank Bouldin, Chuck Dawson, Ryan

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    1 REM PIE CHART
    2 REM RESET  by Ryan Gray, 9/30/84;  ALL RIGHTS RESERVED
    5 PAPER 0: INK 7: BRIGHT 0: OVER 0: INVERSE 0: FLASH 0: BORDER 0: CLS 
    6 PRINT "CAUTION!  If TASWIDE is NOT               in memory at this               time, BREAK the                 program now and load            TASWIDE then re-RUN             PIE CHART"
    7 PRINT ''"Otherwise press any key..."
    8 PAUSE 0
   10 INPUT "# OF PIECES:";N
   11 IF N<2 THEN STOP 
   20 DIM E(N)
   21 DIM P(N): DIM l$(n,10)
   22 LET t=0: PRINT AT 21,16;"# OF PIECES:";n
   30 FOR A=1 TO N: INPUT "PERCENT FOR #";STR$ A;":";E(A)
   31 LET t=t+e(a): PRINT AT 21,0;"TOTAL:";t;"%   "
   32 INPUT "PULL PIECE? (1/0) ";P(A)
   33 INPUT "LABEL:";l$(a)
   34 NEXT a
   35 FOR a=1 TO n: LET e(a)=INT (e(a)*100+.5)/100: NEXT a
   43 PRINT AT 21,0;"                                "
   44 INPUT "MAIN TITLE:";T$: INPUT "SUB TITLE:";s$
   45 LET A1=0
   46 RANDOMIZE USR 64300: PRINT CHR$ 3;
   50 FOR A=1 TO N: LET A3=PI/50*E(A): LET A2=A1+A3/2
   51 LET g1=COS a2: LET g2=SIN a2: LET h1=COS a1: LET h2=SIN a1: LET i1=COS (a1+a3): LET i2=SIN (a1+a3)
   52 PRINT AT 11-(60+(10 AND P(A)))*g2/8,32+(60+(10 AND P(A)))*g1/4-(9 AND a2>PI/2 AND a2<3*PI/2);A;":";l$(a)
   60 PLOT 132+(10*g1 AND P(A)),83+(10*g2 AND P(A)): DRAW 50*h1,50*h2
   61 PLOT 132+(10*g1 AND P(A)),83+(10*g2 AND P(A)): DRAW 50*i1,50*i2
   62 DRAW 50*h1-50*i1,50*h2-50*i2,-A3
   65 LET A1=A1+A3
   66 REM 
   70 NEXT A
   80 FOR A=1 TO N: PRINT AT A+2,0;A;":";" " AND e(a)<10;E(A);".00" AND e(a)=INT e(a);"0" AND e(a)*10=INT (e(a)*10) AND e(a)<>INT e(a);"%": NEXT A
   90 PRINT AT 1,INT ((64-LEN s$)/2);s$
   91 RANDOMIZE USR 64300: PRINT CHR$ 2;AT 0,INT ((32-LEN T$)/2);T$
  100 INPUT "C to COPY, N for new graph:";n$
  110 IF n$="C" OR n$="c" THEN BEEP .01,0: COPY : BEEP .01,5: GO TO 100
  120 IF n$="N" OR n$="n" THEN RUN 
  130 GO TO 100

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top