Graphs - fully configurable Pie Chart

Share your advanced PureBasic knowledge/code with the community.
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2058
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Graphs - fully configurable Pie Chart

Post by Andre »

Part two of the story "How do I create charts in PureBasic?"... :lol:

This time its a fully configurable Pie-Chart... 8)

Feel free to play around with the Init values. Chart is fully resizable and can be positioned on an (existing) image, is possible to include different number of sectors with different values, offers several color-styles and much more....

Code: Select all

; ****  Pie Chart - Diagram  ****
; Created: 1st/2nd May 2003 by Andre Beer / PureBasic-Team (www.purebasic.com)
; Many thanks to David "Tinman" McMinn for fixing the filling routine :-)

;-Init
ImW.w = 500        ; Width of diagram in pixel   \ in this case also the (inner) window
ImH.w = 350        ; Height of diagram in pixel  / dimensions....
MaxValue.w = 1000  ; Maximum individual value stored in the diagramm values
Graphs.w = 10      ; Number of sectors (graphs) in the diagram
Values.l = 1       ; Decide, if the relating sector values will be printed inside the descriptions box
                   ; 0 = print only the sector name (in this example: Part 1, Part 2, etc.)
                   ; 1 = print the sector name as well the relating value (in this example: Part 1 (Value1), Part 2 (Value2), etc.)
Color.l = 2        ; Number of color-style, currently included only three:
                   ; 0 = blue style
                   ; 1 = brown style
                   ; 2 = green style

;-Structures
Structure Diagram
  Value.l      ; Value
  Text.s       ; Description of the individual charts sectors
  Color.l      ; Color for filling the area of this sector
EndStructure 

Structure Style
  Front1.l   ; 1st foreground color  (main)
  Front2.l   ; 2nd foreground color  (lighter)
  Front3.l   ; 3rd foreground color  (darker)
  Back1.l    ; 1st background color  (lighter)
  Back2.l    ; 2nd background color  (darker)
  Bottom.l   ; Color of the bottom bar
  Title.l    ; Title color
  Text.l     ; Text color (axis descriptions)
EndStructure


