home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD-ROM Aktiv 1
/
CDA1_96.ISO
/
clipper
/
line.prg
< prev
next >
Wrap
Text File
|
1996-01-06
|
6KB
|
181 lines
/***************************************************************************
* LINE.PRG
*
* Sample of how to make a simple line graph using CA-Clipper 5.3 graphics
* mode.
*
* compile: CLIPPER LINE /N
*
* link: BLINKER FI LINE LIB LLIBG or...
* EXOSPACE FI LINE LIB LLIBG
*
* Requires: CA-Clipper 5.3
*
* This function was published in Clipper Plus Magazine, Mexico, December 1995 issue
*
* Clipper Plus is a disk based monthly magazine fully written in
* Spanish and published in Mexico, but... due to the success of my last
* pie graph, (pie.prg, available in Clipper forum in Compuserve) this time
* I decided to upload the english version instead of the spanish one,
* this version is exactly the same in spanish, but comments and variable
* names are in english for your better understanding.
*
* Feedback and improvements are welcome!
*
* enjoy and happy clipping !!!!
*
* Rene Flores
* Editor in Chief
* Clipper Plus and VO Plus Magazines
* CIS: 74174,320
****************************************************************************/
#DEFINE PIX_HOR 500
#DEFINE PIX_VER 300
#DEFINE PIX_X_0 70
#DEFINE PIX_Y_0 390
#INCLUDE "LLIBG.CH"
/* Function Main() tests Line_graph() function */
FUNCTION Main
LOCAL aValues := {}
aValues := {{1,3,5,7,9,8,6},;
{0,2,4,6,8,10,20,23,11,17},;
{6,7,8,15,14,9},;
{10,5,15,20,21,6},;
{20,10,5,10,7,8,11,3,5},;
{1,2,4,8,16,32,23,20,15,23,11,2,4,8}}
Line_graph(aValues)
aValues := {{1,3,7,8,6},;
{6,7,8,15,14,9},;
{20,10,5,10,7}}
Line_graph(aValues)
RETURN (NIL)
/* Function: Line_graph(<aValues>)
Description: This function draws a simple line graph
Parameter: an array of arrays in <aValues> (see Function Main())
containing the values to be graph
Comments: This function is not as simple as the pie graph, so we have
to work a little more this time, we have to make some calculations
to draw a grid, to plot every single point and to draw lines
between points */
FUNCTION Line_graph(aValues)
LOCAL nVideoMode // to save video mode
LOCAL nHowHor // to scale horizontally
LOCAL nHowVer // to scale vertically
LOCAL nLongArr // to determine which is the longest array
LOCAL nInty // a subtraction
LOCAL nHcounter // Horizontal counter
LOCAL nVcounter // Vertical counter
LOCAL nSmlVal // smaller value
LOCAL nGrtVal //greater value
/* assiging starting values */
nLongArr := LEN(aValues[1])
nSmlVal := aValues[1,1]
nGrtVal := aValues[1,1]
nVideoMode := GMODE() // save current graphics mode
GMODE(LLG_VIDEO_VGA_640_480_16) // let's go graphics!
/* let's draw a grid */
GLINE(70,90,70,390,8,LLG_MODE_SET)
GLINE(70,390,570,390,8,LLG_MODE_SET)
/* Scaling "x" axis
To scale over the "X" axis, we need to know howmany elements has the
longest array this code block does it. */
AEVAL(aValues,{|x,y| nLongArr := IF(LEN(x) > nLongArr, LEN(x) , nLongArr) })
/* howmany pixels between divisions ? */
nHowHor := PIX_HOR / nLongArr
nHcounter := PIX_X_0
/* ok!, let's draw divisions over the "X" axis */
FOR x := 1 TO nLongArr
nHcounter += nHowHor
GLINE(nHcounter,PIX_Y_0 - 10, nHcounter, PIX_Y_0 + 10,8,LLG_MODE_SET)
GWRITEAT(nHcounter - 3,PIX_Y_0 + 20,LTRIM(STR(x)),8,LLG_MODE_SET)
NEXT
/* Scaling "y" axis
To scale over the "y" axis we need to know the greater and the smaller
value all over the arrays to be graph */
AEVAL(aValues,{|x,y| AEVAL(x,{|v,w| nSmlVal := IF(v < nSmlVal,v,nSmlVal),;
nGrtVal := IF(v > nGrtVal,v,nGrtVal) }) })
/* The next substraction calculates the difference between the smaller
value and the greater one, this will serve to calculate the scale. */
nInty := nGrtVal - nSmlVal
/* howmany pixels between divisions ? ("y" axis) */
nHowVer := PIX_VER / nInty
nVcounter := PIX_Y_0
/* drawing division over the "y" axis */
FOR x := 1 TO nInty
nVcounter -= nHowVer
GLINE(PIX_X_0 - 10, nVcounter, PIX_X_0 + 10, nVcounter,8,LLG_MODE_SET)
GWRITEAT(PIX_X_0 - 30, nVcounter, LTRIM(STR(x)),8,LLG_MODE_SET)
NEXT
/* now, let's plot every point with a "+", the next code block does it
using the GWRITEAT() function,*/
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)}) })
/* finally, draw lines between points, as you cannot do it with a code block
but a couple of for / next structures along with GLINE() can do the job */
FOR x := 1 TO LEN(aValues)
FOR y := 2 TO LEN(aValues[x])
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)
NEXT
NEXT
/* wait for any key, clear screen and come back to the old video mode */
INKEY(0)
CLEAR
GMODE(nVideoMode)
RETURN(NIL)
/* end Line_graph, that's all folks */
/* Improvements and others:
+ You cannot graph more than 16 arrays with different colors
+ The scaling procedures work well for small values but not to big ones
+ You cannot print the graph (unless you are using DOS' command GRAPHICS)
A lot of fancy improvements can be done to this function, for example:
+ To solve the problem of scaling axis
+ Add a title to the graph
+ Add titles over the "x" and "y" axis
Please, let me know your improvements to this function !*/