One of the most important characteristics of DATATRIEVE besides its productivity advantages over third generation languages, is its ability to be modified and extended to meet the needs of users. Kirk Searle of Digital made a presentation yesterday afternoon (Customizing VAX DATATRIEVE) on how VAX DATATRIEVE could be customized to change its apparent functionality by modifying its internal tables, lists, and domains. Larry Jasmann and Phil Naecker this morning in an impromptu, fill in session (Using the DATATRIEVE Call Interface) provided information on how to add apparent functionality by using the call interface. With the call interface, it is possible to add what appears to be new statements in the DATATRIEVE language. And this afternoon, Andy Schneider of Digital will show how the features and functionality of DATATRIEVE may be used in a distributed environment (DATATRIEVE Distributed Manipulation Facility). In addition, users may add new functions to DATATRIEVE with additions to the MACRO linkage file, DTR.FND, to user written and VAX library routines that Phil Naecker described. Perhaps more examples of this type will be given at the Wombat Magic session on Thursday evening. In none of these situation has the internal code of DATATRIEVE been changed as would be required if a completely new statement or command been added to DATATRIEVE such as a statement like
FIND C IN A UNION B
That is a whole new idea and would certainly require internal code to be written.
There is an area of DATATRIEVE where users can write new code in a somewhat PASCALlike language, which can add functionality which is fundamentally new to DATATRIEVE. I am, of course, referring to the internals of the DATATRIEVE plot library which is the topic of this presentation.
In the previous presentation (Using VAX DATATRIEVE Graphics), Kirk Searle described the use of the plot library from the outside. I wish to describe it from the inside and how one would go about adding to it and extending it. This talk is really in three parts. In order to be able to extend the library one has to understand its structure. The first part of the talk will be spent in looking at the structure of the plot library and how the pieces interrelate to each other. If one is going to make changes in a group of library routines, it is very important to understand how and where to make changes so the linkages between the routines won't get broken. The second part of the talk is an introduction to the plot language. In the third part, some new plots are presented.
Let's look in a slightly different way at those routines which Kirk Searle previous described. The plot routines are contained in the common data dictionary node, CDD$TOP.DTR$LIB.PLOTS . The entire contents of that node may be gotten with the EXTRACT ALL command in DATATRIEVE. The plot routines fall into five categories: documented top level plots which start a new plot; documented top level plots which change and/or continue a plot; documented top level plots which modify (without substantive change) a plot; undocumented top level plots; and utility level plots. All routines are listed below and the undocumented and utility routines are briefly described.
BAR BAR_AVERAGE DATE_LOGY DATE_Y
HISTO LOGX_LOGY LOGX_Y MULTI_BAR
MULTI_BAR_GROUP MULTI_LINE MULTI_LR MULTI_SHADE
PIE RAW_BAR RAW_PIE STACKED_BAR
VALUE_PIE WOMBAT X_LOGY X_Y
NEXT_BAR SORT_BAR
BIG CONNECT CROSS_HATCH HARDCOPY
LR PAUSE RE_PAINT SHADE
DATE_FREQ

frequency of occurrence vs. date; arg1=date. 
HATCH

exactly same as CROSS_HATCH; no arguments. 
OUTSTANDING

works a little like "PLOT DATE_FREQ . . .; PLOT SHADE"; arg1=date, arg2=date. 
X_FREQ

frequency of occurrence vs. X; arg1=xvalue. 
STACKED

** This appears to be old code from some previous version of the plot routines. It appears, currently, to be unreachable code. There are no routines which call it. It also appears not to work  at all. ** 
HOUSEKEEP

Plot for entering and exiting graphics mode on the terminal. Manages differences between VT240/1 and VT125. 
LABEL

Utility plot routine with 14 entry points which draws boundary box, scales X and Y, linear, log, and date arrays, computes linear regressions, displays scale lines, and performs several other internal utility functions. 
LEGEND

Utility plot routine with 4 entry points which manages LEGENDs. 
MAP

Basic routine to manage intensity, luminance, hue, and saturation. Used by the PALETTE procedure to adjust colors. 
MONITOR

Test routine to check wiring of color monitor on VT125 or VT241. 
DRAW_BAR

Basic BAR plotting routine that does the real work for BAR, BAR_AVERAGE, HISTO, and RAW_BAR. 
DRAW_PIE

Basic PIE plotting routine that does the real work for PIE, RAW_PIE, and VALUE_PIE. 
X_LABEL

