2006-03-21

BAR GRAPHICS WITHOUT COMPLICATIONS

I always see people asking how to create graphics without active-x controls.

In my opinion, the most simple way to do it is to use labels. labels are versatile, we can change their backcolor, caption, width, height. These four properties are all we need to create a simple graphic, like in this picture below.



The graphic is drawn in a container. we can set the label color to the bar color, in its caption we can store the values, its height is proportional to the value, and the width depends on the division between the container's width and the wuantity of bars.

The bars auto adjust themselves according to the data received, and the dimensions of the container.

Everything is done in a single method. in the form example, I've put this code in the refresh method of the container. a cursor is needed to store the data, where the first field, field(1) receives the values and the second field field(2) receives the caption. The name of the cursor is stored in the tag property of the container. and that's all !

Some extra code was added to allow the resizement of the form.

Put this code in the load event of the form :

 

create cursor sales (amount n(8,2), cname c(6))

insert into sales values (250,"jan")
insert into sales values (128,"feb")
insert into sales values ( 90,"mar")
insert into sales values (330,"apr")
insert into sales values (190,"may")
insert into sales values (250,"jun")
insert into sales values ( 50,"jul")
insert into sales values ( 80,"aug")
insert into sales values ( 50,"sep")
insert into sales values ( 19,"oct")
insert into sales values (160,"nov")
insert into sales values (199,"dec")


 

and this in the refresh event:

 

*!* create array with 12 colors to be used

dimension lacolors(12)
lacolors(1) = rgb(255,128,128) && red
lacolors(2) = rgb(0,255,0) && green
lacolors(3) = rgb(128,128,255) && blue
lacolors(4) = rgb(255,0,255) && pink
lacolors(5) = rgb(0,255,255) && cyan
lacolors(6) = rgb(255,255,0) && yellow
lacolors(7) = rgb(160,160,210) && blue2
lacolors(8) = rgb(255,160,30) && orange
lacolors(9) = rgb(200,140,140) &&
lacolors(10) = rgb(96,196,96) && green2
lacolors(11) = rgb(255,200,200) && rose
lacolors(12) = rgb(200,200,200) && grey


lnblack = rgb(28,28,28) && black
lnwhite = rgb(255,255,255) && white
lctable = this.tag


select "&lctable"

*!* calculate the width of each bar
lnlargura = int(this.width / reccount())
lnaltura = this.height


lcfldvalor = this.tag + "." + field(1)

if fcount() > 1
   lcfldlegenda = this.tag + "." + field(2)
else
   lcfldlegenda = ""
endif
calculate max(evaluate(lcfldvalor)) to lnmax

 

*!* add the labels that will be the bars and the captions
scan
   n = recno()
   lcobj = "label" + transform(n)
   lcleg = "lname" + transform(n)
   *!* check if object already exists to avoid errors
   if type("this."+lcobj) <> "o"
      this.addobject(lcobj,"label")
      this.addobject(lcleg,"label")
   endif


   with this.&lcobj.
      .backstyle = 1 && opaque
      .backcolor = lacolors(iif(n>12,n-12,n))
      .width = lnlargura
      lnvalor = evaluate(lcfldvalor)
      lnbarra = ( lnvalor / lnmax) * (this.height - 1 - 17)
      .height = lnbarra
      .left = ((n-1) * lnlargura) + 2
      .top = lnaltura - this.&lcobj..height – 17
      .tag = transform(lnvalor)
      .caption = transform(lnvalor)
      .fontsize = 8
      .fontbold = .t.
      .alignment = 2
      .visible = .t.
   endwith

   with this.&lcleg.
      .backstyle = 1 && opaque
      .backcolor = lnwhite
      .forecolor = lnblack
      .width = lnlargura – 2
      if not empty(lcfldlegenda)
         .caption = alltrim(evaluate(lcfldlegenda))
      endif
      .left = ((n-1) * lnlargura) + 3
      .top = this.height – 17
      .height = 17
      .fontsize = 8
      .alignment = 2
      .visible = .t.
   endwith


endscan

this.width = ((n) * lnlargura) + 3

 

You may use this technique to create bar graphics at the horizontal, with very slight adaptations in the code.
In the attached file, bargraphics.zip, you'll find bargraphics.scx/sct from this example, and also 3 more files, callbar.prg that calls barras.scx/sct that create a modal form with bargraphics that can be resized.

4 comments:

  1. Excellent example.

    thanks for sharing knowledge.


    ReplyDelete
  2. Muito bom este exemplo de gráficos em Visual Foxpro.

    ReplyDelete
  3. Otra opción similar y 100% código VFP la pueden ver en www.PortalFox.com


    "Gráficas con objetos 100% VFP"

    http://www.portalfox.com/article.php?sid=2211


    ReplyDelete
  4. Versión en Español de este artículo en / Spanish version at http://www.portalfox.com/article.php?sid=2202

    ReplyDelete