Native graph plotting

In this section:

The option [native] is available with %pl (SIMPLEPLOT Graphics Region) for 32-bit applications. It may also be used for 64-bit applications where it becomes the default. The graph plotting for native %pl is provided by ClearWin+ and does not use the external 32-bit SIMPLEPLOT library/DLL.

The only limitation of native %pl is that the option [user_drawn] is not available. However, the user is able to draw directly to a native %pl graph as outlined below.

The native %pl uses the same "drawing surface" as %GR and automatically uses the smoothing features of GDI+. This results in new options that allow graphs to be drawn using such features as anti-aliasing.

A native %pl inherits...

  a) the current font from %fn (Font);
  b) the font style from %it (Italic) etc.;
  c) the font size from %ts (Text Size);
  d) the text colour from %tc (Text Colour); and
  e) the background colour from %`bg.

A title is drawn using the current font size. The x and y captions use a slightly reduced font size, whilst the numbers at the tick marks are reduced a little further.

The style options [style=0] (link data points with lines) and [style=1] (draw box symbols at data points) are still provided but new options "link" and "symbol" are preferred...

   [link=none]    Don't join data points.
   [link=lines]   Join data points with straight lines (the default).
   [link=curves]  Join data points with curves.
   [link=columns] Join columns from the x-axis to the data points.
   [link=bars]    Join bars from the y-axis to the data points.
   [symbol=0]     Don't draw symbols at data points (the default).
   [symbol=1]     Draw boxes.
   [symbol=2]     Draw triangles.
   [symbol=3]     Draw up-side-down triangles.
   [symbol=4]     Draw rhombuses.
   [symbol=5]     Symbols 2 and 3 together.
   [symbol=6]     Draw filled boxes.
   [symbol=7]     Draw filled triangles.
   [symbol=8]     Draw filled up-side-down triangles.
   [symbol=9]     Draw filled rhombuses.
   [symbol=10]    Draw circles.
   [symbol=11]    Draw discs.
   [symbol=12]    Draw pluses
   [symbol=13]    Draw Xs

Native options that are set once for each %pl
(d represents a decimal digit, fval is a floating point number).

[native] Uses ClearWin+ rather than the SIMPLEPLOT DLL.
[width=d] Specifies the line width (default 1).
[symbol_size=d] Specifies the size of symbols (default 8x8). This can be used for each graph in turn or just once to change all graphs.
[smoothing=d] Specifies the smoothing mode,where d is in the range 0 to 5 .
(default 0, 4 and 5 provide for anti-aliasing).
[dx=fval] Specifies the preferred interval between x tick marks.
[dy=fval] Specifies the preferred interval between y tick marks.
dx and dy are only for linear scales and will not always be adopted.
[x_sigfigs=d] Specifies the number of significant figures to use when drawing the numbers at the x tick marks (default 2).
[y_sigfigs=d] Specifies the number of significant figures to use when drawing the numbers at the y tick marks (default 2).
[independent] Specifies that x-data values differ from one graph to the next. See below.
[framed] Adds a box with tick marks as a frame.
[frame] Like [framed] but draws the xy-axis caption and tick values outside of the frame
[x_max=fval] Specifies the maximum x data value.
[x_min=fval] Specifies the minimum x data value.
[margin=d] Specifies the margin value in pixels for all margins.
[margin=(d,d,d,d)] Specifies values in pixels for the left, top, right and bottom margins.
[axes_pen=d] Specifies the pen width for the axes (value must be 2,3 or 4).
[tick_len=d] Specifies the length of the tick marks.
[fixed_aspect] Maintains the initial aspect ratio as the window is resized.
[external_ticks] Implies [framed] and draws tick marks externally to the frame.
[gridlines] Provides a rectangular grid based on tick marks.
[stacked] Treats the y data for different graphs as one large array with the values for the second graph added to the end of those for the first and so on (similarly for independent x arrays). If each graph has the same number of points then this is equivalent to using a 2-dimensional array with the data values in the first dimension and the index ranging from 1 to n_graphs in the second dimension.
[external] The image does not have an associated parent window but is drawn to the current graphics object. The image could for example be drawn to an existing %gr (Graphics Region) object or via a call to open_printer@. Printers typically have a relatively high resolution so %pl[external] automatically adjusts certain default values (e.g. various line widths) in order to compensate. See also: PRINT_GRAPHICS@
Can be used with the native %pl as for %gr (Graphics Region). Related routines such as set_graphics_selection@ and get_graphics_selected_area@ may also be used.
[hscroll], [vscroll]

Adds scrolling options. Previously %vx and %hx could be used with %pl but provided scroll bars as separate controls. The new options create scroll bars that are built into the control and as a result have all of the expected "hot track" characteristics of a scroll bar.

%pl[hscroll] uses the same data as %hx whilst %pl[vscroll] uses the same data as %vx. This is accommodated by presenting %hx with its data before %pl[hscroll] and %vx with its data before %pl[vscroll]. The only restriction is that the %hx and %vx information must not include callback functions. For example:

integer iw,page,range,pos
iw = winio@("%vx&", page, range, pos)
iw = winio@("%^pl[vscroll]",400,250,N,x,y,cb)

The values used for 'page' and 'range' determine the y offset of the origin when drawing to the graphics region. Typically the adjustment could be y = y-pos*range. In this way, %gr can be used to display a snapshot of a larger graph by redrawing the area required. Alternatively a full sized graphics region could be created off-screen, with areas copied to the %gr region as required.

The option [independent] provides for independent x-data for each graph. In this case the number of data points must be presented as a variable (for one graph) or as an array (for one or more graphs) where the array index corresponds to the order in which the graphs are coded. This is also the case for the optional x-start and x-increment data. As a result, these values can be changed after a window has been formed.

Native options that are set for each graph in turn.

[pen_style=d]] Sets the dash style for each line in turn (default zero. These are the Microsoft constants PS_SOLID etc.).
[link=...] See above.
[symbol=d] See above.
[symbol_size=d] Specifies the size of symbols (default 8x8). This can be used for each graph in turn or just once to change all graphs.
[frame_pen=dval] Takes an integer dval for the pen width of the frame. This is now independent of [axes_pen=dval].
[title_hfont=hval] Takes an integer(7) hval for the HFONT of the title. hval can be obtained via %gf (Font Handle) and used in a new routine called winop_hdl@ as illustrated here...
            integer(7) hTitleFont
            iw = winio@("%fn[Verdana]%ts[1.2]%it%gf%sf&",hTitleFont)
            CALL winop_hdl@("%pl[title_hfont]",hTitleFont)
[function=fun] Takes a REAL*8 FUNCTION fun(x) with REAL*8 argument x, and uses this in place of the y array of data values as illustrated here...
            DOUBLE PRECISION x_start,dx
            CALL winop_fun@("%pl[function]",f)
            iw = winio@("%pl",400,300,N,x_start,dx)

winop_hdl@ and winop_fun@ belong to a set of routines that complement winop@. These are used to simplify the coding of options that require a dynamic value. Here is the current set:

            SUBROUTINE WINOP_INT@(fmt, dval)
            SUBROUTINE WINOP_FLT@(fmt, fval)
            SUBROUTINE WINOP_CLR@(fmt, cval) !for colours
            SUBROUTINE WINOP_STR@(fmt, sval)
            SUBROUTINE WINOP_HDL@(fmt, hval)
            SUBROUTINE WINOP_FUN@(fmt, fun)
            CHARACTER(*) fmt,sval
            INTEGER dval,cval
            DOUBLE PRECISION fval
            INTEGER(7) hval
            DOUBLE PRECISION x

In native mode, %^pl can be used to provide a callback function that will be called after ClearWin+ has drawn the graph(s). This will occur initially and (if %pv (Pivot) is used) when the window is resized. The callback function can draw directly to the graph by using %gr (Graphics Region) drawing routines such as DRAW_CHARACTERS@.

The options list for %PL can become quite long. A routine WINOP@ is provided so that the options can be preloaded one or more at a time. For example:

  call winop@("%pl[native,title=Graph]")
  call winop@("%pl[style=0,x_array]")
  i = winio@('%pl&',400,250,N,x,y)

The drawing of a graph can be delayed in one of three alternative ways:

   1) By setting all of the y-data values to zero.

   2) By setting [link=none] and using the default [symbol=0].

   3) By providing the number of data points as a variable and setting it initially to zero.

Correspondingly when the graph is required to be drawn,

   1) set the corresponding y-data values, or

   2) change the "link" value (see below), or

   3) change the number of data points

and then call SIMPLEPLOT_REDRAW@().


The following functions can be called after a window has been formed in order to change the data.

      INTEGER FUNCTION CHANGE_PLOT_INT@(id, option, index, dval)
      INTEGER FUNCTION CHANGE_PLOT_DBL@(id, option, index, fval)
      INTEGER FUNCTION CHANGE_PLOT_CHR@(id, option, index, sval)
      INTEGER id,index,dval
      CHARACTER(*) option, sval
      REAL*8 fval

id is the identifier used with %`PL and SELECT_GRAPHICS_OBJECT@. If there is only one active object then id can be set to zero.
index corresponds to the number of the graph (starting at 1). Set this to zero when the dval/fval/sval applies to all graphs.
dval, fval and sval represent the value to be changed. In two cases this will be an array.
option usually mirrors one of the %PL options and is one of:

          "x_min"     fval - for all graphs
          "x_max"     fval - for all graphs
          "y_min"     fval - for all graphs
          "y_max"     fval - for all graphs
          "dx"        fval - for all graphs
          "dy"        fval - for all graphs
          "x_axis"    sval - for all graphs
          "y_axis"    sval - for all graphs  
          "title"     sval - for all graphs
          "colour"    dval - for each graph in turn
          "pen_style" dval - for each graph in turn
          "symbol"    dval - for each graph in turn
          "link"      dval - for each graph in turn (0=none, 1=lines, 2=curves)
          "x_data"    fval x-data array which varies from one graph to the next when [independent]
          "y_data"    fval y-data array for each graph in turn

