.PAPER SIZE 58, 80 .BLANK .CENTER VAX-DATATRIEVE Graphics Internals .TITLE VAX-DATATRIEVE Graphics Internals .BLANK.CENTER Joe H.#Gallagher .SUBTITLE Joe H.#Gallagher .BLANK.CENTER Cleveland, OH .BLANK 2.CENTER Edited by B.#Z.#Lederman .BLANK 2.CENTER Introduction .PARAGRAPH 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 (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 in a 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 Andy Schneider of Digital has shown 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 DTRFND.MAR, with such user written and VAX library routines that Phil Naecker has described. More examples of this type will have been given at the Wombat Magic sessions and the Newsletter. 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 .BLANK.CENTER FIND C IN A UNION B .BLANK That is a whole new idea and would certainly require internal code to be written. .PARAGRAPH There is an area of DATATRIEVE where users can write new code in a somewhat PASCAL-like 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. .PARAGRAPH In a 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. .BLANK 2.TEST PAGE 5.CENTER Structure and Contents of the Plots Dictionary .PARAGRAPH 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. .BLANK Documented Top Level Plots which Start a New Plot .BLANK.NO JUSTIFY.NO FILL 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 .BLANK 2 Documented Top Level Plots which Change and Continue a Plot .BLANK NEXT__BAR SORT__BAR .BLANK 2 Documented Top Level Plots which Modify (without substantive change) a Plot .BLANK BIG CONNECT CROSS__HATCH HARDCOPY LR PAUSE RE__PAINT SHADE .BLANK 2 Undocumented Top Level Plots .BLANK.JUSTIFY.FILL.LEFT MARGIN +15 .BREAK.INDENT -15 DATE__FREQ######frequency of occurrence vs. date; arg1=date. .BLANK.INDENT -15 HATCH##########exactly same as CROSS__HATCH; no arguments. .BLANK.INDENT -15 OUTSTANDING####works a little like "PLOT DATE__FREQ . . .; PLOT SHADE"; arg1=date, arg2=date. .BLANK.INDENT -15 X__FREQ#########frequency of occurrence vs. X; arg1=x-value. .BLANK.INDENT -15 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. ** .BLANK 2.INDENT -15 Utility Level Plots .BLANK.INDENT -15 HOUSEKEEP######Plot for entering and exiting graphics mode on the terminal. Manages differences between VT240/1 and VT125. .BLANK.INDENT -15 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. .BLANK.INDENT -15 LEGEND#########Utility plot routine with 4 entry points which manages legends. .BLANK.INDENT -15 MAP############Basic routine to manage intensity, luminance, hue, and saturation. Used by the PALETTE procedure to adjust colors. .BLANK.INDENT -15 MONITOR########Test routine to check wiring of color monitor on VT125 or VT241. .BLANK.INDENT -15 DRAW__BAR#######Basic BAR plotting routine that does the real work for BAR, BAR_AVERAGE, HISTO, and RAW_BAR. .BLANK.INDENT -15 DRAW__PIE#######Basic PIE plotting routine that does the real work for PIE, RAW__PIE, and VALUE__PIE. .BLANK.INDENT -15 X__LABEL########Basic X-axis labeling routine that works for MULTI__BAR, MULTI__BAR__GROUP, MULTI__SHADE, and STACKED__BAR .LEFT MARGIN -15 .PARAGRAPH 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. .PARAGRAPH 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 re-reformatted with the editor. .PARAGRAPH 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. .PARAGRAPH 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. .PARAGRAPH When support for VT240 and VT241 terminals was added in Version 3.0 of VAX-DATATRIEVE, 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 re-displayed 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__O. .PARAGRAPH 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. .BLANK 2.CENTER Plot Language .PARAGRAPH Plot Definition: .BLANK A plot definition has the following structure: .BLANK.NO JUSTIFY.NO FILL DEFINE PLOT plotname DECLARE TYPE-SPECIFICATION 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 .JUSTIFY.FILL.BLANK The plot begins with a "DEFINE#PLOT" and ends with an "END__PLOT". .BLANK 2 Declarations Statement and Data Typing: .PARAGRAPH 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 DATE 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#. .BLANK 2 Entry Points: .PARAGRAPH 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 .BLANK ENTRY N [{P1[:TYPE[:COMMENT-STRING]] [,Pn[:TYPE[:COMMENT-STRING]]}] .BLANK 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 COMMENT-STRING 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. .PARAGRAPH 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 cross-hatching. .PARAGRAPH 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. .PARAGRAPH 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. .PARAGRAPH 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. .PARAGRAPH 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 .BLANK PLOT UTILITY__PLOTNAME ENTRY__NUMBER [ ... argument list ... ] .BLANK 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. .BLANK 2 Statements: .PARAGRAPH 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 GOTO-like statement or need for one. There are no statements in the PLOT language other than those described below and the "DEFINE PLOT", "END__PLOT", "DECLARE", and "ENTRY" statements. .LEFT MARGIN +5 .BLANK 2 Assignment Statement: .BLANK 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: .BLANK.INDENT X = 23.5 .BREAK.INDENT Y = 27.8 PSTRING = 'NUMBER' .BLANK 2 Compound Statement: .BLANK Compound statements are exactly the same as in DATATRIEVE. The BEGIN-END form the boundaries of the compound statement. .BLANK.NO JUSTIFY.NO FILL BEGIN X = X + 1 Y = X / 3 END .BLANK 2.JUSTIFY.FILL IF-THEN-ELSE Statement: .BLANK Although the IF-THEN-ELSE statement within the PLOT Package may appear to be the same as in DATATRIEVE, it is ^¬\&. The difference is that an ELSE may begin a statement line. Thus it is possible to easily create n-way branching logic without the use of BEGIN-END statements as illustrated in the following examples: .BLANK.NO JUSTIFY.NO FILL IF X < 5 THEN BEGIN X = X + 1 Y = X * X END ELSE Y = X * 3 .BLANK or .BLANK 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" .BLANK 2.JUSTIFY.FILL PRINT Statement: .BLANK 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 re-execute 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: .LEFT MARGIN +36 .BLANK.INDENT -36 RELEASE__SEGMENTS##################- initialize all segments .BREAK.INDENT -36 CLEAR__SEGMENT N###################- initialize segment N .BREAK.INDENT -36 SET__SEGMENT N###################- cause all output from the PRINT statements to go into segment N .BREAK.INDENT -36 OUTPUT__SEGMENT#N[,N2[,N3#.#.#.]]##- transfer the contents of segments N, N2, N3, etc. to the display terminal. That is, actually perform the output. .LEFT MARGIN -36 .BLANK 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: .BLANK.LEFT MARGIN +18 .INDENT -18 $###############- special symbol for .BLANK.INDENT -18 CLRSCR##########- clear screen escape sequence .BLANK.INDENT -18 ENTER__REGIS(1)##- enter ReGIS mode escape sequence .BLANK.INDENT -18 EXIT__REGIS######- exit ReGIS mode escape sequence .BLANK.INDENT -18 RESTORE__VT125###- special ReGIS code sequence which sets the four (black and white) intensity levels to 0, 33, 66, and 100%. .LEFT MARGIN -18 .BLANK 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: .BLANK PRINT $,'<',CLRSCR,ENTER__REGIS(1),'S(m0(l0)1(l33)2(l66)3(l100))' .BREAK PRINT 'P',LXY(X__AXIS+1,Y__POS),'V(W(P4I(0)))',RX(LINE__LEN) .BLANK 2 PLOT Statement: .BLANK 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: .BLANK PLOT LABEL 2 (X__MIN, Y__MIN, X__VECTOR) .BREAK PLOT HOUSEKEEP 0 .BREAK .BLANK 2 SORT Statement: .BLANK Although the SORT statement looks like a function, it is a statement which performs a sorting operations on the specified array or arrays. Upon return from this statement, the arrays have been re-ordered 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 re-order all arrays specified. SORT takes one to four arrays as arguments. Examples are: .BLANK DECLARE VECTOR X, Y1, Y2, Y3 .BREAK DECLARE VECTOR DATE .BLANK SORT (X, Y1, Y2, Y3) .BREAK SORT DESCENDING (DATE, Y1) .BLANK 2 INCREMENT Statement: .BLANK Since the PLOT Package contains arrays (which DATATRIEVE doesn't have), a DO-LOOP mechanism (which DATATRIEVE doesn't really need) is implemented. The INCREMENT statement takes on two forms. The first form is .BLANK.NO JUSTIFY.NO FILL INCR loop-variable FROM start-variable TO stop-variable .BLANK and .BLANK INCR loop-variable OVER array-name .BLANK This second form is equivalent to .BLANK INCR loop-variable FROM 1 TO SIZE(array-name) .BLANK Examples of the INCREMENT statement are: .BLANK INCR INDEX OVER VALUES VALUES(INDEX) = VALUES(INDEX)/COUNT(INDEX) .BLANK and .BLANK INCR I FROM Y__ORIGIN TO TOP - 1 INCR J FROM 1 TO 9 BEGIN POINT = J * 10 ** I . . . END .JUSTIFY.FILL .BLANK 2 WHILE Statement: .BLANK 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: .BLANK.NO JUSTIFY.NO FILL WHILE DATE__COM(SCRATCH__VALUE) < MAX__VALUE BEGIN . . . END .JUSTIFY.FILL .LEFT MARGIN -5 .BLANK 2 Operators and Expressions: .PARAGRAPH 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. .PARAGRAPH 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. .BLANK 2 Functions: .PARAGRAPH 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: .LEFT MARGIN +12 .BLANK.INDENT -12 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. .BLANK.INDENT -12 CVT######-#CVT takes a REAL number as a parameter and returns it as a string. .BLANK.INDENT -12 COS######-#COS takes a REAL number in degrees and returns the REAL cosine. .BLANK.INDENT -12 INT######-#INT takes a REAL number and return a REAL number which has the value of the nearest integer. .BLANK.INDENT -12 LENGTH###-#LENGTH takes a STRING and return a REAL number which is the length of the string. .BLANK.INDENT -12 LOG######-#LOG takes a REAL number and returns the REAL natural log of the number. .BLANK.INDENT -12 LX#######-#LX takes one REAL X coordinate and returns the string representing the absolute ReGIS coordinates [X]. .BLANK.INDENT -12 LXY######-#LXY takes the REAL X and Y coordinates and returns the string representing the absolute ReGIS coordinates [X,Y]. .BLANK.INDENT -12 LY#######-#LY takes one REAL Y coordinate and returns the string representing the absolute ReGIS coordinate [,Y]. .BLANK.INDENT -12 MAX######-#MAX takes an array as a parameter and returns the maximum value of its elements. .BLANK.INDENT -12 MIN######-#MIN takes an array as a parameter and returns the minimum value of its elements. .BLANK.INDENT -12 QUOTE####-#QUOTE takes a STRING as a parameter and returns the string in a form for inserting it into a ReGIS command. .BLANK.INDENT -12 RX#######-#RX takes one REAL X coordinate and returns the string representing the relative ReGIS coordinates [+X]. .BLANK.INDENT -12 RXY######-#RXY takes two REAL X and Y coordinate and returns the string representing the relative ReGIS coordinates [+X,+Y]. .BLANK.INDENT -12 RY#######-#RY takes one REAL Y coordinate and returns the string representing the relative ReGIS coordinate [,+Y]. .BLANK.INDENT -12 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. .BLANK.INDENT -12 SIN######-#SIN takes a REAL number in degrees and returns the REAL sine. .BLANK.INDENT -12 SIZE#####-#SIZE takes an array as a parameter and returns the number of elements in the array. .BLANK.INDENT -12 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? .BLANK.INDENT -12 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. .LEFT MARGIN -12 .BLANK 2.CENTER Some New Plots .PARAGRAPH 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 right-hand margin with "<--". .BLANK.NO JUSTIFY.NO FILL 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 .JUSTIFY.FILL.PARAGRAPH 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 right-hand margin with "<--". The use of DATE__SUM is illustrated in Figures 1, 2, and 3. .BLANK.NO JUSTIFY.NO FILL 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 .JUSTIFY.FILL .PARAGRAPH 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. .BLANK.NO JUSTIFY.NO FILL 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 .JUSTIFY.FILL .PARAGRAPH 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? .PARAGRAPH 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. .BLANK 2 .CENTER Example Plots .BLANK.NO JUSTIFY.NO FILL find diskuse with acc="USER1" find diskuse with acc="USER2" plot date__y all date, blocks plot date__y all date, blocks find diskuse with acc="USER1","USER2" plot x__y__group all x, y, group plot date__sum all date, blocks .JUSTIFY.FILL .BLANK 2 .CENTER Conclusion .PARAGRAPH The VAX-DATATRIEVE 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. .BLANK 2.CENTER Acknowledgments .PARAGRAPH 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 20-31. 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. .BLANK 2.TEST PAGE 15.CENTER Discussion [The following are excerpts from the question and answers which followed the first presentation of this talk. Only a small part of the discussion is summarized here.] .PARAGRAPH 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? .BLANK Gallagher: Plots are just like any other dictionary object. Since there is no RELEASE PLOT-NAME command, you do have to exit and re-enter DATATRIEVE for your editing changes to take effect. .PARAGRAPH Hesler, Medical College of Virginia: When a new version of DTR gets installed, what happens to plots in the plot library? .BLANK 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 re-install 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. .PARAGRAPH Eric Mathew, Teradyne: Have your tried using other DATATRIEVE statements within a DEFINE PLOT? .BLANK Gallagher: Yes, I have tried a few. The statements I have given are apparently the only legal statements with the plot language. .PARAGRAPH Mathew: One comment on ReGIS code, I also played with the HARDCOPY plot, and I had to buy a manual. .BLANK 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 are all slight different. There's "ReGIS" code and then there's ReGIS code. .PARAGRAPH Doug Wegsheid: It's very important to make a complete copy of everything in the plot library. .BLANK 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. .PARAGRAPH Unknown female questioner: Is there a way to get your plots to the pen plotter? .BLANK Gallagher: The pen plotter, of course, must be able to handle ReGIS code. For a simple plot use the construct PLOT PLOT-NAME 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. .BLANK [Editor's note: it is possible to PLOT to a file (ReGIS), then transfer it to a PRO series system where an unsupported utility will translate the result to GiDis, which may then be output to the LVP-16 (Hewlett-Packard) pen plotter, but the results are not entirely satisfactory.] .PARAGRAPH 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? .BLANK 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 "[5i[4i" before the LA device physically finishes making the hardcopy. This problem is discussed and solved in the Wombat Examiner, Volume 6, Number 4, pages 42-44. .PAGE.CENTER DOWN the Calling Tree .NO JUSTIFY.NO FILL .BLANK BAR__2 DATE__LOGY__2 HISTO__2 LOGX__Y__2 DRAW__BAR__0 HOUSEKEEP__2 DRAW__BAR__0 HOUSEKEEP__2 DRAW__BAR__2 LABEL__5 DRAW__BAR__2 LABEL__3 HOUSEKEEP__0 LABEL__11 HOUSEKEEP__0 LABEL__10 HOUSEKEEP__2 LABEL__6 HOUSEKEEP__2 LABEL__11 LABEL__0 LABEL__14 LABEL__0 LABEL__4 LABEL__13 LABEL__8 LABEL__13 LABEL__12 LABEL__15 DATE__Y__0 LABEL__15 LABEL__14 LABEL__3 HOUSEKEEP__0 LABEL__3 LABEL__8 LABEL__10 LABEL__0 LABEL__10 LR__0 LABEL__11 LABEL__13 LABEL__11 HOUSEKEEP__2 LABEL__8 DATE__Y__2 LABEL__8 HOUSEKEEP__4 BAR__AVERAGE__2 HOUSEKEEP__2 LABEL__0 LABEL__7 DRAW__BAR__0 LABEL__3 LABEL__13 LABEL__13 DRAW__BAR__2 LABEL__10 LABEL__2 MAP__2 HOUSEKEEP__0 LABEL__11 LABEL__10 HOUSEKEEP__2 HOUSEKEEP__2 LABEL__6 LABEL__12 MONITOR__0 LABEL__0 LABEL__14 LABEL__14 HOUSEKEEP__0 LABEL__13 LABEL__8 LABEL__3 HOUSEKEEP__2 LABEL__15 DRAW__BAR__2 LABEL__10 MULTI__BAR__0 LABEL__3 HOUSEKEEP__0 LABEL__11 HOUSEKEEP__0 LABEL__10 HOUSEKEEP__2 LABEL__4 LABEL__0 LABEL__11 LABEL__0 LABEL__12 LABEL__13 LABEL__8 LABEL__13 LABEL__14 MULTI__BAR__2 BIG__0 LABEL__15 LABEL__5 HOUSEKEEP__2 HOUSEKEEP__4 LABEL__3 LABEL__11 LABEL__10 CONNECT__0 LABEL__10 LABEL__6 LABEL__3 HOUSEKEEP__2 LABEL__11 LABEL__14 LABEL__10 HOUSEKEEP__4 LABEL__8 LABEL__7 LABEL__11 LABEL__9 DRAW__BAR__3 LABEL__13 LABEL__8 CROSS__HATCH__0 DRAW__BAR__2 LEGEND__0 LEGEND__3 HOUSEKEEP__2 HOUSEKEEP__0 HOUSEKEEP__2 LEGEND__5 DATE__FREQ__0 HOUSEKEEP__2 LEGEND__3 X__LABEL__0 HOUSEKEEP__0 LABEL__0 LEGEND__5 MULTI__BAR__GROUP__0 LABEL__0 LABEL__13 LEGEND__4 HOUSEKEEP__0 LABEL__13 LABEL__15 LEGEND__5 LABEL__0 DATE__FREQ__2 LABEL__3 LOGX__LOGY__0 LABEL__13 HOUSEKEEP__2 LABEL__10 HOUSEKEEP__0 MULTI__BAR__GROUP__2 LABEL__3 LABEL__11 LABEL__0 HOUSEKEEP__2 LABEL__10 LABEL__8 LABEL__13 LABEL__10 LABEL__11 DRAW__PIE__0 LOGX__LOGY__2 LABEL__3 LABEL__6 HOUSEKEEP__0 HOUSEKEEP__2 LABEL__10 LABEL__14 HOUSEKEEP__2 LABEL__4 LABEL__11 LABEL__8 HARDCOPY__0 LABEL__12 LABEL__8 DATE__LOGY__0 HOUSEKEEP__2 LABEL__14 LEGEND__3 HOUSEKEEP__0 HOUSEKEEP__4 LABEL__5 LEGEND__5 LABEL__0 HATCH__0 LABEL__11 X__LABEL__0 LABEL__13 HOUSEKEEP__2 LABEL__8 MULTI__LINE__0 LOGX__Y__0 HOUSEKEEP__0 HOUSEKEEP__0 LABEL__0 LABEL__0 LABEL__13 LABEL__13 .PAGE MULTI__LINE__2 , NEXT__BAR__0 SORT__BAR__0 X__LOGY__0 HOUSEKEEP__2 DRAW__BAR__2 DRAW__BAR__3 HOUSEKEEP__0 LABEL__2 HOUSEKEEP__0 DRAW__BAR__2 LABEL__0 LABEL__10 HOUSEKEEP__2 HOUSEKEEP__0 LABEL__13 LABEL__12 LABEL__0 HOUSEKEEP__2 X__LOGY__2 LABEL__14 LABEL__13 LABEL__0 HOUSEKEEP__2 LABEL__3 LABEL__15 LABEL__15 LABEL__2 LABEL__10 LABEL__3 LABEL__3 LABEL__10 LABEL__11 LABEL__10 LABEL__8 LABEL__12 LEGEND__4 LABEL__11 STACKED__2 LABEL__14 LEGEND__5 LABEL__8 HOUSEKEEP__0 LABEL__5 MULTI__LINE__3 OUTSTANDING__0 HOUSEKEEP__2 LABEL__11 LABEL__8 HOUSEKEEP__0 LABEL__0 LABEL__8 MULTI__LINE__3 LABEL__0 LABEL__13 X__Y__0 LABEL__8 LABEL__13 LABEL__3 HOUSEKEEP__0 MULTI__LR__0 OUTSTANDING__2 LABEL__10 LABEL__0 HOUSEKEEP__0 HOUSEKEEP__2 LABEL__11 LABEL__13 LABEL__0 LABEL__3 LEGEND__0 X__Y__2 LABEL__13 LABEL__10 HOUSEKEEP__2 HOUSEKEEP__2 MULTI__LR__2 LABEL__11 STACKED__3 LABEL__2 HOUSEKEEP__2 LABEL__6 STACKED__BAR__0 LABEL__10 LABEL__2 LABEL__14 HOUSEKEEP__0 LABEL__12 LABEL__10 LABEL__8 LABEL__0 LABEL__14 LABEL__12 PIE__2 LABEL__13 LABEL__3 LABEL__14 DRAW__PIE__0 STACKED__BAR__2 LABEL__10 LABEL__3 HOUSEKEEP__0 HOUSEKEEP__2 LABEL__11 LABEL__10 HOUSEKEEP__2 LABEL__3 LABEL__8 LABEL__11 RAW__BAR__2 LABEL__10 LEGEND__4 DRAW__BAR__0 LABEL__11 LEGEND__5 DRAW__BAR__2 LABEL__8 MULTI__LR__3 HOUSEKEEP__0 LEGEND__3 LABEL__7 HOUSEKEEP__2 LEGEND__5 LABEL__13 LABEL__0 X__LABEL__0 LABEL__8 LABEL__13 VALUE__PIE__2 MULTI__LR__3 LABEL__15 DRAW__PIE__0 LABEL__7 LABEL__3 HOUSEKEEP__0 LABEL__13 LABEL__10 HOUSEKEEP__2 LABEL__8 LABEL__11 WOMBAT__0 MULTI__SHADE__0 LABEL__8 HOUSEKEEP__0 HOUSEKEEP__0 RAW__PIE__2 HOUSEKEEP__2 LABEL__0 DRAW__PIE__0 X__FREQ__0 LABEL__13 HOUSEKEEP__0 HOUSEKEEP__0 MULTI__SHADE__2 HOUSEKEEP__2 LABEL__0 HOUSEKEEP__2 RE__PAINT__0 LABEL__13 LABEL__3 HOUSEKEEP__4 X__FREQ__2 LABEL__10 RE__PAINT__2 HOUSEKEEP__2 LABEL__11 HOUSEKEEP__2 LABEL__2 LABEL__8 SHADE__0 LABEL__10 LEGEND__3 HOUSEKEEP__2 LABEL__12 LEGEND__5 HOUSEKEEP__4 LABEL__14 X__LABEL__0 LABEL__9 LABEL__3 LABEL__10 LABEL__11 LABEL__8 .PAGE.CENTER UP the Called Tree .NO JUSTIFY.NO FILL DRAW__BAR__0 HOUSEKEEP__2 LABEL__10 LABEL__11 BAR__2 CONNECT__0 LABEL__2 LABEL__3 BAR__AVERAGE__2 CROSS__HATCH__0 MULTI__LINE__2 DATE__FREQ__2 HISTO__2 DATE__FREQ__2 MULTI__LR__2 DATE__Y__2 RAW__BAR__2 DATE__LOGY__2 X__FREQ__2 DRAW__BAR__2 HOUSEKEEP__0 DATE__Y__2 X__LOGY__2 BAR__2 DATE__FREQ__0 DRAW__BAR__2 X__Y__2 BAR__AVERAGE__2 DATE__LOGY__0 BAR__2 LABEL__3 DRAW__BAR__3 DATE__Y__0 BAR__AVERAGE__2 DATE__FREQ__2 HISTO__2 DRAW__BAR__2 DRAW__BAR__3 DATE__Y__2 NEXT__BAR__0 BAR__2 SORT__BAR__0 DRAW__BAR__2 RAW__BAR__2 BAR__AVERAGE__2 HISTO__2 BAR__2 LOGX__Y__2 DRAW__BAR__3 NEXT__BAR__0 BAR__AVERAGE__2 MULTI__BAR__2 SORT__BAR__0 RAW__BAR__2 DRAW__BAR__3 MULTI__BAR__GROUP__2 HISTO__2 DRAW__PIE__0 HISTO__2 MULTI__LINE__2 NEXT__BAR__0 PIE__2 NEXT__BAR__0 MULTI__LR__2 RAW__BAR__2 RAW__PIE__2 RAW__BAR__2 MULTI__SHADE__2 DRAW__PIE__0 VALUE__PIE__2 LOGX__Y__2 OUTSTANDING__2 PIE__2 HARDCOPY__0 MULTI__BAR__2 STACKED__2 RAW__PIE__2 HATCH__0 MULTI__BAR__GROUP__2 STACKED__BAR__2 VALUE__PIE__2 LEGEND__0 MULTI__LINE__2 X__FREQ__2 LOGX__LOGY__0 STACKED__2 MULTI__LR__2 X__Y__2 LOGX__Y__0 LOGX__LOGY__2 MULTI__SHADE__2 LABEL__5 MONITOR__0 LOGX__Y__2 OUTSTANDING__2 DATE__LOGY__2 MULTI__BAR__0 LR__0 STACKED__2 LOGX__LOGY__2 MULTI__BAR__GROUP__0 MAP__2 STACKED__BAR__2 X__LOGY__2 MULTI__LINE__0 MONITOR__0 X__FREQ__2 LABEL__12 MULTI__LR__0 MULTI__BAR__2 X__Y__2 LABEL__2 MULTI__SHADE__0 MULTI__BAR__GROUP__2 MULTI__BAR__2 MULTI__LINE__2 OUTSTANDING__0 MULTI__LINE__2 MULTI__BAR__GROUP__2 MULTI__LR__2 STACKED__2 MULTI__LR__2 X__FREQ__2 STACKED__BAR__0 MULTI__SHADE__2 X__LOGY__2 WOMBAT__0 OUTSTANDING__2 X__Y__2 X__FREQ__0 RE__PAINT__2 LABEL__4 X__LOGY__0 SHADE__0 LOGX__LOGY__2 X__Y__0 STACKED__2 LOGX__Y__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__0 .PAGE LABEL__13 LABEL__13 (cont'd) LABEL__15 (con'd) LABEL__8 (cont'd) LABEL__0 LABEL__7 HISTO__2 MULTI__LR__3 DATE__FREQ__0 LR__0 NEXT__BAR__0 MULTI__LR__2 DATE__LOGY__0 MULTI__LR__3 RAW__BAR__2 MULTI__SHADE__2 DATE__Y__0 MULTI__LR__2 LABEL__3 OUTSTANDING__2 DRAW__BAR__2 LABEL__14 DRAW__BAR__2 STACKED__BAR__2 BAR__2 LABEL__2 DRAW__BAR__3 X__FREQ__2 BAR__AVERAGE__2 MULTI__LINE__2 SORT__BAR__0 X__LOGY__2 DRAW__BAR__3 MULTI__LR__2 LABEL__8 X__Y__2 HISTO__2 X__FREQ__2 DATE__FREQ__2 LABEL__9 NEXT__BAR__0 X__LOGY__2 DATE__LOGY__2 CONNECT__0 RAW__BAR__2 X__Y__2 DATE__Y__2 SHADE__0 LOGX__LOGY__0 LABEL__4 DRAW__BAR__2 LEGEND__5 LOGX__Y__0 LOGX__LOGY__2 BAR__2 LEGEND__3 MULTI__BAR__0 LOGX__Y__2 BAR__AVERAGE__2 MULTI__BAR__2 MULTI__BAR__GROUP__0 LABEL__6 DRAW__BAR__3 MULTI__BAR__GROUP__2 MULTI__LINE__0 DATE__FREQ__2 SORT__BAR__0 MULTI__SHADE__2 MULTI__LR__0 DATE__LOGY__2 HISTO__2 STACKED__BAR__2 MULTI__SHADE__0 DATE__Y__2 NEXT__BAR__0 LEGEND__4 OUTSTANDING__0 OUTSTANDING__2 RAW__BAR__2 MULTI__LINE__2 STACKED__2 LABEL__15 LOGX__LOGY__2 MULTI__LR__2 STACKED__BAR__0 DRAW__BAR__2 LOGX__Y__2 STACKED__3 X__FREQ__0 BAR__2 MULTI__BAR__2 STACKED__2 X__LOGY__0 BAR__AVERAGE__2 MULTI__BAR__GROUP__2 X__LABEL__0 X__Y__0 DRAW__BAR__3 MULTI__LINE__3 MULTI__BAR__2 SORT__BAR__0 MULTI__LINE__2 MULTI__BAR__GROUP__2 MULTI__SHADE__2 STACKED__BAR__2 .PAGE.CENTER PLOTNAME vs SEGMENTS .NO JUSTIFY.NO FILL _\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 | | .PAGE.CENTER Segments Access by Plots .NO JUSTIFY.NO FILL 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