JRT Pascal User's Guide NOT FOR SALE -177- E. JGRAF JGRAF is an external procedure which formats x-y graphs and scatter graphs. The graph size in rows and columns and the lower and upper x and y bounds are set by the user. A title to the graph may be provided. Once the graph has been prepared, it can be displayed on the console, printed or stored in a disk file. Any number of data points can be plotted. Any number of separate plots can be prepared simultaneously (within memory limitations). To use JGRAF, your program (or occasionally an external procedure) must declare the char9000 and jgraf_interface types. Your program must then declare one (or more) variable of type jgraf_interface. For convenience, the interface variable will be called jgi in this document. Your program could call the interface variable(s) anything appropriate. Your program must also declare JGRAF as an external procedure. The declarations for sample main program to take plotting commands from a disk file and create a plot is shown here. (The body of the sample program is listed later.) Everything listed here is required of any program using JGRAF except for the declarations noted as specific to jg. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -178- program jg; %ltrace %ptrace (* optional - suggested *) type char9000 = array [1..9000] of char; jgraf_interface = record command : char; (* R *) plot_char : char; (* R *) x_grid : boolean; (* R *) y_grid : boolean; (* R *) rows : integer; (* R *) columns : integer; (* R *) x_lower : real; (* R *) x_upper : real; (* R *) y_lower : real; (* R *) y_upper : real; (* R *) filename : array [1..14] of char; graf_title : string; (* R *) (* fields below used internally by jgraf *) b : ^char9000; bufr_size : integer; line_size : integer; row_count : integer; x_spacing : real; y_spacing : real; end; var jgi : jgraf_interface; (* following are used by program jg *) file_name : array[1..20] of char; title : array[1..24] of char; inf : file of char; x, y : real; command : char; (* end of variables used by sample program *) procedure jgraf ( var jg : jgraf_interface; x, y : real ); extern; (* end of declarations *) To produce graphs, your program must first set all members of jgi marked (* R *) in the jgraf_interface type declaration to appropriate values. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -179- Jgi.x_grid would be set to false if grid lines running across the graph should be omitted. Jg.y_grid is likewise set to false if grid lines running up and down are to be omitted. Jgi.rows and jgi.columns contain the number of lines and number of characters across the body of the plot itself (minus one). The number of rows and columns should normally be divisible by 10. Plot size can be calculated as (number of columns + 16) * (number of lines + 5), which should not exceed 9000 characters. The length of jgi.title should be less than the number of columns in the plot. Once all the requaired members of jgi are initialized, set jgi.command to 'I' and call JGRAF, as JGI.COMMAND := 'I'; JGRAF ( JGI, 0.0, 0.0 ); (Note that the examples listed here in upper case are for illustration only and are NOT part of the program jg.) Then, to place data points on the graph, set jgi.command to 'D' and call JGRAF for each of the appropriate points. Do this as often as needed. To get two distinct curves, you could set jgi.plot_char to '*' for one set of points, then set it to '#' before calling JGRAF with another set of points. JGI.COMMAND := 'D'; JGI.PLOT_CHAR := '*'; JGRAF ( JGI, 15.4, 199.2 ); JGRAF ( JGI, 15.9, 205.7 ); JGI.PLOT_CHAR := '#'; JGRAF ( JGI, 9.0, 105.0 ); To print the graph on the console, set jgi.command to 'C' and call JGRAF with x and y arguments zero, as JGI.COMMAND := 'C'; JGRAF ( JGI, 0.0, 0.0 ); If you want output to the line printer as well as to the console, set jgi.command to 'P' instead of 'C' before calling JGRAF. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -180- To write the graph to a file, set jgi.filename to the desired name, jgi.command to 'S', and call JGRAF. JGI.FILENAME := 'B:PLOT.5'; JGI.COMMAND := 'S'; JGRAF ( JGI, 0.0, 0.0 ); More data points can be added to a graph after printing, so that development or trends can be plotted in succession. Further, by setting jgi.plot_char to a space (' '), data points can be erased (although grid lines will not be restored). If you want to print more than one graph using the same interface record (jgi) or want JGRAF to free the memory allocated to produce a graph, you can set jgi.command to 'X' before calling JGRAF. This will free the buffers allocated by JGRAF (in the 'I' command). Note that every call to JGRAF that is not providing data (jgi.command = 'D') should have the x and y arguments equal to 0.0. The body of the sample program jg is included here, and illustrates one use of JGRAF. Jg takes a disk file of commands as input and produces one or more plots as directed. Commands on the disk file are similiar to the options to JGRAF, with the addition of two commands. T followed by 'title' may preceed the I command. Period (.) followed by a space and a new plot character will reset the current plot character. begin (* jg *) write('General graphing input file: '); readln(file_name); reset(inf,file_name, text, 512); jgi.title := ' '; while (not eof(inf)) do begin read(inf; command); command := upcase(command); writeln('db ',command); jgi.command := command; case command of 'T': begin readln (inf; title); jgi.title := title; end; Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -181- 'I': begin readln (inf; jgi.rows, jgi.columns, jgi.x_lower, jgi.x_upper, jgi.y_lower, jgi.y_upper); jgi.plot_char := '*'; jgi.x_grid := true; jgi.y_grid := true; (* note that all required members *) (* of jgi have been set *) jgraf(jgi, 0.0, 0.0); writeln(' done I'); end; 'D': begin read(inf; x, y); jgraf(jgi, x, y); end; '.': readln(inf; jgi.plot_char); 'C': jgraf(jgi, 0.0, 0.0); 'P': jgraf(jgi, 0.0, 0.0); 'S': begin readln(inf; file_name); jgi.filename := file_name; jgraf(jgi, 0.0, 0.0); end; 'X': jgraf(jgi, 0.0, 0.0); else: writeln('Unrecognized command: ',command); end; end; close(inf); end. Given the input file SAMPLE.DAT as follows: T 'Sample' I 20 40 0 40 0 60 D 5 6 D 6 10 D 7 12 D 8 15 D 9 16 D 10 16 . # D 5 2 D 32 6 D 32 27 C S sample.out X Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -182- Jg will produce the (uninspired) output file SAMPLE.OUT as follows, given the input listed above. JGRAF ver 3.0 **** Sample **** 60 -I---------I---------I---------I---------I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I 30 -I---------I---------I---------I---------I I I I I # I I I I I I I I I I I I I I I I I *** I I I I * I I I I I * I I I I I * I I I # I I # I I I I 0 -I---------I---------I---------I---------I 0 10 20 30 40 A summary of the commands to JGRAF is included now for reference: code meaning ---- ----------- C display graph on console D plot a data point I initialize graph buffer and axes P print graph S save graph on a disk file X delete graph buffer The source code for JGRAF is provided and may be modified. For example, the number of lines between the x_grid lines can be changed to 6 (or to 8) so that the grid lines form a one inch square on printers with 10 characters per inch and 6 (or 8) lines per inch. Copy compliments of Merle Schnick APPENDIX E: JGRAF JRT Pascal User's Guide NOT FOR SALE -183- JGRAF is not limited to scatter plots. With appropriate selection of data points, histograms can be produced. Contour plots (and even isometric drawings) are also possible. Copy compliments of Merle Schnick APPENDIX E: JGRAF  plots (and even isometric drawings) are also possible.