The functions return zero on success or a non-zero error code. CLEARWIN_STRING@("ERROR_REPORT") describes the cause of a failure.

The routine CLEARWIN_OPTION@ can be called in order to change the way that these errors are reported...

          CLEARWIN_OPTION@("hide_error")  ClearWin+ does not generate a direct message. This is the default.
          CLEARWIN_OPTION@("show_error")  ClearWin+ reports an error in a "message box" and continues.
          CLEARWIN_OPTION@("fatal_error") ClearWin+ reports an error in a dialog box together with a trace back and exits.   

The following routine can be called from within a %pl (SIMPLEPLOT Graphics Region) callback function in order to get the pixel coordinates of a particular point relative to the axes.

            INTEGER FUNCTION GET_PLOT_POINT@(x,y,xpix,ypix)
            REAL*8 x,y           (input values)
            REAL*8 xpix,ypix     (output values) 

There is also the inverse function GET_PLOT_DATA@. This is for use with [full_mouse_input] and gets the (x,y) values for a given point on the screen. The point is retrieved by calling clearwin_info@ using "GRAPHICS_MOUSE_X" and "GRAPHICS_MOUSE_Y".

            INTEGER FUNCTION GET_PLOT_DATA@(ix,iy,x,y)
            INTEGER ix,iy        (input values)
            REAL*8 x,y           (output values)

