|
|
|
|
||
|
DEFINITION MODULE DM2DGraphs; (******************************************************************* Module DM2DGraphs ('Dialog Machine' DM_V3.0) Copyright (c) 1986-2006 by Alex Itten, Andreas Fischlin, Olivier Roth and ETH Zurich. Purpose Library module for two dimensional lineplots and/or scattergrams. Remarks An unlimited number of graphs (coordinate systems) in different or the same windows can be used, each one with its own scaling. The module supports linear and logarithmic scaling for both dimensions, multiple curves in the same graph with different plotting styles and it offers a mechanism for labeling each axis, avoiding label collisions and computes a reasonable distance for tick marks. It is possible to make scatterplots, lineplots and combinations of them. Usage: Define as many graphs as you wish in an already existing window (see DMWindows). Define the scale by passing minimum and maximum values. For each graph you may specify subsequently one or more curves with their own line types for later plotting. Each curve is connected with a particular graph, each graph is associated with a window. After declarations of graphs and curves you may use various procedures to draw actually into the graphs. It is also possible to alter a graph's axes and its position and to redefine attributes of curves. A simple method is offered to add a legend to a graph. This module is based on DMWindIO. It supports the autoupdating mechanism of this module. It changes the current pen position and the clipping rectangle. This module belongs to the 'Dialog Machine'. Programming o Design Alex Itten 21/10/1986 o Implementation Alex Itten 21/10/1986 Andreas Fischlin 20/08/1987 Olivier Roth 09/09/1989 ETH Zurich Systems Ecology CHN E 35.1 Universitaetstrasse 16 8092 Zurich SWITZERLAND URLs: <mailto:RAMSES@env.ethz.ch> <http://www.sysecol.ethz.ch> <http://www.sysecol.ethz.ch/SimSoftware/RAMSES> Last revision of definition: 19/04/1996 AF & DG *******************************************************************) FROM DMWindows IMPORT Window, RectArea; FROM DMWindIO IMPORT Color; TYPE Graph; (* Variables of this type identify particular graphs. Declare variables of this type always (!) on a global level, since the graph management routines attempt to update your variables. E.g. when removing a graph by using the procedures RemoveGraph or RemoveAllGraphs, "DM2DGraphs" assigns to your graph variable the value notExistingGraph. It is a recommended practice to assign notExistingGraph to your variables of type Graph for initial- ization. *) Curve; (* In every graph may be defined an unlimited number of different curves. These curves are associated with a particular graph. Variables of this type are used to reference the object Curve. Declare variables of this type always (!) on a global level, since the graph management routines attempt to update your variables. E.g. when removing a graph by using the procedures RemoveCurve, RemoveGraph or RemoveAllGraphs the "DM2DGraphs" assigns to all associated curve variables the value notExistingCurve. It is a recommended practice to assign notExistingCurve to your variables of type Curve for initialization. *) LabelString = ARRAY[0..255] OF CHAR; (* Each axis of a graph has its own label, which will be displayed for the horizontal axis below the right end and for the vertical axis to the right of the top left corner of the graph area. *) GridFlag = (withGrid,withoutGrid); (* Specifies whether a grid of auxiliary lines is drawn in the data area. A gridline is drawn at every labeled tick mark. *) ScalingType = (lin, log, negLog); (* The scaling of each axis may be linear or logarithmic independently from the other. negLog produces logarithmic scaling for data values less or equal to zero. *) PlottingStyle = (solid, slash, slashDot, dots, hidden, wipeout); (* Each curve may have its own plotting style. Style hidden may be used to produce scatter plots, wipeout to erase a previously plotted curve by redrawing it with this style. *) Range = RECORD min,max : REAL END; (* This type is used to specify a range. For example the range of the x and y axis. *) AxisType = RECORD range : Range; scale : ScalingType; dec : CARDINAL; tickD : REAL; label : LabelString; END; (* An axis is fully defined by the attributes of AxisType. dec defines the number of digits after the decimal point, and tickD specifies the distance between two tick marks on the axis and between the gridlines. dec may not be greater than 5, otherwise it will be set to 5. If tickD is too small, so there is not enough room to write the values, a multiple of tickD is used as distance between labeled tick marks. If tickD is zero, a default tickD will be calculated automatically. The label of the x axis will be written in the lower right corner of the graph and the label of the y axes will be written in the upper left corner.*) VAR DM2DGraphsDone: BOOLEAN; (* This variable is TRUE if the critical routines of this module have succeeded. The following routines may not succeed: DefGraph - window does not exist or not enough memory. RedefGraph - graph does not exist. DefCurve - " " " " RedefCurve - " or curve do not exist. Plot - If calculated point lies outside the integer (pixel) range. PlotCurve - " " " " " " " " " Move - " " " " " " " " " GraphToWindowPoint- " " " " " " " " " WindowToGraphPoint- " " " " " " real graph " *) VAR notExistingGraph: Graph; notExistingCurve: Curve; (* Read only variables which may be used for variables of type Graph (Curve) to denote that the associated object is actually not existing, i.e. allocated. It is a good programming practice to assign this value to all variables during the initialization phase of the "Dialog Machine", i.e. before calling procedure DMMaster.RunDialogMachine. *) PROCEDURE GraphExists( g: Graph ) : BOOLEAN; (* Returns TRUE if the graph g exists otherwise FALSE *) PROCEDURE CurveExists( g: Graph; c: Curve ) : BOOLEAN; (* Returns TRUE if the curve c exists associated with graph g otherwise FALSE (new in DM_V1.1). *) PROCEDURE DefGraph( VAR g: Graph; u: Window; r: RectArea; xAxis, yAxis: AxisType; grid: GridFlag); (* You may define multiple graphs in different or the same windows. Each graph is permanently associated with window u; all other parameters may be changed with procedure RedefGraph. r defines the rectangle area to which the graph is drawn including axis, all labels and marks. This area is affected by the procedures ClearGraph and DrawGraph. With xAxis and yAxis specify the attributes of the horizontal (x) and vertical (y) axis. The label of the x axis will be drawn below the lower right end of the x axis and the label of the y axis over the upper left corner of the data area. The variable grid indicates whether or not a grid should be drawn. *) PROCEDURE SetNegLogMin( nlm: REAL ); (* Sets nlm as the minimum value for the linear transformation (applied before logarithmic transformation) if ScalingType negLog is used. nlm must be > 0.0, otherwise setting is ignored. (nlm initially set to 0.01). *) PROCEDURE DefCurve( g: Graph; VAR c: Curve; col: Color; style: PlottingStyle; sym: CHAR ); (* Every curve has it own plotting style and color.This allows for the simultaneous drawing of an arbitrary number of curves within the same graph. sym specifies a character which is drawn at each new data point, they help identifying a curve (sym = 0C, no mark is plotted). If c already exists the curve c is redefined (as RedefGraph). *) PROCEDURE RedefGraph( g: Graph; r: RectArea; xAxis,yAxis :AxisType; grid: GridFlag ); (* Alters attributes of already existing graphs (except for the associated window). *) PROCEDURE RedefCurve( c: Curve; col: Color; style: PlottingStyle; sym: CHAR ); (* Use this procedure if you want to alter an already existing curve. *) PROCEDURE ClearGraph( g: Graph ); (* Clears the rectangle occupied by graph g with the current windows background color and pattern *) PROCEDURE DrawGraph( g: Graph ); (* Draws graph g, the axis including all ticks, tick marks and optionally the grid. Ticks, tick marks and grid lines are automatically calculated and fitted into the drawing rectangle in order to yield optimal results. The pen is set to the origin of the defined coordinate system. This procedure changes the current output window to the graph's window. No action takes place if this window does not exist. *) TYPE GraphProc = PROCEDURE(Graph); PROCEDURE DoForAllGraphs( u: Window; gp: GraphProc ); (* To clear or draw to every existing graph associated with window u, call this procedure with the respective GraphProc ClearGraph or DrawGraph *) PROCEDURE DrawLegend( c: Curve; x,y: INTEGER; comment: ARRAY OF CHAR ); (* Draws a portion of curve c with the current attributes at position x and y and writes the comment to the right of c. After this procedure the pen location is just to the right of the string "comment", so it's possible to add for example values of parameters by calling DMWindIO procedures WriteReal (etc.) just after this procedure. *) PROCEDURE RemoveGraph( VAR g: Graph ); (* This procedure removes a graph definition and all associated objects, such as e.g. curves. It clears the rectangle area which was occupied by the graph. This module sets g and the values of all associated curve variables to notExistingGraph. WARNING: make sure that not only variable g but also all variables for attached curve objects are declared globally and therefore still exist when calling this procedure. *) PROCEDURE RemoveAllGraphs( u: Window ); (* Calls repeatedly the procedure RemoveGraph for all defined Graphs associated with window u. Typically this procedure is called within a MouseHandler of type CloseWindow (see DMMaster or DMWindows). *) PROCEDURE RemoveCurve( VAR c: Curve ); (* This procedure removes a curve definition and all associated objects. This procedure sets c to notExistingCurve. *) PROCEDURE SetGapSym(gapSym: CHAR); PROCEDURE GetGapSym(VAR gapSym: CHAR); (* These procedures allow to control the symbol which is used by Plot or PlotCurve while missing values are encountered. Note that whenever the coordinates x,y of a point have the value undefREAL (from module DMConversions), that DM2DGraphs stops drawing until it encounters again a well defined point (i.e. x<>undefREAL AND y<>undefREAL). The result may be a curve with gaps. Now note that a curve may consist of several gaps, eventually having inbetween just a single, isolated point. Since DM2Graphs draws for every defined point,at least a dot of one pixel size, an isolated point is at least visible in form of a single pixel. But a dot is easily overlooked, in particular on larger screens. If the curve is to be drawn with a symbol, i.e. sym<>0C, there is no problem to see such isolate points, since DM2DGraphs draws them with the symbol specified for the curve. However, if the curve draws just lines, the visibility of such curves becomes a problem. To avoid this problem, DM2DGraphs uses the special gap symbol gapSym to improve on the visibility of such isolated points. Note that this symbol is the same for all curves. In addition, the begin as well as the end of a gap are also marked with gapSym. The default symbol is "+". You may suppress the usage of gapSym by calling SetGapSym(0C); in this case an isolated point will be drawn with a dot which is only as big as a pixel. *) PROCEDURE Plot( curve: Curve; newX,newY: REAL ); (* You can plot (draw a curve) from the last (saved) position to the point specified by the new coordinates newX and newY. Portions of the curve outside the graph's panel are automatically clipped. If either newX or newY are equal to DMConversions.undefREAL, no connecting lines are drawn (see also SetGapSym). Note: DrawGraph resets the pen position. Errors: If the point specified by newX and newY lies outside the integer (pixel) range DM2DGraphsDone will be set to FALSE. If you use this procedure in a loop (e.g. during a simulation run) test the variable DM2DGraphsDone repeatedly in order to detect such an error condition and to eventually abort the simulation. *) PROCEDURE Move( c: Curve; x,y: REAL ); (* moves the pen to position (x,y). Typically used at the begin of a sequence of calls to routine Plot or to reset the pen position (without any drawing) after having drawn a curve. Errors: If the point specified by x and y lies outside the integer (pixel) range DM2DGraphsDone will be set to FALSE. *) PROCEDURE PlotSym( g: Graph; x,y: REAL; sym: CHAR ); (* draws the symbol sym at the position (x,y). May be used as an alternate method to make scatter grams. Errors: If the point specified by x and y lies outside the integer (pixel) range DM2DGraphsDone will be set to FALSE. *) PROCEDURE PlotCurve( c: Curve; nrOfPoints: CARDINAL; x,y: ARRAY OF REAL ); (* Plots an entire sequence of nrOfPoints coordinate pairs contained within the two vectors x and y. Otherwise the same rules apply as to routine Plot (see above). May also be useful to implement an update mechanism. Errors: - If the point specified by x and y lies outside the integer (pixel) range DM2DGraphsDone will be set to FALSE. - If the maximum number of elements of x or y is less than nrOfPoints, then only the lower number of elements of either x or y will be plotted. *) PROCEDURE GraphToWindowPoint( g: Graph; xReal,yReal: REAL; VAR xInt,yInt: INTEGER ); (* Calculates the pixel coordinates (xInt and yInt) of the Graph's window (see also DMWindIO) from the specified graph Point (given by xReal and yReal). Errors: If the point specified by xReal and yReal lies outside the integer (pixel) range, DM2DGraphsDone will be set to FALSE and xInt and yInt are set to MIN(INTEGER) or MAX(INTEGER) respectively. *) PROCEDURE WindowToGraphPoint( g: Graph; xInt,yInt: INTEGER; VAR xReal,yReal: REAL ); (* Converts pixel coordinates (xInt, yInt) of the graph's window (see also DMWindIO) to graph coordinates (xReal, yReal) of the graph g (is inverse of GraphToWindowPoint) (new in DM_V1.1). Errors: If the point specified by xInt and yInt lies outside the integer (pixel) range, DM2DGraphsDone will be set to FALSE and xReal and yReal are set to MIN(REAL) or MAX(REAL) respectively. *) END DM2DGraphs.
|
||
|
|
|