Basic Xaxis labeling routine that works for MULTI_BAR, MULTI_BAR_GROUP, MULTI_SHADE, and STACKED_BAR 
As will be described in detail in the second part of this presentation, plots within the plot library are all called in a manner very similar to multiple entry subroutines in FORTRAN. Most top level plots have three or more entry points. However, WOMBAT has only one, but LABEL has fifteen.
In order to investigate which plot routine calls which other plot routines (more specifically which entry point of which routine calls which entry point of another or the same routine), I extracted the entire plot library from the dictionary, removed the procedure PALETTE with the editor, and converted all "REDEFINE PLOT" to "REDEFINE_PLOT" also with the editor. I then used a small BASIC program which keyed off of the tokens "REDEFINE_PLOT", "ENTRY", and "PLOT" to create the pairs of routine entry points  calling entry point with called entry point. The entry points are indicated by appending an underline character and the number of the entry point to the name of the plot routine. Thus, HOUSEKEEPING_2 refers to the entry point 2 in the HOUSEKEEPING plot routine. I then use DATATRIEVE to create a view of four domains (actually the same domain with itself three more times) in which the called entry point is matched with another calling entry point to create the entire tree of references through the plot library. Multiple references to the same linkage (duplicates) were removed and the output report was slightly rereformatted with the editor.
The "CALLING" linkages within the plot library are listed in the table "DOWN the Calling Tree". In this table, one can find all routines in alphabetic order which call other routines. Below each routine is the routines which it calls. The order in which routines are called is not preserved; they are listed in alphabetic order.BAR 00
DATA_LIMITS 00
DIMENSIONS 00
BAR 01
BAR 02
DATA_LIMITS 09
DATA_LIMITS 10
DRAW_BAR 00
DATA_LIMITS 02
DIMENSIONS 05
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
BAR_ASCENDING 00
DRAW_BAR 04
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
BAR_AVERAGE 00
DATA_LIMITS 00
DIMENSIONS 00
BAR_AVERAGE 01
BAR_AVERAGE 02
DATA_LIMITS 09
DATA_LIMITS 10
DRAW_BAR 00
DATA_LIMITS 02
DIMENSIONS 05
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
BIG 00
HOUSEKEEP 02
HOUSEKEEP 04
CONNECT 00
HOUSEKEEP 02
HOUSEKEEP 04
LABEL 09
CROSS_HATCH 00
HOUSEKEEP 02
DATA_LIMITS 00
DIMENSIONS 00
DATA_LIMITS 02
DATA_LIMITS 03
DATA_LIMITS 04
DATA_LIMITS 05
DATA_LIMITS 10
DATA_LIMITS 06
DATA_LIMITS 07
DATA_LIMITS 08
DATA_LIMITS 10
DATA_LIMITS 09
DATA_LIMITS 10
DATA_LIMITS 10
DATA_LIMITS 11
DATA_LIMITS 12
DATA_LIMITS 13
DATA_LIMITS 14
DATA_LIMITS 10
DATE_LOGY 00
DATA_LIMITS 00
DIMENSIONS 00
DATE_LOGY 01
DATE_LOGY 02
DATA_LIMITS 02
DATA_LIMITS 05
DATA_LIMITS 10
DIMENSIONS 13
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 05
DIMENSIONS 07
LABEL 11
LABEL 06
LABEL 14
LABEL 08
DATE_Y 00
DATA_LIMITS 00
DIMENSIONS 00
DATE_Y 01
DATE_Y 02
DATA_LIMITS 02
DATA_LIMITS 05
DATA_LIMITS 10
DIMENSIONS 06
DIMENSIONS 13
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 06
LABEL 14
LABEL 08
DIMENSIONS 00
DIMENSIONS 02
DIMENSIONS 03
DIMENSIONS 04
DIMENSIONS 05
DIMENSIONS 06
DIMENSIONS 07
DIMENSIONS 08
DIMENSIONS 09
DIMENSIONS 10
DIMENSIONS 11
DIMENSIONS 12
DIMENSIONS 13
DIMENSIONS 14
DRAW_BAR 00
DATA_LIMITS 02
DIMENSIONS 05
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
DRAW_BAR 03
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
DRAW_BAR 04
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
DRAW_BAR 05
DRAW_PIE 00
DATA_LIMITS 04
DATA_LIMITS 06
DATA_LIMITS 07
DATA_LIMITS 13
HOUSEKEEP 00
HOUSEKEEP 02
HARDCOPY 00
HOUSEKEEP 02
HOUSEKEEP 04
HISTO 00
DATA_LIMITS 00
DIMENSIONS 00
HISTO 01
HISTO 02
DATA_LIMITS 09
DATA_LIMITS 10
DRAW_BAR 00
DATA_LIMITS 02
DIMENSIONS 05
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
HOUSEKEEP 00
HOUSEKEEP 01
HOUSEKEEP 02
HOUSEKEEP 03
HOUSEKEEP 04
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 02
LABEL 10
LABEL 12
LABEL 14
LABEL 03
LABEL 10
LABEL 11
LABEL 04
DIMENSIONS 07
LABEL 12
LABEL 14
LABEL 05
DIMENSIONS 07
LABEL 11
LABEL 06
LABEL 14
LABEL 07
LABEL 13
LABEL 16
LABEL 08
LABEL 09
LABEL 10
LABEL 11
LABEL 12
LABEL 13
LABEL 14
LABEL 15
LABEL 16
LEGEND 00
HOUSEKEEP 02
LEGEND 03
LEGEND 05
LEGEND 04
LEGEND 05
LEGEND 05
LIMITS_X 00
LIMITS_X 01
DIMENSIONS 04
DIMENSIONS 14
LIMITS_Y 00
LIMITS_Y 01
DIMENSIONS 02
DIMENSIONS 14
DRAW_BAR 05
LOGX_LOGY 00
DATA_LIMITS 00
DIMENSIONS 00
LOGX_LOGY 01
LOGX_LOGY 02
DATA_LIMITS 02
DATA_LIMITS 05
DATA_LIMITS 10
DIMENSIONS 03
DIMENSIONS 13
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 04
DIMENSIONS 07
LABEL 12
LABEL 14
LABEL 05
DIMENSIONS 07
LABEL 11
LABEL 08
LOGX_Y 00
DATA_LIMITS 00
DIMENSIONS 00
LOGX_Y 01
LOGX_Y 02
DATA_LIMITS 02
DATA_LIMITS 05
DATA_LIMITS 10
DIMENSIONS 03
DIMENSIONS 13
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 04
DIMENSIONS 07
LABEL 12
LABEL 14
LABEL 08
LR 00
HOUSEKEEP 02
HOUSEKEEP 04
LABEL 07
LABEL 13
LABEL 16
MAP 00
MAP 01
MAP 02
HOUSEKEEP 02
MONITOR 00
HOUSEKEEP 00
HOUSEKEEP 02
MULTI_BAR 00
DATA_LIMITS 00
DIMENSIONS 00
MULTI_BAR 01
MULTI_BAR 02
DATA_LIMITS 02
DATA_LIMITS 09
DATA_LIMITS 10
DIMENSIONS 08
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 10
LEGEND 03
LEGEND 05
X_LABEL 00
MULTI_BAR_GROUP 00
DATA_LIMITS 00
DIMENSIONS 00
MULTI_BAR_GROUP 01
MULTI_BAR_GROUP 02
DATA_LIMITS 02
DATA_LIMITS 09
DATA_LIMITS 10
DIMENSIONS 08
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 10
LEGEND 03
LEGEND 05
X_LABEL 00
MULTI_LINE 00
DATA_LIMITS 00
DIMENSIONS 00
MULTI_LINE 01
MULTI_LINE 02
DATA_LIMITS 02
DATA_LIMITS 08
DATA_LIMITS 10
DIMENSIONS 09
DIMENSIONS 10
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 02
LABEL 10
LABEL 12
LABEL 14
LABEL 03
LABEL 10
LABEL 11
LABEL 16
LEGEND 04
LEGEND 05
MULTI_LINE 03
LABEL 08
MULTI_LINE 03
LABEL 08
MULTI_LR 00
DATA_LIMITS 00
DIMENSIONS 00
MULTI_LR 01
MULTI_LR 02
DATA_LIMITS 02
DATA_LIMITS 08
DATA_LIMITS 10
DIMENSIONS 09
DIMENSIONS 10
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 02
LABEL 10
LABEL 12
LABEL 14
LABEL 03
LABEL 10
LABEL 11
LABEL 16
LEGEND 04
LEGEND 05
MULTI_LR 03
LABEL 07
LABEL 13
LABEL 16
LABEL 08
MULTI_LR 04
MULTI_LR 03
LABEL 07
LABEL 13
LABEL 16
LABEL 08
MULTI_LR 04
MULTI_LR 04
MULTI_SHADE 00
DATA_LIMITS 00
DIMENSIONS 00
MULTI_SHADE 01
MULTI_SHADE 02
DATA_LIMITS 02
DATA_LIMITS 14
DATA_LIMITS 10
DIMENSIONS 11
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 16
LEGEND 03
LEGEND 05
X_LABEL 00
NEXT_BAR 00
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
PAUSE 00
PIE 00
DATA_LIMITS 00
DIMENSIONS 00
PIE 01
PIE 02
DATA_LIMITS 09
DATA_LIMITS 10
DRAW_PIE 00
DATA_LIMITS 04
DATA_LIMITS 06
DATA_LIMITS 07
DATA_LIMITS 13
HOUSEKEEP 00
HOUSEKEEP 02
RAW_BAR 00
DATA_LIMITS 00
DIMENSIONS 00
RAW_BAR 01
RAW_BAR 02
DATA_LIMITS 09
DATA_LIMITS 10
DRAW_BAR 00
DATA_LIMITS 02
DIMENSIONS 05
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
RAW_PIE 00
DATA_LIMITS 00
DIMENSIONS 00
RAW_PIE 01
RAW_PIE 02
DATA_LIMITS 09
DATA_LIMITS 10
DRAW_PIE 00
DATA_LIMITS 04
DATA_LIMITS 06
DATA_LIMITS 07
DATA_LIMITS 13
HOUSEKEEP 00
HOUSEKEEP 02
REFERENCE_X 00
DATA_LIMITS 02
REFERENCE_X 01
DATA_LIMITS 11
HOUSEKEEP 02
HOUSEKEEP 04
LABEL 16
REFERENCE_Y 00
DATA_LIMITS 02
REFERENCE_Y 01
DATA_LIMITS 11
HOUSEKEEP 02
HOUSEKEEP 04
LABEL 16
RE_PAINT 00
HOUSEKEEP 04
RE_PAINT 02
SHADE 00
HOUSEKEEP 02
HOUSEKEEP 04
LABEL 09
SORT_BAR 00
DRAW_BAR 03
DRAW_BAR 02
DIMENSIONS 06
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LABEL 15
STACKED_BAR 00
DATA_LIMITS 00
DIMENSIONS 00
STACKED_BAR 01
STACKED_BAR 02
DATA_LIMITS 02
DATA_LIMITS 09
DATA_LIMITS 10
DIMENSIONS 12
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 03
LABEL 10
LABEL 11
LABEL 08
LEGEND 03
LEGEND 05
X_LABEL 00
TITLE 00
TITLE 01
DATA_LIMITS 03
DATA_LIMITS 12
VALUE_PIE 00
DATA_LIMITS 00
DIMENSIONS 00
VALUE_PIE 01
VALUE_PIE 02
DATA_LIMITS 09
DATA_LIMITS 10
DRAW_PIE 00
DATA_LIMITS 04
DATA_LIMITS 06
DATA_LIMITS 07
DATA_LIMITS 13
HOUSEKEEP 00
HOUSEKEEP 02
WOMBAT 00
HOUSEKEEP 00
HOUSEKEEP 02
X_LABEL 00
X_LOGY 00
DATA_LIMITS 00
DIMENSIONS 00
X_LOGY 01
X_LOGY 02
DATA_LIMITS 02
DATA_LIMITS 05
DATA_LIMITS 10
DIMENSIONS 03
DIMENSIONS 13
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 02
LABEL 10
LABEL 12
LABEL 14
LABEL 05
DIMENSIONS 07
LABEL 11
LABEL 08
X_Y 00
DATA_LIMITS 00
DIMENSIONS 00
X_Y 01
X_Y 02
DATA_LIMITS 02
DATA_LIMITS 05
DATA_LIMITS 10
DIMENSIONS 03
DIMENSIONS 06
DIMENSIONS 13
HOUSEKEEP 00
HOUSEKEEP 02
LABEL 00
DATA_LIMITS 13
LABEL 13
LABEL 02
LABEL 10
LABEL 12
LABEL 14
LABEL 03
LABEL 10
LABEL 11
LABEL 08
Inverting the calling tree with the DATATRIEVE view produces the "CALLED" linkages within the plot library. These are listed in the table "UP the Called Tree". In this table, one can find all routines in alphabetic order which are called by other routines. Below each routine is the routines which it is called by. It is from this table that one can determine which routines might be affected by a change in a particular routine.
DRAW_BAR_0
BAR_2
BAR_AVERAGE_2
HISTO_2
RAW_BAR_2
HOUSEKEEP_0
DATE_FREQ_0
DATE_LOGY_0
DATE_Y_0
DRAW_BAR_2
BAR_2
BAR_AVERAGE_2
DRAW_BAR_3
SORT_BAR_0
HISTO_2
NEXT_BAR_0
RAW_BAR_2
DRAW_PIE_0
PIE_2
RAW_PIE_2
VALUE_PIE_2
LOGX_LOGY_0
LOGX_Y_0
MONITOR_0
MULTI_BAR_0
MULTI_BAR_GROUP_0
MULTI_LINE_0
MULTI_LR_0
MULTI_SHADE_0
OUTSTANDING_0
STACKED_2
STACKED_BAR_0
WOMBAT_0
X_FREQ_0
X_LOGY_0
X_Y_0
HOUSEKEEP_2
CONNECT_0
CROSS_HATCH_0
DATE_FREQ_2
DATE_LOGY_2
DATE_Y_2
DRAW_BAR_2
BAR_2
BAR_AVERAGE_2
DRAW_BAR_3
SORT_BAR_0
HISTO_2
NEXT_BAR_0
RAW_BAR_2
DRAW_PIE_0
PIE_2
RAW_PIE_2
VALUE_PIE_2
HARDCOPY_0
HATCH_0
LEGEND_0
STACKED_2
LOGX_LOGY_2
LOGX_Y_2
LR_0
MAP_2
MONITOR_0
MULTI_BAR_2
MULTI_BAR_GROUP_2
MULTI_LINE_2
MULTI_LR_2
MULTI_SHADE_2
OUTSTANDING_2
RE_PAINT_2
SHADE_0
STACKED_2
STACKED_BAR_2
WOMBAT_0
X_FREQ_2
X_LOGY_2
X_Y_2
HOUSEKEEP_4
BIG_0
CONNECT_0
HARDCOPY_0
LR_0
RE_PAINT_0
SHADE_0
LABEL_0
DRAW_BAR_2
DRAW_BAR_3
SORT_BAR_
LABEL_10
LABEL_2
MULTI_LINE_2
MULTI_LR_2
X_FREQ_2
X_LOGY_2
X_Y_2
LABEL_3
DATE_FREQ_2
DATE_Y_2
DRAW_BAR_2
BAR_2
BAR_AVERAGE_2
DRAW_BAR_3
HISTO_2
NEXT_BAR_0
RAW_BAR_2
LOGX_Y_2
MULTI_BAR_2
MULTI_BAR_GROUP_2
MULTI_LINE_2
MULTI_LR_2
MULTI_SHADE_2
OUTSTANDING_2
STACKED_2
STACKED_BAR_2
X_FREQ_2
X_Y_2
MULTI_BAR_2
MULTI_BAR_GROUP_2
LABEL_11
LABEL_3
DATE_FREQ_2
DATE_Y_2
DRAW_BAR_2
BAR_2
BAR_AVERAGE_2
DRAW_BAR_3
HISTO_2
NEXT_BAR_0
RAW_BAR_2
LOGX_Y_2
MULTI_BAR_2
MULTI_BAR_GROUP_2
MULTI_LINE_2
MULTI_LR_2
MULTI_SHADE_2
OUTSTANDING_2
STACKED_2
STACKED_BAR_2
X_FREQ_2
X_Y_2
LABEL_5
DATE_LOGY_2
LOGX_LOGY_2
X_LOGY_2
LABEL_12
LABEL_2
MULTI_LINE_2
MULTI_LR_2
X_FREQ_2
X_LOGY_2
X_Y_2
LABEL_4
LOGX_LOGY_2
LOGX_Y_2
LABEL_13
LABEL_0
DATE_FREQ_0
DATE_LOGY_0
DATE_Y_0
DRAW_BAR_2
BAR_2
BAR_AVERAGE_2
DRAW_BAR_3
HISTO_2
NEXT_BAR_0
RAW_BAR_2
LOGX_LOGY_0
LOGX_Y_0
MULTI_BAR_0
MULTI_BAR_GROUP_0
MULTI_LINE_0
MULTI_LR_0
MULTI_SHADE_0
OUTSTANDING_0
STACKED_2
STACKED_BAR_0
X_FREQ_0
X_LOGY_0
X_Y_0
LABEL_7
LR_0
MULTI_LR_3
MULTI_LR_2
LABEL_14
LABEL_2
MULTI_LINE_2
MULTI_LR_2
X_FREQ_2
X_LOGY_2
X_Y_2
LABEL_4
LOGX_LOGY_2
LOGX_Y_2
LABEL_6
DATE_FREQ_2
DATE_LOGY_2
DATE_Y_2
OUTSTANDING_2
LABEL_15
DRAW_BAR_2
BAR_2
BAR_AVERAGE_2
DRAW_BAR_3
SORT_BAR_0
HISTO_2
NEXT_BAR_0
RAW_BAR_2
LABEL_3
DRAW_BAR_2
DRAW_BAR_3
SORT_BAR_0
LABEL_8
DATE_FREQ_2
DATE_LOGY_2
DATE_Y_2
DRAW_BAR_2
BAR_2
BAR_AVERAGE_2
DRAW_BAR_3
SORT_BAR_0
HISTO_2
NEXT_BAR_0
RAW_BAR_2
LOGX_LOGY_2
LOGX_Y_2
MULTI_BAR_2
MULTI_BAR_GROUP_2
MULTI_LINE_3
MULTI_LINE_2
MULTI_LR_3
MULTI_LR_2
MULTI_SHADE_2
OUTSTANDING_2
STACKED_BAR_2
X_FREQ_2
X_LOGY_2
X_Y_2
LABEL_9
CONNECT_0
SHADE_0
LEGEND_5
LEGEND_3
MULTI_BAR_2
MULTI_BAR_GROUP_2
MULTI_SHADE_2
STACKED_BAR_2
LEGEND_4
MULTI_LINE_2
MULTI_LR_2
STACKED_3
STACKED_2
X_LABEL_0
MULTI_BAR_2
MULTI_BAR_GROUP_2
MULTI_SHADE_2
STACKED_BAR_2
When support for VT240 and VT241 terminals was added in Version 3.0 of VAXDATATRIEVE, the method of performing I/O for graphics instructions was changed. With the VT125 it was possible to write directly to the terminal. Because the graphics planes and characters planes of the VT125 were independent; command prompting, command input, and graphics output were unaffected by each other. However, with the VT240/1 terminal in which the graphic and character displays were intertwined, the DATATRIEVE plot library had to be changed to write all graphics instructions into internal buffers so that the VT24X terminal could be cleared and the image redisplayed one or more times. These buffers are called SEGMENTs; there are eight of them numbered zero to seven. There are three ways of referencing these segments  CLEAR, OUTPUT, and SET. The meaning of these references will be explained in the second part of the presentation. The table "PLOTNAME\SEGMENTS" lists all plot library entry points which make a reference to a segment. With each is listed the segment number which is referenced and the method by which it is referenced. Most top level plot routines make reference to one or more segments within their entry points 0 and 2. Notice that HOUSEKEEP_0 clears all segments and all top level routines call HOUSEKEEP_0.
\SEGMENTS CLEAR OUTPUT SET
PLOTNAME\ 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
BIG_0  4  4 5 6  4 
CONNECT_0    1 
CROSS_HATCH_0  0 4  0 1 3 4 6  0 4 
DATE_FREQ_0    1 
DATE_FREQ_2   1  
DATE_LOGY_0    1 
DATE_LOGY_2   1  
DATE_Y_0    1 
DATE_Y_2   1  
DRAW_BAR_2   1  1 
DRAW_PIE_0  3  0 1  0 1 5 
HARDCOPY_0  4  4 5 6  4 
HATCH_0  0 4  0 1 3 4 6  0 4 
HOUSEKEEP_0  0 1 2 3 4 5 6 7  4 6  4 6 
HOUSEKEEP_1  4  4  4 
HOUSEKEEP_2  7  7  7 
HOUSEKEEP_3  4  4  4 
HOUSEKEEP_4  4  0 1 3 4 6  4 
LEGEND_0  4  4 6  4 
LEGEND_5   2 3  2 3 
LOGX_LOGY_0    1 
LOGX_LOGY_2   1  
LOGX_Y_0    1 
LOGX_Y_2   1  
LR_0    1 
MAP_0  4   4 
MAP_2   4  
MONITOR_0  1  1  1 
MULTI_BAR_0   0 6  0 1 
MULTI_BAR_2   1  
MULTI_BAR_GROUP_0   0 6  0 1 
MULTI_BAR_GROUP_2   1  
MULTI_LINE_0   0  0 1 
MULTI_LINE_2   1  
MULTI_LR_0   0  0 1 
MULTI_LR_2   1  
MULTI_SHADE_0   0 6  0 1 
MULTI_SHADE_2   1  
OUTSTANDING_0    1 
OUTSTANDING_2   1  
PAUSE_0  4  4  4 
SHADE_0    1 
STACKED_2   1  1 
STACKED_BAR_0   0 6  0 1 
STACKED_BAR_2   1  
WOMBAT_0   0 1  0 1 2 
X_FREQ_0    1 
X_FREQ_2   1  
X_LOGY_0    1 
X_LOGY_2   1  
X_Y_0    1 
X_Y_2   1  
The table "Segments Access by Plots" inverts the "PLOTNAME\SEGMENTS" table to show which segments are manipulated by which plots. It is from the information in these two tables that one can see how changes in such plot routines as HOUSEKEEPING, HARDCOPY, and BIG will affect other routines.
Segment 0 Segment 1 (continued)
CROSS_HATCH_0 X_LOGY_0
DRAW_PIE_0 X_LOGY_2
HATCH_0 X_Y_0
HOUSEKEEP_0 X_Y_2
HOUSEKEEP_4 Segment 2
MULTI_BAR_0 HOUSEKEEP_0
MULTI_BAR_GROUP_0 LEGEND_5
MULTI_LINE_0 WOMBAT_0
MULTI_LR_0 Segment 3
MULTI_SHADE_0 CROSS_HATCH_0
STACKED_BAR_0 DRAW_PIE_0
WOMBAT_0 HATCH_0
Segment 1 HOUSEKEEP_0
CONNECT_0 HOUSEKEEP_4
CROSS_HATCH_0 LEGEND_5
DATE_FREQ_0 Segment 4
DATE_FREQ_2 BIG_0
DATE_LOGY_0 CROSS_HATCH_0
DATE_LOGY_2 HARDCOPY_0
DATE_Y_0 HATCH_0
DATE_Y_2 HOUSEKEEP_0
DRAW_BAR_2 HOUSEKEEP_1
DRAW_PIE_0 HOUSEKEEP_3
HATCH_0 HOUSEKEEP_4
HOUSEKEEP_0 LEGEND_0
HOUSEKEEP_4 MAP_0
LOGX_LOGY_0 MAP_2
LOGX_LOGY_2 PAUSE_0
LOGX_Y_0 Segment 5
LOGX_Y_2 BIG_0
LR_0 DRAW_PIE_0
MONITOR_0 HARDCOPY_0
MULTI_BAR_0 HOUSEKEEP_0
MULTI_BAR_2 Segment 6
MULTI_BAR_GROUP_0 BIG_0
MULTI_BAR_GROUP_2 CROSS_HATCH_0
MULTI_LINE_0 HARDCOPY_0
MULTI_LINE_2 HATCH_0
MULTI_LR_0 HOUSEKEEP_0
MULTI_LR_2 HOUSEKEEP_4
MULTI_SHADE_0 LEGEND_0
MULTI_SHADE_2 MULTI_BAR_0
OUTSTANDING_0 MULTI_BAR_GROUP_0
OUTSTANDING_2 MULTI_SHADE_0
SHADE_0 STACKED_BAR_0
STACKED_2 Segment 7
STACKED_BAR_0 HOUSEKEEP_0
STACKED_BAR_2 HOUSEKEEP_2
WOMBAT_0
X_FREQ_0
X_FREQ_2
A plot definition has the following structure:
DEFINE PLOT plotname
DECLARE TYPESPECIFICATION date_variable1 [,data_variable...]
ENTRY 0 [{P1[:TYPE[:COMMENT]] [,Pn[:TYPE[:COMMENT]]}]
BEGIN
. . .
plot statements
. . .
END
. . .
. . .
ENTRY N [{P1[:TYPE[:COMMENT]] . . . ]
BEGIN
. . .
END
END_PLOT
The plot begins with a "DEFINE PLOT" and ends with an "ENDPLOT".
There are three data types allow with the plot package. These are REAL, DATE, and STRING. The data type REAL is the default data type. Thus, if a variable is to be of the DATA or STRING data type, it must be declared in a DECLARE statement or have its type specified within the entry point statement. In addition the plot package allows for dynamic arrays. That is, array variables may be allocated on the fly as needed. To specify that a variable is an array, then the declaration modifier VECTOR is added to the data declaration statement. Vectors can be indexed by literal integers (even though there is not really an integer data type) or by REALs. The reals are rounded to the nearest integer before being used as an index. Thus for an N element vector, the valid indexes I are 0.5 <= I < N+0.5 .
Unlike any other DATATRIEVE objects, plots have multiple entry points. These entry points have parameters which are specified in a manner very similar to PASCAL that allows a flexible but more carefully specified interface with ordinary DATATRIEVE statements. The form of an entry statement is
ENTRY N [{P1[:TYPE[:COMMENTSTRING]] [,Pn[:TYPE[:COMMENTSTRING]]}]
where N is an integer literal, P1 though Pn are variable names, TYPE is one of the valid data types (REAL, DATE, and STRING), and COMMENTSTRING is a literal string while documents variable being passed. Parameters are, in effect, declared in the entry point with the TYPE modifier. The default data type is REAL, so if the TYPE modifier is left off, the parameter is assumed to be REAL.
Entry point 0 is used to initialize the plot. It is called once to initialize the plot and to pass in the labels associated with all of the parameters. This entry point specifies the number of parameters of the plot, and all of the parameters are STRING type. In general, this entry point clears the necessary plot segment buffers, clears the screen, and sets up size and location of the plots and any special plotting parameters like shading or crosshatching.
Entry point 1 is called once for each set of parameters that are to be managed in the plot. Thus if there are 23 points to be plot, entry point 1 would be used 23 times. In general, data is moved from the user's record stream into internal arrays. Usually there is no actual output within this entry point. Data is just gathered up.
Entry point 2 is called only, once and it has no parameters. Final calculations are done, scaling of the plot is passed to various routines within LABEL, the actual plot is written into any appropriate PLOT SEGMENT buffer, and the control is passed off to HOUSEKEEPING to display the plot.
Most top level plots have only three entry points 0, 1, and 2. That is, plots which are called with the DATATRIEVE PLOT statement observe the conventions of entry points 0, 1, and 2. A single PLOT statement at DATATRIEVE command level will execute entry 0 once, entry 1 multiple time, and entry 2 one.
Top level plots which are called by the user may make calls to other utility plots. These calls from within plot definitions to other plots are of the form
PLOT UTILITY_PLOTNAME ENTRY_NUMBER [ ... argument list ... ]
Utility plots, in contract to top level plots, do not observe the convention of entry points 0, 1, and 2. However, many utility plots do not have an entry 1 or 2. When utility plots are called with a specify entry point reference, only the specified entry is executed. No other plot routines are executed unless specifically called.
The statements with the PLOT Package appear similar to the statements with DATATRIEVE. However, they are, in some ways, very different. Statements in the PLOT Package are a highly structure language just as is DATATRIEVE. Thus, there is no GOTOlike statement or need for one. There are no statements in the PLOT language other than those described below and the "DEFINE PLOT", "ENDPLOT", "DECLARE", and "ENTRY" statements.
The assignment statement takes the usual form. However, it is possible to have multiple assignment statements on a single line as in the following example:
X = 23.5
Y = 27.8 PSTRING = 'NUMBER'
Compound statements are exactly the same as in DATATRIEVE. The BEGINEND form the boundaries of the compound statement.
BEGIN
X = X + 1
Y = X / 3
END
Although the IFTHENELSE statement within the PLOT Package may appear to be the same as in DATATRIEVE, it is not. The difference is that an ELSE may begin a statement line. Thus it is possible to easily create nway branching logic without the use of BEGINEND statements as illustrated in the following examples:
IF X < 5 THEN
BEGIN
X = X + 1
Y = X * X
END
ELSE Y = X * 3
or
IF X = 1 THEN
PRINT "X equals 1"
ELSE IF X = 2 THEN
PRINT "X equals 2"
ELSE IF X = 3 THEN
PRINT "X equals 3"
ELSE
PRINT "X equals other"
Since the support of VT240 and VT241 terminals, ReGIS code is not transferred directly from the modules of the PLOT Package to the terminal hardware, but the ReGIS instructions are first placed in output buffers (knows as SEGMENTS) since it may be required to reexecute the graphics instructions. Thus, ReGIS code is saved in internal segments (buffers). The PRINT statement moves data into these buffers. There are four special "functions" which control the use of these buffer. They are:
RELEASE_SEGMENTS

initialize all segments 
CLEAR_SEGMENT N

initialize segment N 
SET_SEGMENT N

cause all output from the PRINT statements to go into segment N 
OUTPUT_SEGMENT N[,N2[,N3 . . .]]

transfer the contents of segments N, N2, N3, etc to the display terminal. That is, actually perform the output. 
Thus, the PRINT statement does not do output directly, but moves data into buffers. There are several special symbols or declared global variables which have meaning only within the PLOT Package. These are:
$

special symbol for <ESC> 
CLRSCR

clear screen escape sequence 
ENTER_REGIS(1)

enter ReGIS mode escape sequence 
EXIT_REGIS

exit ReGIS mode escape sequence 
RESTORE_VT125

special ReGIS code sequence which sets the four (black and white) intensity levels to 0, 33, 66, and 100%. 
A PRINT statement may contains one or more of the special symbols, one or more special graphics functions (described later), or strings. Some examples of PRINT statement are:
PRINT $,'<',CLRSCR,ENTER_REGIS(1),'S(m0(l0)1(l33)2(l66)3(l100))'
PRINT 'P',LXY(X_AXIS+1,Y_POS),'V(W(P4I(0)))',RX(LINE_LEN)
Other utility plot may be called from within a plot definition. To call these utility plots, one must specify the entry point as well as the calling arguments. Example of these utility plot calls are:
PLOT LABEL 2 (X_MIN, Y_MIN, X_VECTOR)
PLOT HOUSEKEEP 0
Although the SORT statement looks like a functions, it is a statement which performs a sorting operations on the specified array or arrays. Upon return from this statement, the arrays have been reordered in their same storage locations. The SORT statement may optionally take the modified DESCENDING or DESC. The SORT statement will sort on the first array but will reorder all arrays specified. SORT takes one to four arrays as arguments. Examples are:
DECLARE VECTOR X, Y1, Y2, Y3
DECLARE VECTOR DATE
SORT (X, Y1, Y2, Y3)
SORT DESCENDING (DATE, Y1)
Since the PLOT Package contains arrays (which DATATRIEVE doesn't have), a DOLOOP mechanism (which DATATRIEVE doesn't really need) is implemented. The INCREMENT statement takes on two forms. The first form is
INCR loopvariable FROM startvariable TO stopvariable
and
INCR loopvariable OVER arrayname
This second form is equivalent to
INCR loopvariable FROM 1 TO SIZE(arrayname)
Examples of the INCREMENT statement are:
INCR INDEX OVER VALUES
VALUES(INDEX) = VALUES(INDEX)/COUNT(INDEX)
and
INCR I FROM Y_ORIGIN TO TOP  1
INCR J FROM 1 TO 9
BEGIN
POINT = J * 10 ** I
. . .
END
A WHILE statement is also implemented although it is used only once within the PLOT Package in LABEL 6. The syntax of the WHILE statement is the same as in DATATRIEVE. An example is:
WHILE DATE_COM(SCRATCH_VALUE) < MAX_VALUE
BEGIN
. . .
END
The usual set of arithmetic operators are implemented (+, , *, and /). In addition, exponentiation is implemented in the form "**". There is, however unlike DATATRIEVE, no string concatenation operators within the PLOT Package.
Many Boolean relations operators have been implemented. However, they are, by no means, a complete and exhaustive set. The operators (AND, OR, <, >, EQ, LT, LE, GE, GT, and NE) exist. Notable by its absence is "NOT", but that doesn't seem to create any problems.
The PLOT Package is rich in internally defined functions. User defined functions and the DATATRIEVE functions like FN$FUNCTION are not accessible. The functions internal to the PLOT Package are:
CENTER

CENTER takes four arguments. A REAL value giving an X coordinate. A REAL value giving a Y coordinate. A STRING whose upper left corner is to be placed at the coordinate. And the size of the characters to be displayed (in pixels). CENTER returns a string representing the ReGIS commands to display the string. 
CVT

CVT takes a REAL number as a parameter and returns it as a string. 
COS

COS takes a REAL number in degrees and returns the REAL cosine. 
INT

INT takes a REAL number and return a REAL number which has the value of the nearest integer. 
LENGTH

LENGTH takes a STRING and return a REAL number which is the length of the string. 
LOG

LOG takes a REAL number and returns the REAL natural log of the number. 
LX

LX takes one REAL X coordinate and returns the string representing the absolute ReGIS coordinates [X]. 
LXY

LXY takes the REAL X and Y coordinates and returns the string representing the absolute ReGIS coordinates [X,Y]. 
LY

LY takes one REAL Y coordinate and returns the string representing the absolute ReGIS coordinate [,Y]. 
MAX

MAX takes an array as a parameter and returns the maximum value of its elements. 
MIN

MIN takes an array as a parameter and returns the minimum value of its elements. 
QUOTE

QUOTE takes a STRING as a parameter and returns the string in a form for inserting it into a ReGIS command. 
RX

RX takes one REAL X coordinate and returns the string representing the relative ReGIS coordinates [+X]. 
RXY

RXY takes two REAL X and Y coordinate and returns the string representing the relative ReGIS coordinates [+X,+Y]. 
RY

RY takes one REAL Y coordinate and returns the string representing the relative ReGIS coordinate [,+Y]. 
SEARCH

SEARCH takes a string, and an array of strings as parameters and returns the index of the string in the array, or 0 if it is not found in the array. 
SIN

SIN takes a REAL number in degrees and returns the REAL sine. 
SIZE

SIZE takes an array as a parameter and returns the number of elements in the array. 
SQRT

SQRT takes a REAL number as a parameters and returns the REAL square root. Even though this functions is available, it is not now used. But it still works! Wonder what other functions are available but are just not used? 
TXY

TXY takes two parameters which are the X (column) and Y (row) coordinates. TXY returns the escape sequence which will position the cursor to that location on the 80 column by 24 line screen. 
When Version 3.0 of DATATRIEVE was release last fall, the plot HARDCOPY was changed. In versions 2.X, HARDCOPY only printed the plot and the legend was not plotted unless specifically requested. With Version 3.0, HARDCOPY was changed so that the LEGEND was always copied  even if the LEGEND was blank. This caused a lot of blank space after PIE, X_Y, and other kinds of plots. In order the maintain some compatibility with some of my command files, it was necessary to create a plot which worked like the Version 2.X HARDCOPY. I called the plot HARDCOPY_WITHOUT_LEGEND. The changes from the Version 3.0 of HARDCOPY are shown in bold and marked at the righthand margin with "<".
PLOT HARDCOPY PLOT HARDCOPY_WITHOUT_LEGEND <
ENTRY 0 ENTRY 0
BEGIN BEGIN
PLOT HOUSEKEEP 4 PLOT HOUSEKEEP 4
OUTPUT_SEGMENT 5 OUTPUT_SEGMENT 5
CLEAR_SEGMENT 4 CLEAR_SEGMENT 4
SET_SEGMENT 4 SET_SEGMENT 4
PRINT 'S(H)S(E)P[100,200]@BS(H)' PRINT 'S(H)' <
OUTPUT_SEGMENT 5,4,6 OUTPUT_SEGMENT 5,4,6
PLOT HOUSEKEEP 2 PLOT HOUSEKEEP 2
END END
END_PLOT END_PLOT
In my system, I keep track of the number of disk blocks which are used by each account on each day. Very often I need to have a graph of the total disk blocks used by a group of users in a department or division. I would, therefore, like to have a plot of date vs the sum of y. The plots X_FREQ and DATE_FREQ can easily be modified to make plots X_SUM and DATE_SUM. In a similar way, BAR_AVERAGE could be changed make a plot BAR_SUM. DATE_SUM can be created from DATE_FREQ by making changes in only five lines of plot code. The changes are noted in bold and marked on the righthand margin with "<". The use of DATE_SUM is illustrated in Figures 1, 2, and 3.
PLOT DATE_FREQ PLOT DATE_SUM <
. .
. .
ENTRY 0 (X_LABEL : STRING) ENTRY 0 (X_LABEL:STRING,Y_DL:STRING) <
BEGIN BEGIN
. . . . . .
Y_LABEL = 'NUMBER' Y_LABEL = 'SUM' <
. . . . . .
END END
ENTRY 1 (X : DATE) ENTRY 1 (X : DATE , Y) <
BEGIN BEGIN
INDEX = SEARCH (X, DATES) INDEX = SEARCH (X, DATES)
IF INDEX EQ 0 IF INDEX EQ 0
BEGIN BEGIN
INDEX = SIZE (DATES) + 1 INDEX = SIZE (DATES) + 1
DATES (INDEX) = X DATES (INDEX) = X
END END
FREQS(INDEX)=FREQS(INDEX) + 1 FREQS(INDEX)=FREQS(INDEX) + Y <
END END
ENTRY 2 ENTRY 2
BEGIN BEGIN
. . . . . .
END END
END_PLOT END_PLOT
In our medical environment it is very often necessary to display an X_Y scattergraph of more than one group of patients. By comparison with the plots X_Y and MULTI_LINE, a new plot X_Y_GROUP is created which has as its call arguments the x coordinate, the y coordinate, and a string indicating group membership. Because of the restrictions of LEGEND entry points 4 and 5, the number of groups is limited to three. All points belonging to the fourth, fifth, and higher groups are plotted as members of the third group.
DELETE X_Y_GROUP;
REDEFINE PLOT X_Y_GROUP
DECLARE X_AXIS, Y_AXIS, X_LENGTH, Y_LENGTH, X_MAX, X_MIN, Y_MIN, Y_MAX
DECLARE X_POS, Y_POS, I, J, WIDTH
DECLARE VECTOR XS, YS, ZS, Y_MX,COLOR
DECLARE STRING VECTOR GROUP_VALUE, CHR
ENTRY 0 (X_LABEL : STRING, Y_LABEL : STRING, GROUP_LABEL : STRING)
BEGIN
PLOT HOUSEKEEP 0
SET_SEGMENT 0
PRINT 'L(A2)'
PRINT 'L"0"00181818FF181818' ! cross
PRINT 'L"1"003C42818181423C' ! circle
PRINT 'L"2"0081422418244281' ! X
OUTPUT_SEGMENT 0
CHR(1) = '0' CHR(2) = '1' CHR(3) = '2'
COLOR(1) = 1 COLOR(2) = 1 COLOR(3) = 1
SET_SEGMENT 1
X_AXIS = 100
Y_AXIS = 360
X_LENGTH = 600
Y_LENGTH = 350
PLOT LABEL 0 (X_AXIS, Y_AXIS, X_LENGTH, Y_LENGTH, X_LABEL, Y_LABEL)
END
ENTRY 1 (X : REAL , Y : REAL , G : STRING)
BEGIN
XS (SIZE (XS) + 1 ) = X
YS (SIZE (YS) + 1 ) = Y
I = SEARCH(G,GROUP_VALUE)
IF I EQ 0 THEN BEGIN
GROUP_VALUE(SIZE(GROUP_VALUE) + 1) = G
I = SIZE(GROUP_VALUE)
IF I GT 3 THEN I = 3 ! RESTRICTION DUE TO LEGEND
END
ZS (SIZE(ZS) + 1) = I
END
! Print scatter plot
ENTRY 2
BEGIN
X_MIN = MIN (XS)
X_MAX = MAX (XS)
Y_MAX = MAX (YS)
Y_MIN = MIN (YS)
IF Y_MIN > 0
THEN Y_MIN = 0
PLOT LABEL 2 (X_MIN, X_MAX, XS)
PLOT LABEL 3 (Y_MIN, Y_MAX)
PLOT LABEL 8 (YS)
!
PRINT 'T(BA2S[8,16])'
INCR I OVER XS
PRINT 'P', LXY(XS(I)4,YS(I)8),'T',QUOTE(CHR(ZS(I)))
PRINT 'T(E)'
OUTPUT_SEGMENT 1
!
WIDTH = X_LENGTH/30
Y_MX(30) = 0
INCR I OVER XS
BEGIN
J = ((XS(I)  X_AXIS) / WIDTH) + 1
Y_MX(J) = 1000
IF Y_MX(J) GT YS(I) THEN
Y_MX(J) = YS(I)
END
INCR I OVER Y_MX
IF (I NE 1) AND (Y_MX(I) EQ 0) THEN
Y_MX(I) = Y_MX(I  1)
PLOT LEGEND 4 (X_AXIS,Y_AXIS,X_LENGTH,Y_LENGTH,WIDTH,Y_MX,
CHR,COLOR,GROUP_VALUE)
PLOT HOUSEKEEP 2
END
END_PLOT
What I have given is three new plots; what I would really like to give you is the courage to go in and create your own plots. Keep in mind that the plot library is undocumented. That means, Digital makes no promises as to how DATATRIEVE graphics will be implemented in the future. If some new graphical device appears on the scene, it's likely that the internal structure of the plot library will change as it did in the case of VT240 support. If you create new plots, you are really on your own. But isn't the freedom great?
The news plot DATE_SUM is show in Figure 3. For comparison, Figures 1 and 2 shows the data which combines in Figure 3. Figure 4 is the new plot X_Y_GROUP. The plot HARDCOPY_WITHOUT_LEGEND can not be easily illustrated since it is the absence of a blank legend which is of interest.
The VAXDATATRIEVE PLOT Package contains significant programming tools. If one is willing to spend a little time becoming familiar with the PLOT Package and the PLOT language, then modifications to existing plots and addition of new plots may be accomplished with relative ease.
I would like to gratefully acknowledge the work of Don Becker which appeared in an article "How to Write Plots in DTR" in the Wombat Examiner, Volume 5, Number 3, pages 2031. It is from this first article published on the plot language that much of the information in the second part of this presentation was taken. I would also like to acknowledge the assistance of Andy Schneider of Digital. In several conversations with Andy over the past year, I gained enough insight into the plot library that I begin to understand it in some meaningful way.
[The following are excerpts from the question and answers which followed the presentation. Only a small part of the discussion is summarized here.]
Doug Wegsheid, Whirlpool Corporation: Is it true that if you make a change to one of your plots after you have done a SET PLOTS, you have to get out of DATATRIEVE and get back in for your changes to take effect?
Gallagher: Plots are just like any other dictionary object. Since there is no RELEASE PLOTNAME command, you do have to exit and reenter DATATRIEVE for your editing changes to take effect.
Jane Hesler, Medical College of Virginia: When a new version of DTR gets installed, what happens to plots in the plot library?
Gallagher: They all get blown away. The way to avoid this is to keep a source code copy of all your plots in a separate account. Then reinstall these plots after DTR has been update. Another method is to keep a copy of the plot library on another node of the CDD which would not be affected by a DTR update. Your own dictionary node is one possibility.
Eric Mathew, Teradyne: Have your tried using other DATATRIEVE statements within a DEFINE PLOT?
Gallagher: Yes, I have tried a few. The statements I have given are apparently the only legal statements with the plot language.
Mathew: One comment on ReGIS code, I also played with the HARDCOPY plot, and I had to buy a manual.
Gallagher: A word of caution about ReGIS code, the implementation of ReGIS code on a VT125, VT240, GIGI, Rainbow emulator, DECmate emulator, and PRO emulator is slight different. There's ReGIS code and then there's ReGIS code.
Doug Wegsheid: It's very important to make a complete copy of everything in the plot library.
Gallagher: It is very important in the plot development stage that you do not do your development on the production plot library. Users don't like that.
Unknown female questioner: Is there a way to get your plots to the pen plotter?
Gallagher: The pen plotter, of course, must be able to handle ReGIS code. For a simple plot use the construct PLOT PLOTNAME on PLOTFILE. Then transfer the file to the pen plotter. However, the plot library routines are based on the assumption that you are plotting to a ReGIS terminal with a hardcopy device.
Brian Lockery, ITT: I have a VT125 and an LA50 hardcopy device. I have a procedure that prints out about 50 plots in a row. How do I get a form feed between the hardcopy plots?
Gallagher: This is a particular nasty problem which has to do with the timing between the computer, VT125, and LA hardcopy device. The computer must be prevented from issuing the sequence "<ESC>[5i<FF><ESC>[4i" before the LA device physically finishes making the hardcopy. This problem is discussed and solved in the Wombat Examiner, Volume 5, Number 4, pages 4244.
Joe H. Gallagher, Ph. D. dtrwiz@ix.netcom.com 
Back 