2009-04-24

Circular Gauge chart with GdiPlusX

drawing shapes with gdiplusx is super easy, and we can very easilly transport this to solve some of our chart needs.


in this post i'm sending you a very primitive sample for creating circular gauge charts. obviously i hope to apply the techniques shown here in foxcharts. but foxcharts is getting big, and i confess that learning from the methods in foxcharts may not be easy for people that are not that familiar with gdiplusx.


please note that this is an unfinished sample. i'm posting it here to let people see that drawing is not that complicated. just using some imagination, merging it with some geometrical thoughts, and voilá !



download the gauge sample, unzip and run testgauge.scx ! i'm including the gdiplusx sources to let everybody immediately run the samples.


 


notice that you can control the colors of the background and pointer.


the pointer shape can be modified too. play with all the spinners to modify the shape and size! and please tell me which you like most. i'll apreciate receiving some image samples with some desired gauge charts.


 


below is the relevant code for the circular gauge drawing. you'll find it in the "beforedraw()" event of the imagecanvas class. it extracts the information from the form controls, and it's very easy to adapt it to your needs.


 


 


local lnangle, lnbasew, lnbasex, lnbasey, lntopw, lnheightpercent, lntopy
local lntype, lnpointclr, lnbackclr, lnticks
lnticks =
thisform.spnticks.value
lntype = thisform.optshape.value
lnangle = thisform.spnangle.value
lnbasew = thisform.spnbottomw.value
lntopw = thisform.spntopw.value
lnbasex = this.width/2 -lnbasew/2
lnbasey =
this.height/2
lnheightpercent =
thisform.spnheight.value / 100
lntopy = lnbasey - (lnbasey * lnheightpercent) + lntopw / 2
lnpointclr =
thisform.shppointercolor.backcolor
lnbackclr = thisform.shpbackcolor.backcolor
local
logfx as xfcgraphics
logfx =
this.ogfx


with _screen.system.drawing
   local lobrush as xfcsolidbrush
   lobrush = .solidbrush.new(.
color.fromrgb(lnpointclr))


   logfx.clear(.color.fromrgb(thisform.backcolor))


   * create a shape for the pointer
   local lopath as xfcgraphicspath
   lopath = .drawing2d.graphicspath.new()
   lopath.startfigure()
   logfx.fillellipse(.solidbrush.new(.color.fromrgb(lnbackclr)), ;
         this.rectangle)


   if lntype = 1
      lopath.addarc(lnbasex,
this.height/2 -lnbasew/2, lnbasew, lnbasew, 0, 180)
   endif


   lopath.addline(lnbasex, lnbasey, this.width/2 - lntopw/2, lntopy)
   if lntype = 1
      local lapoints(3)
      lapoints(1) = .
point.new(this.width/2 - lntopw/2, lntopy)
      lapoints(2) = .
point.new(this.width/2 , lntopy - lntopw / 2)
      lapoints(3) = .
point.new(this.width/2 + lntopw/2, lntopy)
      lopath.addcurve(@lapoints)
   endif


   lopath.addline( this.width/2 + lntopw/2, lntopy, lnbasex + lnbasew, lnbasey)
   lopath.closefigure()


   * rotate the shape pointer
   logfx.translatetransform(this.width/2, this.height/2)
   logfx.rotatetransform(lnangle)
   logfx.translatetransform(-
this.width/2, - this.height/2)


   * draw the pointer
   logfx.fillpath(lobrush, lopath)


   * restore the original gfx rotation state
   logfx.resettransform()
 


   if lnticks > 0
      for lnangle = 0 to 360 step 360 / lnticks


         * rotate the gfx
         logfx.translatetransform(this.width/2, this.height/2)
         logfx.rotatetransform(lnangle)
         logfx.translatetransform(-
this.width/2, - this.height/2)


         * draw the ticks
         logfx.drawline(.pens.black, this.width/2, 0, this.width/2, 10)


         * restore the original gfx rotation state
         logfx.resettransform()
      endfor 
   endif


endwith


 


enjoy !!!


download gauge prototype sample with gdiplusx


 


i've prepared a much more complete sample using foxcharts.
people can get it from the main download, and run the sample "chartssample_circulargauge.scx"
it allows lots of customizations, like the picture below.


you can get the latest version of foxcharts here:
http://vfpx.codeplex.com/release/projectreleases.aspx?releaseid=18515

2 comments:

  1. Thanks Cesar! I will try it soon.

    ReplyDelete