home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM Aktiv 1 / CDA1_96.ISO / clipper / line.prg < prev    next >
Text File  |  1996-01-06  |  6KB  |  181 lines

  1. /***************************************************************************
  2.  * LINE.PRG
  3.  *
  4.  * Sample of how to make a simple line graph using CA-Clipper 5.3 graphics
  5.  * mode.
  6.  *
  7.  * compile: CLIPPER LINE /N
  8.  *
  9.  * link: BLINKER FI LINE LIB LLIBG  or...
  10.  *       EXOSPACE FI LINE LIB LLIBG
  11.  *
  12.  * Requires: CA-Clipper 5.3
  13.  *
  14.  * This function was published in Clipper Plus Magazine, Mexico, December 1995 issue
  15.  *
  16.  * Clipper Plus is a disk based monthly magazine fully written in
  17.  * Spanish and published in Mexico, but... due to the success of my last
  18.  * pie graph, (pie.prg, available in Clipper forum in Compuserve) this time
  19.  * I decided to upload the english version instead of the spanish one,
  20.  * this version is exactly the same in spanish, but comments and variable
  21.  * names are in english for your better understanding.
  22.  *
  23.  * Feedback and improvements are welcome!
  24.  *
  25.  * enjoy and happy clipping !!!!
  26.  *
  27.  * Rene Flores
  28.  * Editor in Chief
  29.  * Clipper Plus and VO Plus Magazines
  30.  * CIS: 74174,320
  31.  ****************************************************************************/
  32.  
  33. #DEFINE PIX_HOR 500
  34. #DEFINE PIX_VER 300
  35. #DEFINE PIX_X_0 70
  36. #DEFINE PIX_Y_0 390
  37.  
  38. #INCLUDE "LLIBG.CH"
  39.  
  40. /* Function Main() tests Line_graph() function */
  41.  
  42. FUNCTION Main
  43.     LOCAL aValues := {}
  44.     aValues := {{1,3,5,7,9,8,6},;
  45.         {0,2,4,6,8,10,20,23,11,17},;
  46.         {6,7,8,15,14,9},;
  47.         {10,5,15,20,21,6},;
  48.         {20,10,5,10,7,8,11,3,5},;
  49.         {1,2,4,8,16,32,23,20,15,23,11,2,4,8}}
  50.     Line_graph(aValues)
  51.     aValues := {{1,3,7,8,6},;
  52.         {6,7,8,15,14,9},;
  53.         {20,10,5,10,7}}
  54.     Line_graph(aValues)
  55. RETURN (NIL)
  56.  
  57. /* Function: Line_graph(<aValues>)
  58.    Description: This function draws a simple line graph
  59.     Parameter: an array of arrays in <aValues> (see Function Main())
  60.                containing the values to be graph
  61.  
  62.     Comments: This function is not as simple as the pie graph, so we have
  63.               to work a little more this time, we have to make some calculations
  64.                  to draw a grid, to plot every single point and to draw lines
  65.                  between points */
  66.  
  67. FUNCTION Line_graph(aValues)
  68.     LOCAL nVideoMode                              // to save video mode
  69.     LOCAL nHowHor                                 // to scale horizontally
  70.     LOCAL nHowVer                                 // to scale vertically
  71.     LOCAL nLongArr                                // to determine which is the longest array
  72.     LOCAL nInty                                   // a subtraction
  73.     LOCAL nHcounter                               // Horizontal counter
  74.     LOCAL nVcounter                               // Vertical counter
  75.     LOCAL nSmlVal                                 // smaller value
  76.     LOCAL nGrtVal                                 //greater value
  77.  
  78. /* assiging starting values */
  79.  
  80.     nLongArr := LEN(aValues[1])
  81.     nSmlVal := aValues[1,1]
  82.     nGrtVal := aValues[1,1]
  83.  
  84.     nVideoMode := GMODE()                         // save current graphics mode
  85.  
  86.     GMODE(LLG_VIDEO_VGA_640_480_16)               // let's go graphics!
  87.  
  88.     /* let's draw a grid */
  89.  
  90.     GLINE(70,90,70,390,8,LLG_MODE_SET)
  91.     GLINE(70,390,570,390,8,LLG_MODE_SET)
  92.  
  93.     /* Scaling "x" axis
  94.  
  95.         To scale over the "X" axis, we need to know howmany elements has the
  96.         longest array this code block does it.  */
  97.  
  98.     AEVAL(aValues,{|x,y| nLongArr := IF(LEN(x) > nLongArr, LEN(x) , nLongArr) })
  99.  
  100.     /* howmany pixels between divisions ? */
  101.  
  102.     nHowHor := PIX_HOR / nLongArr
  103.  
  104.     nHcounter := PIX_X_0
  105.  
  106.     /* ok!, let's draw divisions over the "X" axis */
  107.  
  108.     FOR x := 1 TO nLongArr
  109.         nHcounter += nHowHor
  110.         GLINE(nHcounter,PIX_Y_0 - 10, nHcounter, PIX_Y_0 + 10,8,LLG_MODE_SET)
  111.         GWRITEAT(nHcounter - 3,PIX_Y_0 + 20,LTRIM(STR(x)),8,LLG_MODE_SET)
  112.     NEXT
  113.  
  114.     /* Scaling "y" axis
  115.  
  116.         To scale over the "y" axis we need to know the greater and the smaller
  117.         value all over the arrays to be graph */
  118.  
  119.     AEVAL(aValues,{|x,y| AEVAL(x,{|v,w| nSmlVal := IF(v < nSmlVal,v,nSmlVal),;
  120.         nGrtVal := IF(v > nGrtVal,v,nGrtVal) }) })
  121.  
  122.     /* The next substraction calculates the difference between the smaller
  123.        value and the greater one, this will serve to calculate the scale. */
  124.  
  125.     nInty := nGrtVal - nSmlVal
  126.  
  127.     /* howmany pixels between divisions ? ("y" axis) */
  128.  
  129.     nHowVer := PIX_VER / nInty
  130.  
  131.     nVcounter := PIX_Y_0
  132.  
  133.     /* drawing division over the "y" axis */
  134.  
  135.     FOR  x := 1 TO nInty
  136.         nVcounter -= nHowVer
  137.         GLINE(PIX_X_0 - 10, nVcounter, PIX_X_0 + 10, nVcounter,8,LLG_MODE_SET)
  138.         GWRITEAT(PIX_X_0 - 30, nVcounter, LTRIM(STR(x)),8,LLG_MODE_SET)
  139.     NEXT
  140.  
  141.     /* now, let's plot every point with a "+", the next code block does it
  142.     using the GWRITEAT() function,*/
  143.  
  144.     AEVAL(aValues,{|x,y| r:= y, AEVAL(x,{|v,w| GWRITEAT(PIX_X_0 + (nHowHor * w ) - 3,PIX_Y_0 - (nHowVer * v) - 7,"+",r,LLG_MODE_SET)}) })
  145.  
  146.     /* finally, draw lines between points, as you cannot do it with a code block
  147.     but a couple of for / next structures along with GLINE() can do the job */
  148.  
  149.     FOR x := 1 TO LEN(aValues)
  150.         FOR y := 2 TO LEN(aValues[x])
  151.             GLINE(PIX_X_0 + (nHowHor * y ),PIX_Y_0 - (nHowVer * aValues[x,y]),PIX_X_0 + (nHowHor * (y-1)),PIX_Y_0 - (nHowVer * aValues[x,y-1]),x,LLG_MODE_SET)
  152.  
  153.         NEXT
  154.     NEXT
  155.  
  156.     /* wait for any key, clear screen and come back to the old video mode */
  157.  
  158.     INKEY(0)
  159.     CLEAR
  160.     GMODE(nVideoMode)
  161.  
  162. RETURN(NIL)
  163. /* end Line_graph, that's all folks */
  164.  
  165. /* Improvements and others:
  166.  
  167.     + You cannot graph more than 16 arrays with different colors
  168.     + The scaling procedures work well for small values but not to big ones
  169.     + You cannot print the graph (unless you are using DOS' command GRAPHICS)
  170.  
  171. A lot of fancy improvements can be done to this function, for example:
  172.  
  173. + To solve the problem of scaling axis
  174. + Add a title to the graph
  175. + Add titles over the "x" and "y" axis
  176.  
  177.     Please, let me know your improvements to this function !*/
  178.  
  179.  
  180.  
  181.