.RIGHT MARGIN 80.LEFT MARGIN 2 .TITLE;##More Barcharts in DATATRIEVE-11 .SUBTITLE;##B.#Z.#Lederman ITT#World#Communications .PARAGRAPH My previous article showed how bargraphs could be generated with any version of DATATRIEVE, and on any CRT or printer. All of the previous bargraphs ran vertically: I will now do some bar graphs which run horizontally. .PARAGRAPH One other employee at my location developed his own method of printing bar charts by defining a table such as this: .BLANK.NO JUSTIFY.NO FILL DEFINE TABLE BAR-TAB USING BEGIN "0" | " ", "1" | "*", "2" | "**", "3" | "***", "4" | "****", "5" | "*****", "6" | "******", .BLANK.JUSTIFY.FILL and so on up to 100. Then the value to be graphed is printed via this table. It does work, and it allows two or more values to be concatenated, but it is not exactly the way I like to do things. Also, if the table is large, it will occupy a large amount of pool space when loaded. .PARAGRAPH To show my alternative method of generating horizontal bar charts, I will first define a record which has a field for a numerical value (which will be graphed) to be stored, and a group of characters which will form the actual bar. .BLANK.NO JUSTIFY.NO FILL .TEST PAGE 8 DEFINE RECORD H-STRING-REC 01 H-STRING-REC. 03 VALUE PIC 999. 03 STRING OCCURS 50 TIMES. 06 CHAR PIC X. ; DEFINE DOMAIN H-STRING USING H-STRING-REC ON HBAR.SEQ; .JUSTIFY.FILL.BLANK Now I will define another record which acts on the same file, only this time, the bar will be considered as a single field. .BLANK.NO JUSTIFY.NO FILL .TEST PAGE 7 DEFINE RECORD H-BAR-REC 01 H-BAR-REC. 03 VALUE PIC 999 EDIT-STRING ZZ9. 03 BAR PIC X(50) QUERY-HEADER " ". ; DEFINE DOMAIN H-BAR USING H-BAR-REC ON HBAR.SEQ; .JUSTIFY.FILL.BLANK Note that both domains work on the same file, and that while there are two record definitions, there is really only one record, and the data is the same in both domains: only the way we look at the data changes. .PARAGRAPH Just to make entering the data easier, I also defined a domain which contains data only. .BLANK.NO JUSTIFY.NO FILL .TEST PAGE 6 DEFINE RECORD DATA-REC 01 DATA-REC. 03 VALUE PIC 999 EDIT-STRING ZZ9. ; DEFINE DOMAIN DATA USING DATA-REC ON DATA.SEQ; .JUSTIFY.FILL .PARAGRAPH To create a graph, I first take the data from the domain where it is stored, and put it into the H-BAR domain. While doing so, I also insure that the bar portion is blank. The define file statement is a faster way to get an empty domain than to FIND and ERASE all of the data in an existing file, but be certain to purge out your old files periodically if you don't want the system manager mad at you for using up too much disk space. .BLANK.NO JUSTIFY.NO FILL .TEST PAGE 16 DEFINE PROCEDURE MAKE-H-BAR DEFINE FILE FOR H-BAR READY H-BAR WRITE READY DATA DECLARE BLANK PIC X(50). BLANK=" " ! blank spaces. FOR DATA STORE H-BAR USING BEGIN VALUE = VALUE ! Move in the value to be graphed. BAR = BLANK ! Put in a blank line. END ! ! Always clean up pool when done. ! RELEASE BLANK FINISH .JUSTIFY.FILL.BLANK Now I want to change the blank line into a bar graph. This is done with the other domain which allows looking at each character in the bar. The following procedure takes one record at a time from the domain. It then uses an inner list to move down one character of the string group at a time (which is the same as moving left to right in the bar), and compares the counter with the value to be graphed. If the position in the string is less than the value to be graphed, a character (in this case an asterisk) is moved into that position of the bar. The position in the bar is determined with a temporary variable TMP, which is increased by a fixed amount for each character in the bar. In this example, there are 50 characters in the bar, so the increment per character INC is the maximum value of the graph divided by 50. .BLANK.NO JUSTIFY.NO FILL .TEST PAGE 17 READY H-STRING MODIFY DECLARE INC PIC 999. DECLARE TMP PIC 999. INC = *."Maximum vale of graph" ! The maximum for the right-hand side INC = INC / 50 ! The size of each of the 50 steps. FOR H-STRING BEGIN TMP = INC ! Start at the first step FOR STRING MODIFY USING BEGIN ! Then move across the bar. IF TMP LE VALUE CHAR = "*" ! Put in printing character TMP = TMP + INC ! Increment to next position. END END RELEASE TMP RELEASE INC FINISH END-PROCEDURE .JUSTIFY.FILL.BLANK Believe it or not, that is all that is required. If the domain which accesses the data as a single bar is printed, the result is: .BLANK.NO JUSTIFY.NO FILL .TEST PAGE 17 READY H-BAR PRINT H-BAR VALUE 1 * 5 ***** 10 ********** 15 *************** 20 ******************** 30 ****************************** 35 *********************************** 37 ************************************* 40 **************************************** 49 ************************************************* 50 ************************************************** .JUSTIFY.FILL.PARAGRAPH All that is required now is to use a simple report to make data look a little nicer: .BLANK.NO JUSTIFY.NO FILL .TEST PAGE 8 READY H-BAR REPORT H-BAR ON HBAR.RPT SET COLUMNS-PAGE=80 SET REPORT-NAME="Horizontal Bar Graphs" PRINT COL 10, VALUE, SPACE 1, "|", SPACE 1, BAR END-REPORT END-PROCEDURE .JUSTIFY.FILL.BLANK The resulting report is: .NO JUSTIFY.NO FILL.BLANK .TEST PAGE 17 Horizontal Bar Graphs 14-May-83 Page 1 VALUE 1 | * 5 | ***** 10 | ********** 15 | *************** 20 | ******************** 30 | ****************************** 35 | *********************************** 37 | ************************************* 40 | **************************************** 49 | ************************************************* 50 | ************************************************** .JUSTIFY.FILL.BLANK Just as for any other report, commands may be added such as AT#TOP or AT#BOTTOM to make a scale print out, or print the MAX, MIN, TOTAL of fields, and so on, and the character used to print the bar may be changed for another which may look better on your particular device. For example, the following change to the procedure which creates the bars generates a record with a vertical bar every 10 spaces to draw in a scale on the graph. First, in the procedure MAKE-H-BAR change the constant BLANK from: .BLANK BLANK#=#"##################################################" .BLANK to .BLANK BLANK#=#"#########|#########|#########|#########|#########|" .BLANK which will fill the bar with the grid (a vertical line every 10 spaces. When the bar is filled in with the printing character (*), it will replace the bar where necessary. A modified report procedure which will print the corresponding grid in the final report is used. .BLANK.NO JUSTIFY.NO FILL.TEST PAGE 13 READY H-BAR REPORT H-BAR ON HBAR.RPT SET COLUMNS-PAGE=80 SET REPORT-NAME="Horizontal Bar Graphs" PRINT COL 10, VALUE, SPACE 1, "|" | BAR, SKIP, COL 14, "| | | | | |" AT BOTTOM OF REPORT PRINT COL 14, "0 10 20 30 40 50", SKIP 2, COL 1, "Maximum VALUE =", SPACE 1, MAX(VALUE), SPACE 1, ", Minimum VALUE =", SPACE 1, MIN(VALUE), SPACE 1, ", Average VALUE =", SPACE 1, AVERAGE(VALUE) END-REPORT .JUSTIFY.FILL.BLANK.TEST PAGE 29.NO JUSTIFY.NO FILL Horizontal Bar Graphs 23-Jun-83 Page 1 1 |* | | | | | | | | | | | 5 |***** | | | | | | | | | | | 10 |********** | | | | | | | | | | 15 |*************** | | | | | | | | | | 20 |******************** | | | | | | | | | 30 |****************************** | | | | | | | | 35 |*********************************** | | | | | | | | 37 |************************************* | | | | | | | | 40 |**************************************** | | | | | | | 49 |*************************************************| | | | | | | 50 |************************************************** | | | | | | 0 10 20 30 40 50 Maximum VALUE = 50 , Minimum VALUE = 1 , Average VALUE = 26 .BLANK.JUSTIFY.FILL Doubtless many other combinations are possible, such as printing the bar twice on successive lines to make it twice as high, or defining CHAR to be three characters wide, then filling it with a sequence of character-backspace-character to form a single symbol by over printing, and so on. Similarly, if the graph is to appear only on VT100 type CRT's, the escape sequence which puts the printer into graphics mode could be used so that the solid rectangle could be printed as a bar. .PARAGRAPH The primary advantage that horizontal bar graphs have over the vertical bar graphs of the previous article is the ease with which a large number of bars may be graphed. With vertical bar graphs, the record definition and all of the procedures must be changed if the number of bars to be graphed are increased, but with horizontal bar graphs, the procedures given here run until the domain with the data is exhausted.