GET_PLOT_POINT@ and GET_PLOT_DATA@ return zero on success or a non-zero error code.


Additional notes

1. If ClearWin+ draws a title or axis caption at an inappropriate point then its position can be adjusted. For example [title=My Graph@(4.8)] using a decimal point, draws "My Graph" at a point that is adjusted 4 pixels to the right and 8 pixels down from its default position.

2. If an axis caption is not supplied then the defaults are lower case "x" and "y". Setting [x-axis=@] or [y-axis=@] prevents ClearWin+ from drawing the caption which could then be drawn using a callback function.

3. %`PL provides for a user identifier for the %PL control that can be used in a call to SELECT_GRAPHICS_OBJECT@ but this call is not needed within a %^PL callback because the corresponding object will already be selected.

4. Options like y_min, y_max and dy are intended for small adjustments to the results provided by ClearWin+. For example if the range of y was from 1 to 99, then for a better presentation you could set y_min=0.0 and y_max=100.0. Similarly if the tick marks turn out to be at intervals of 11 (say) then you could set dy=10.0.

Here are two sample programs that illustrates many of these features:

Example 1

      USE clrwin 
      INTEGER N,i
      REAL*8 x(N),y(N)
      DO i=1,N
      CALL winop@("%pl[title=Graph]")
      CALL winop@("%pl[width=2]")
      CALL winop@("%pl[y_max=0.9]")
      CALL winop@("%pl[x_array]")
      CALL winop@("%pl[link=curves]")
      CALL winop@("%pl[symbol=9]")
      CALL winop@("%pl[colour=red]")
      CALL winop@("%pl[pen_style=2]")

Example 2

      MODULE mydata
        USE clrwin
        LOGICAL shown
        INTEGER errstate
        errstate = change_plot_int@(0,"link",graph1,link_curves)
        if(errstate /= 0) print*, clearwin_string@("ERROR_REPORT")
        errstate = change_plot_int@(0,"colour",graph1,RGB@(255,0,0))
        errstate = change_plot_dbl@(0,"y_max",all_graphs,1.5d0)
        shown = .true.
        CALL simpleplot_redraw@()
        show = 2
      END FUNCTION show
      INTEGER FUNCTION clear()
        INTEGER errstate
        errstate = change_plot_int@(0,"link",graph1,link_none)
        shown = .false.
        CALL simpleplot_redraw@()
        clear = 2
      END FUNCTION clear
      INTEGER FUNCTION legend()
        IF(shown .AND. clearwin_string@("CALLBACK_REASON") == "PLOT_ADJUST") THEN
          CALL draw_characters@("Legend:..", 300, 100, 0)
          CALL draw_line_between@(300,120,360,120,RGB@(0,0,255))
        legend = 2
      END FUNCTION legend
      END MODULE mydata
      PROGRAM main
      USE mydata
      INTEGER i,x
      DOUBLE PRECISION p1,p2,p3
      DO i=1,n
      shown = .false.
      i=winio@('%ww[no_border]%ca[Damped wave]%pv&')
      i=winio@('%mn[Edit[Show, Clear]]&', show, clear)
      i=winio@('%ts&', 1.1d0)
      CALL winop@("%pl[native]")
      CALL winop@('%pl[title="Sample plot"]')
      CALL winop@("%pl[x_axis=Time(Milliseconds)]")
      CALL winop@("%pl[y_axis=Amplitude@(-4.0)]")
      CALL winop@("%pl[smoothing=4]") ! anti-aliasing
      CALL winop@("%pl[link=none]")   ! delay drawing


Copyright © 1999-2024 Silverfrost Limited