ETHZ_Logo RAMSES_Logo_Right   RAMSES   RAMSES_Logo_Left Systems Ecology  
Start    search button      Modules:   A-Z   Function   Layer        QuickRefs:   DM   AuxLib   AuxLibE   SciLib   EasyMW   MW   ISIS   RMSLib

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.

  Contact RAMSES@env.ethz.ch Last updated: 25-Jul-2011 [Top of page]