--- title: "3D Bar Graph" id: 57147 type: "computer_media" slug: "3d-bar-graph" url: "http://localhost/computer_media/3d-bar-graph/" markdown_url: "http://localhost/computer_media/3d-bar-graph.md" published_at: "2024-10-04T00:51:03+00:00" modified_at: "2026-03-30T21:19:29+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/96_Bar.png" excerpt: "Enter your data values and watch this program render a labelled bar chart complete with diagonal tops, axis lines, and centred title — all using PLOT and UNPLOT." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Graphics" slug: "graphics" taxonomy: "genre" url: "http://localhost/type/graphics/" media_contents: - id: 56733 title: "Timex Sinclair Public Domain Library Tape 1002" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1002/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/96_Bar.png" media_type_tags: "Graphics, Software" --- # 3D Bar Graph This program draws a bar chart on screen based on user-supplied data values. The user inputs the number of items, each item’s numeric value, and a chart label; the program then renders vertical bars using PLOT and UNPLOT commands, with each bar topped by a diagonal step effect drawn in a FOR X=1 TO 4 loop. Numeric values are printed beneath each bar as two-character strings using STR$ with space-padding for single-digit numbers. The chart label is centred on the top row using INT((32-LEN L$)/2). Bar geometry is computed from array A() with column positions spaced six pixels apart via the P1/P2/P3 assignments. *** ## Program Analysis ### Program Structure The program is divided into two logical sections separated by a subroutine boundary: 1. **Data input (lines 100–112):** Prompts for item count, fills array `A(N)`, collects a label string `L$`, clears the screen, and returns. 2. **Drawing loop (lines 10–60):** Iterates over each item, computing pixel column positions and drawing bar outlines, fills, diagonal caps, and numeric labels. Execution begins at line 1 with `GOSUB 100`, so input is collected before any drawing takes place. After drawing, line 70 busy-waits for any keypress before halting (or re-running via line 201’s `GOTO 1`, which also immediately follows the `SAVE` at line 200). ### Bar Geometry For each bar `Y`, three column anchors are precomputed: | Variable | Formula | Role | | --- | --- | --- | | `P1` | `Y*6-6` | Left edge of bar | | `P2` | `Y*6-2` | Right edge of bar (P1+4) | | `P3` | `Y*6+2` | Right edge of diagonal cap (P2+4) | Each bar is therefore 4 pixels wide with a 4-pixel diagonal cap offset to the right, and bars are spaced 6 pixels apart. This allows up to approximately 10 bars before the rightmost bar exceeds the 64-pixel display width. ### Drawing Techniques Three separate loops handle different parts of each bar: - **Lines 30–35:** Vertical fill — plots the left, right, and right-cap columns pixel by pixel from 1 to `A(Y)`. `UNPLOT` calls on `P1+1` and `P1+2` create a hollow interior effect by erasing interior pixels. - **Lines 40–44:** Horizontal base and top lines — plots the bottom row at Y=1, the top row at Y=`A(Y)`, and the offset top row at Y=`A(Y)+4` for the cap. - **Lines 50–55:** Diagonal cap — draws a 4-pixel staircase from the top of the main bar to the top of the cap column, with an `UNPLOT` on the inner diagonal pixel when `X>1` to keep the outline clean. ### Numeric Label Formatting Lines 56–58 handle printing the bar height beneath each bar. `STR$ A(Y)` converts the numeric value to a string. If the value is less than 10 (single digit), a leading space is prepended so the label always occupies exactly two characters. These two characters are then printed across two rows using `PRINT AT 19` and `AT 20`, positioned at column `Y*3-2`. ### Key BASIC Idioms - **Centred title:**`INT((32-LEN L$)/2)` is a standard idiom for horizontally centring a string on a 32-column display, used at both lines 61 and 111. - **Busy-wait for keypress:** Line 70 loops on `INKEY$=""` until any key is pressed, a common pattern for pause-before-exit. - **AT-based screen clearing:** Line 102 prints a blank-padded string at the prompt row rather than issuing a full `CLS`, preserving screen content above. - **DIM after INPUT:**`DIM A(N)` at line 103 uses the just-entered value of `N` to size the array dynamically. ### Potential Issues and Anomalies - The `UNPLOT P1+2,Z` on line 31 erases a pixel that was never plotted (only `P1` and `P2=P1+4` are drawn in that loop), so it has no visible effect unless a previous bar happened to occupy that column — this appears to be a minor logic error or leftover from an earlier version. - With bars spaced 6 pixels apart and starting at column 0, bar `Y=11` would place `P2` at pixel column 62, which is still within the 64-pixel width, but taller bars may overwrite the label row at line 19/20 if `A(Y)` approaches the display height (44 pixels on a ZX81). - The two-character label split (`N$(1)` and `N$(2)`) assumes values up to 99; values of 100 or more would produce a three-character `STR$` result, but the code only prints two characters — truncating the tens digit silently. - Line 201 (`GOTO 1`) is only reachable after `SAVE` at line 200, making it effectively a post-save restart rather than part of the normal run path. ## Source Code ``` 1 GOSUB 100 10 FOR Y=1 TO N 11 LET P1=Y*6-6 12 LET P2=Y*6-2 13 LET P3=Y*6+2 20 FOR Z=1 TO A(Y) 30 PLOT P1,Z 31 UNPLOT P1+2,Z 32 PLOT P2,Z 33 PLOT P3,Z+4 34 UNPLOT P1+1,Z 35 NEXT Z 40 FOR X=P1 TO P2 41 PLOT X,1 42 PLOT X,A(Y) 43 PLOT X+4,A(Y)+4 44 NEXT X 50 FOR X=1 TO 4 51 PLOT P1+X-1,A(Y)+X-1 52 PLOT P2+X-1,A(Y)+X-1 53 PLOT P2+X-1,X 54 IF X>1 THEN UNPLOT P1+X,A(Y)+X-1 55 NEXT X 56 LET N$=STR$ A(Y) 57 IF A(Y)<10 THEN LET N$=" "+N$ 58 PRINT AT 19,Y*3-2;N$(1);AT 20,Y*3-2;N$(2) 60 NEXT Y 61 PRINT AT 0,INT ((32-LEN L$)/2);L$ 70 IF INKEY$="" THEN GOTO 70 100 PRINT AT 21,0;"HOW MANY ITEMS?" 101 INPUT N 102 PRINT AT 21,0;"ITEM: " 103 DIM A(N) 104 FOR X=1 TO N 105 PRINT AT 21,5;X 106 INPUT A(X) 107 NEXT X 108 PRINT AT 21,0;"LABEL?" 109 INPUT L$ 110 CLS 111 PRINT AT 0,INT ((32-LEN L$)/2);L$ 112 RETURN 200 SAVE "1009%6" 201 GOTO 1 ```