Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Microsoft: FoxPro FAQ


Simple chart in a Grid or elsewhere by Toman
Posted: 29 Apr 04 (Edited 29 Apr 04)

Charts help to understand long series of numerical values better. To see what this means just Copy & Paste PROGRAM2 at the end of this article into the Command window and run it (for newbies only:  select all lines of code in command window before you press Enter).

That's why VFP has its own tools for creating graphs. If you need a chart from table values occasionally or just need to make some preliminary analyze of numeric data and you need it quickly and efficiently, follow this way.

The idea is pretty simple and admonishes of about good old days of text orientated computing. Form the bars of the chart as a string of characters in one column of grid such a way, that the string length as seen on the screen correspondents to given numeric value. Some conditions must be met to obtain acceptable results.

Let's suppose we have a table with numeric field numField and with one extra field of character type tmp to be filled with bars. This field can be added temporarily just for displaying chart or calculated field can be used as well.

The "key operation" is to fill column with bars by putting the string with appropriate length into the field tmp for every record and it is in fact the only thing you must do.



REPLACE tmp WITH REPLICATE("I", lnMaxSize * numField / lnMaxValue) FOR ALL

   * or using SQL

SELECT numField, PADR(REPLICATE("I", lnMaxSize * numField / lnMaxValue), lnMaxSize," ") AS tmp FROM table


"I"     character as a basic element for creating bars of chart. Here uppercase letter I is used. Especially suitable if taken from some Sans Serif proportional bold font, e.g. ARIAL. Other candidates are characters from Wingdings fonts. Some of them even have no gap between each other.

lnMaxSize     Number of elements to form maximum usable width of graph. The bigger is lnMaxSize, the higher is a resolution and less is the granularity. Big values are better but lead to wide graph of course and that's why the narrow proportional letter "I" is so useful here.

lnMaxValue     expected maximal numeric value to be displayed. To keep control over the graph and avoid error messages we must set this value thoroughly. If we want the highest value to occupy full width of graph, we simply set lnMaxValue to maximal value from series by means of command CALCULATE MAX(numField) TO lnMaxValue. This is the safest method. In other situations we may want set lnMaxValue higher. For example if our values are in percents (but surely less then 100%) it might be advisable set lnMaxValue = 100

Don't forget: bars are still characters in TextBoxes and can be colored (even conditionally) at your will using SETALL command in conjunction with column properties DYNAMIC... It was described here many times (Thread184-343788 and so on). See also FAQ184-3098 with different approach to this problem.

Let's summarize this method:

- Absolute simplicity
- Very quick painting and refreshing
- Universal - works with grids, browse windows and others controls with text property (not mentioned obsolete LIST, DISPLAY)
- No DLLs, Classes, Libraries or third party elements
- No place on disk
- Easy to implement in existing projects
- VFP version independent (in fact it is even VFP independent)

- There is no easy way to add axis and scales to these charts. If you really insist on having some, you can construct those using abscissas from Shape base class. While lnMaxValue remains the same theirs positions need not to be changed.

- Unable to work with more series although quasi two series are possible with combination of letters like       iiiiiiiiiiIIIIIIII

- It is neither 3-D nor 4-D. Graphical quality is low, if any. Happily there are other tools to use (mainly outside of VFP), if graphical effects are on the first place.

Here are two sample codes to play with


* Sample program to illustrate
* placing a quasi chart into a grid column

PUBLIC oform1, lnMaxSize, lnMaxValue
lnMaxSize = 100


DEFINE CLASS form1 AS form
 DoCreate = .T.
 Caption = "Chart inside a grid - try change a field Area"
 Name = "Form1"
 Width = 530
 Height = 220

 ADD OBJECT grid1 AS Grid WITH ;
  Height = 182, ;
  Left = 20, ;
  Top = 20, ;
  Width = 485, ;
  Name = "Grid1", ;
  Font = "Arial"

   CREATE table tblTable (state c(20),numField n(6),tmp c(100))
   INSERT INTO tblTable VALUES ("TEXAS",692407,"")
   INSERT INTO tblTable VALUES ("UTAH",219932,"")
   INSERT INTO tblTable VALUES ("VERMONT",24887,"")
   INSERT INTO tblTable VALUES ("VIRGINI",105711,"")
   INSERT INTO tblTable VALUES ("WASHINGTON",176617,"")
   INSERT INTO tblTable VALUES ("WISCONSIN",145439,"")
   INSERT INTO tblTable VALUES ("WYOMING",253597,"")
   * and few more fictional states
   FOR n = 1 TO 1000
        lcState = ""
           FOR m = 1 TO 3 + 9 * RAND()
               lcState = lcState + CHR(65 + 25 * RAND())
       INSERT INTO tblTable VALUES (lcState,50000 + 600000 * RAND(),"")
   WITH thisform.grid1
    .columncount = 3
    .DeleteMark = .F.
    .RecordMark = .F.
    .recordsourcetype = 1
    .recordsource = [tblTable]
    .GridLineColor = RGB(192,192,192)
    .column1.width = 100
    .column1.header1.caption = "State"
    .column1.header1.FontBold = .T.
    .column2.width = 55
    .column2.header1.caption = "Area"
    .column2.header1.FontBold = .T.
    .column3.width = 360
    .column3.fontbold = .T.
    .column3.forecolor = RGB(255,0,0)
    .column3.header1.caption = "  Areas are expressed graphically here"
    .column3.header1.FontBold = .T.
    .column3.enabled = .F.

  PROCEDURE grid1.AfterRowColChange
     *  This code should better go to
     *  ThisForm.Grid1.column2.text1.InteractiveChange proc,
     *  but I don't know how to write it down in this program
     *  (Column2 not found Error)
   lnRecNo = RECNO()
   CALCULATE MAX(numField) to lnMaxValue
   REPLACE tmp WITH " " + REPLICATE("I", lnMaxSize * numField / lnMaxValue) ALL

   GOTO lnRecNo


* Sample program to demonstrate strength (and beauty)
* of graphical presentations of numbers

*    need some table with numeric values
CREATE CURSOR tmp (numbers N(4))

*    let numbers follow elegant sine curve,
*    but use "error" values sometimes
FOR n = 1 TO 1000
  IF MOD(n,5) = 1
    * random error value
    INSERT INTO tmp (numbers) VALUES (100 + 899 * RAND())
    * pure sine
    INSERT INTO tmp (numbers) VALUES (100 + 449 * (1+SIN(n/8)))

*    see numbers only first
BROWSE TITLE "Do you think that these numbers  a r e  r a n d o m ?          ... close to see"

*    see both numbers and its graphical presentation - what a surprise
SELECT numbers, PADR(REPLICATE("I", 100 * numbers / 1000),100," ") AS Graph FROM tmp INTO CURSOR WithGraph

BROWSE TITLE "With graphical presentation you can see  m o r e               ... close to end" NOWAIT

With love to all Tek-Tips members

Back to Microsoft: FoxPro FAQ Index
Back to Microsoft: FoxPro Forum

My Archive

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close