; Init array  (item 0 is used for general settings, item 1 until Graphs+1 contains the diagram data
Dim Stats.Diagram(Graphs+1) 

;-ColorStyles
Dim Colors.Style(3)

; Set blue color-style
Colors(0)\Front1 = RGB(71,71,108)
Colors(0)\Front2 = RGB(140,140,183)
Colors(0)\Front3 = RGB(49,49,75)
Colors(0)\Back1  = RGB(201,211,233)
Colors(0)\Back2  = RGB(184,197,226)
Colors(0)\Bottom = RGB(255,255,255)
Colors(0)\Title  = RGB(0,0,255)
Colors(0)\Text   = RGB(0,0,0)

; Set red-brown color-style
Colors(1)\Front1 = RGB(108,71,71)
Colors(1)\Front2 = RGB(183,120,120)
Colors(1)\Front3 = RGB(75,49,49)
Colors(1)\Back1  = RGB(233,211,201)
Colors(1)\Back2  = RGB(226,197,184)
Colors(1)\Bottom = RGB(243,232,226)
Colors(1)\Title  = RGB(255,0,0)
Colors(1)\Text   = RGB(240,0,0)

; Set green color-style
Colors(2)\Front1 = RGB(71,108,71)
Colors(2)\Front2 = RGB(120,183,120)
Colors(2)\Front3 = RGB(49,75,49)
Colors(2)\Back1  = RGB(201,233,211)
Colors(2)\Back2  = RGB(184,226,197)
Colors(2)\Bottom = RGB(223,242,228)
Colors(2)\Title  = RGB(49,75,49)
Colors(2)\Text   = RGB(24,58,35)

;-Procedure
Procedure Pie(ID.l, Count.l, x.l, y.l, Width.l, Height.l, Color.l, Title.s) 
  ; ID     = Output-ID for drawing operations (e.g. WindowOutput, ImageOutput, etc.)
  ; Count  = Value-/Bars-number
  ; x, y   = top-left corner of the diagram in pixel
  ; Width  = Width of diagram in pixel
  ; Height = Height of diagram in pixel, including title line and text line
  ; Color  = number of color-style
  ; Title  = String with the text, which should be printed as title line

  ; Initial values
  #Pi.f = 3.141593
  #Resolution.f = 65     ; Resolution is the part used for the pie-chart in percent, the other part is used for the description on the right side
  #Border = 10           ; Border (in pixel) on left and right side of the pie-chart
  AngleStart.f = -#Pi    ; needed later for calculating the circle-parts
  AngleEnd.f = 0         ; defines where the drawing starts: 0 = right, #Pi = left, #Pi/2 = bottom, -#Pi/2 = top
  #TitleBar = 20         ; Height of the Title bar area
  #TitleFontHeight = 10  ; Font height of the Title text
  #TextFontHeight = 8    ; Font height of the Description text
  #White = 16777215      ; Set the value of RGB(255,255,255) to a white color constant
  
  ; Calculate initial chart values
  LeftWidth = Width * #Resolution / 100
  temp1.l = (LeftWidth - #Border - 5) / 2
  temp2.l = (Height - #TitleBar - 5) / 2
  If temp1 < temp2
    Radius.l = temp1
  Else
    Radius.l = temp2
  EndIf  
  MX.l = x + #Border + ((LeftWidth-#Border) / 2)
  MY.l = y + temp2 + #TitleBar

  ; Count the sum of all graphs value (=100%)
  For a=1 To Count
    Sum.l + Stats(a)\Value
  Next

  ; Load fonts
  FontID.l = LoadFont(1, "ARIAL", #TitleFontHeight, #PB_Font_Bold | #PB_Font_HighQuality)
  FontID2.l = LoadFont(1, "ARIAL", #TextFontHeight, #PB_Font_HighQuality)

  StartDrawing(ID) 
  
  ; Paint background  (used similar one as in Bars-Chart example, I was too lazy to create a new one  ;-)
  #Title   = 24
  #Bottom  = 15
  Box(x,y,Width,Height,Colors(Color)\Back1)                   ; paint lighter background fullsize
  Box(x,y,#Border,Height,Colors(Color)\Back2)                 ; paint darker bar at left 
  Box(x+Width-#Border,y,#Border,Height,Colors(Color)\Back2)   ; paint darker bar at right
  For a = y+25 To Height Step 50
    Box(x+#Border+1,a,Width-(2*#Border)-2,25)                 ; paint darker background bars
  Next a

  ; Paint title string
  FrontColor(Red(Colors(Color)\Title),Green(Colors(Color)\Title),Blue(Colors(Color)\Title))
  DrawingMode(1)     ; set drawing-mode to 1 for transparent text drawing
  DrawingFont(FontID)
  Locate(x+(Width-TextLength(Title))/2, y)
  DrawText(Title)

  FrontColor(0,0,0) 
  
  For id=1 To Count
    AngleStart = AngleEnd
    AngleEnd = AngleStart + (Stats(id)\Value * 2 * #Pi / Sum)

    ; Set black as default color for all border lines
    FrontColor(0,0,0)
       
    ; Draw the lines from inside the circle to the border
    LineXY(MX,MY,Cos(AngleStart)*(Radius+1)+MX,Sin(AngleStart)*(Radius+1)+MY)    ; note: Radius must be increases by 1 here,
    LineXY(MX,MY,Cos(AngleEnd)*(Radius+1)+MX,Sin(AngleEnd)*(Radius+1)+MY)        ; because otherwise sometimes misses a pixel

    ; Draw the circle     
    For a.l = AngleStart * Radius To AngleEnd * Radius  ;Step 2 
      px.l = Cos(a / Radius) * Radius + MX 
      py.l = Sin(a / Radius) * Radius + MY 
      Plot(px, py) 
    Next 
    
    ; Calc the coordinates for filling point and finally fill the selected area
    px = Cos((AngleEnd + AngleStart) / 2)*(Radius / 2) + MX
    py = Sin((AngleEnd + AngleStart) / 2)*(Radius / 2) + MY
    FillArea(px,py,0,Stats(id)\Color)
  Next  
  
  ; Now draw the descriptions on the right side
  #LineHeight = #TextFontHeight + 4
  #LineSpace = 5
  ; Find the widthest string
  For id=1 To Count
    temp1 = TextLength(Stats(id)\Text)
  Next
  temp1 + #LineHeight
  temp2 = (Width - LeftWidth - temp1) / 2
  If temp2 <=0 : temp2 = 0 : EndIf
  px = x + LeftWidth + temp2
  temp2 = (#LineHeight * Count) + (#LineSpace * (Count-1))
  py = y + #TitleBar + ((Height - temp2 - #TitleBar) / 2)  ; Image height decreased by needed height for the text descriptions
  DrawingFont(FontID2)
  ; paint white background box with black borders
  DrawingMode(0)
  Box(px-4,py-4,temp1,(#LineHeight+#LineSpace)*Count+4,#White)
  DrawingMode(4)
  Box(px-5,py-5,temp1+2,(#LineHeight+#LineSpace)*Count+5,0)
  Line(px-3+temp1,py-4,0,(#LineHeight+#LineSpace)*Count+5)
  Line(px-4,py+(#LineHeight+#LineSpace)*Count,temp1,0)
  ; paint the color boxes with relating description
  For id=1 To Count
    Box(px,py,#LineHeight,#LineHeight,0)
    DrawingMode(0)
    Box(px+1,py+1,#LineHeight-2,#LineHeight-2,Stats(id)\Color)
    DrawingMode(1)
    FrontColor(Red(Colors(Color)\Text),Green(Colors(Color)\Text),Blue(Colors(Color)\Text))
    Locate(px + #LineHeight + 4, py-1)
    DrawText(Stats(id)\Text)
    py + #LineHeight + #LineSpace
  Next
  
  StopDrawing() 
EndProcedure 

;- Diagram data

; Store some general values
Stats(0)\Value = MaxValue  ; value is relating to 100% diagram height, must correspond to (at least) the greatest individual value!!!
; Fill data array
For a=1 To Graphs
  ; Fill value
  Value = Random(MaxValue-1)+1       ; the values should be at least 2
  Stats(a)\Value = Value
  ; Fill x-Axis
  If Values=0
    Stats(a)\Text = "Part "+Str(a)
  Else
    Stats(a)\Text = "Part "+Str(a)+" ("+Str(Value)+")"
  EndIf
  ; Fill color
  Red   = Random(255)
  Green = Random(255)
  Blue  = Random(255)
  Stats(a)\Color = RGB(Red,Green,Blue)      ; currently here are used random colors, feel free to set your own's ;-)
Next a

; Set some fixed values instead of random numbers  (delete the ";" in front of the lines if wanted)
;Stats(1)\Value = 10
;Stats(2)\Value = 20
;Stats(3)\Value = 30


;-Main Programm 
OpenWindow(0,100,200,ImW,ImH,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Diagrams... ;-)    <written May 2003 by Andre Beer>") 

;-Create Image
If CreateImage(0,ImW,ImH)
  StartDrawing(ImageOutput())
  Box(0,0,ImW,ImH,$FFFFFF)
  StopDrawing()
Else
  Debug "Error when creating image..."
  End
EndIf


;-Call Diagram
; Parameters: OutputID, Elements, x, y, Width, Height, Colorstyle, Title-String
Pie(ImageOutput(), Graphs, 0, 0, ImW, ImH, Color, "Pie Chart Example")         


WinID.l = WindowID()
If CreateGadgetList(WinID)
  ImageGadget(0,2,2,300,220,ImageID())
EndIf


;- Main loop
Repeat 
   Event = WaitWindowEvent() 
   Select Event 
      Case #PB_EventCloseWindow 
         Quit = #True 
   EndSelect 
Until Quit 
End 
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
TronDoc
Enthusiast
Enthusiast
Posts: 310
Joined: Wed Apr 30, 2003 3:50 am
Location: 3DoorsDown

Post by TronDoc »

I don't know if I'm doing something wrong or not,
with either the random data or the uncommented
test data all I get is this:
Image
Joe
peace
[pI 166Mhz 32Mb w95]
[pII 350Mhz 256Mb atir3RagePro WinDoze '98 FE & 2k]
[Athlon 1.3Ghz 160Mb XPHome & RedHat9]
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2058
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Post by Andre »

TronDoc wrote:I don't know if I'm doing something wrong or not,
with either the random data or the uncommented
test data all I get is this:
Joe, don't know what isn't working correctly on your system.

Normally it should draw (using the initial settings) a background containing lighter & darker green horizontal bars. On top of this in the left area the Pie chart is drawed and in the right area the description box (which is working like to be seen on your screenshot).

It was created (tested hundert times :wink:) using WinXP and also on Tinman's config (Win98) is does working properly.

Don't know, what happening here with your config.... :?:
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
TronDoc
Enthusiast
Enthusiast
Posts: 310
Joined: Wed Apr 30, 2003 3:50 am
Location: 3DoorsDown

Post by TronDoc »

O.K. I am using Windows98 original version.
I will try some things to see if I can make it work.
Joe
peace
[pI 166Mhz 32Mb w95]
[pII 350Mhz 256Mb atir3RagePro WinDoze '98 FE & 2k]
[Athlon 1.3Ghz 160Mb XPHome & RedHat9]
Cor
Enthusiast
Enthusiast
Posts: 124
Joined: Fri Apr 25, 2003 7:52 pm
Location: Netherlands
Contact:

Post by Cor »

Works great here :D

Win98 SE
Cor de Visser

Registered PureBasic user

Author of ChordPlanet
Made with PureBasic
http://www.chordplanet.com
midebor
User
User
Posts: 26
Joined: Fri Apr 25, 2003 10:22 pm
Location: Liege, Belgium

Post by midebor »

Works fine here on Win 98.

Michel :D
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2058
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Post by Andre »

Thanks for testing :D

Anyone more beside TronDoc, who have problems ?
If not, it should really be something wrong with TronDoc's gfx setup... :roll:
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
TronDoc
Enthusiast
Enthusiast
Posts: 310
Joined: Wed Apr 30, 2003 3:50 am
Location: 3DoorsDown

Post by TronDoc »

the bar chart program you posted elsewhere works fine
so I do not know what would be the difference between
the two programs to stop this one from working and
allow the other one to work fine.
I tried to compare the two files, but I haven't
found anything yet.
Joe
peace
[pI 166Mhz 32Mb w95]
[pII 350Mhz 256Mb atir3RagePro WinDoze '98 FE & 2k]
[Athlon 1.3Ghz 160Mb XPHome & RedHat9]
kns
User
User
Posts: 54
Joined: Sat Apr 26, 2003 2:06 am

Post by kns »

Stupid question time....

Why do I receive a "Garbage to the end of line" error on the
first line of code? I just copied and pasted into the editor...

Thanks
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2058
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Post by Andre »

kns wrote:Stupid question time....

Why do I receive a "Garbage to the end of line" error on the
first line of code? I just copied and pasted into the editor...
There is nothing special. I could copy & paste it easily back to my PB-Editor.

Try to paste it to Windows Wordpad first and then copy & paste it to the editor...
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2058
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Post by Andre »

TronDoc wrote:the bar chart program you posted elsewhere works fine
so I do not know what would be the difference between
the two programs to stop this one from working and
allow the other one to work fine.
Thats really strange (as no other user seems to have that problem). There isn't anything special in the procedure, only the calculations and drawing commands have changed... 8)
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
Danilo
Addict
Addict
Posts: 3037
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Post by Danilo »

@kns: I guess you use Opera!?
cya,
...Danilo
...:-=< http://codedan.net/work >=-:...
-= FaceBook.com/DaniloKrahn =-
kns
User
User
Posts: 54
Joined: Sat Apr 26, 2003 2:06 am

Post by kns »

Yup, I probably copied from Opera... I switch between Opera and Mozilla. I find Opera fast but unstable and the reverse for Mozilla.

K
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Can someone else test this?

I would like to use pie charts in a program I'm writing but this (and the version in purearea) seems a little "funny" on my system (win xp sp2, pb 3.94).

Just wondering if it's my system or if others get "unusual" (black horizontal stripes across the chart) results.

P.S. you'll have to fix the constant "typing" at around lines 89,90.

Thanks for testing.
Jellybean
User
User
Posts: 95
Joined: Wed Aug 24, 2005 7:33 pm

Post by Jellybean »

I don't know what compiler version you use, Andre, but constants can't have a type in version 3.94.

On to the real problems; it looks "a bit" "strange".

Image
Post Reply