Jump to content


Photo

Pie Chart Function


  • Please log in to reply
5 replies to this topic

#1 ton80

ton80
  • Members
  • 71 posts

Posted 02 January 2012 - 07:45 AM

I recently had a use for a pie chart in ahk, and had trouble finding any solution for this.. So I created a pie chart function, and thought someone else may be able to use it.

Screenshot:
Posted Image

function:PieChart(hwnd, x_coord, y_coord, diameter,segments,bordersize, showpercentages = 0)
The parameters for the function are:
hwnd of the window you wish to draw pie chart on
x coord of the pie chart (relative to the window)
y coord of the pie chart (relative to the window)
diameter of the pie chart
segments is a csv list of name|size of segments, these arent percentages, but they can be you so choose. (the function will calc the percentages otherwise)
bordersize - the thickness of the border around the ellipse, as well as between the segments, 0 = no border
showpercentages - display the percentage for each pie segment (0 for no, 1 for yes)

Example Usage:
gui, show, x300 y100 h800 w1000, piecharts
whwnd := WinExist("A")
data = Internet Explorer|20, Firefox|30, Chrome|50, Opera|20, Other|10
PieChart(whwnd,40,20,300,data,3,1)

todo - create key for chart (if anyone has a use for this)
- fix bugs that im sure this will have :roll:

edit 1 - cleaned up the % display, moved to inside pie

Function:
PieChart(hwndWin, xpos, ypos, size,segments,bordersize, showpercentages = 0)
{
	;define colors
	color_1	:= 0x008000							;green
	color_2 := 0x0000FF							;red
	color_3	:= 0xFF0000							;blue
	color_4 := 0x00FFFF							;yellow
	color_5 := 0x00FF00							;lime
	color_6 := 0x808000							;teal
	color_7 := 0xFFFF00							;aqua
	color_8	:= 0xFF00FF							;fuchsia
	color_9 := 0x800080							;purple
	color_10:= 0xFFFFFF							;white
	
	;get a dc for the window
	hdcWin := DllCall("GetDC", "UInt", hwndWin)
	Pen := DllCall("CreatePen", int, 0, int, bordersize, int, 0x000000)
	DllCall("SelectObject", uint, hdcWin, uint, pen)

	;draw ellipse to the window
	DllCall("Ellipse", uint, hdcWin, int, xpos, int, ypos, int, xpos + size, int, ypos + size)
	
	;set variables
	radius := size / 2
	tradius := size / 2 * .8								;test radius
	2pi := 2*3.1415926
	center_x := xpos + size / 2
	center_y := ypos + size / 2
	dangle	:= 0											;set the initial angle to 0 degrees
	rangle	:= dangle * .01745329252						;convert degrees to radians
	prev_x	:= center_x + radius * cos(rangle-2pi/4)		;find the x coord of the initial angle
	prev_y	:= center_y + radius * sin(rangle-2pi/4)		;find the y coord of the initial angle
	
	;count the number of segments
	Loop, Parse, segments, `,
		{
			Segment_Count := A_Index
			Loop, Parse, A_Loopfield, |
				{
					If (A_Index & 1)
						continue
					Piece_Count += A_Loopfield
				}
		}

	;get the size of each piece
	piece_size_deg := 1 / Piece_Count * 360
	
	;draw pie slice
	loop, parse, segments, `,
		{
			bcolor := A_Index
			if A_Index > 10								; only storing 10 diffent colors, if there is more pie pieces
				bcolor := A_Index - 10					; than this, then start reusing the colors.. 
			
			bcolor := color_%bcolor%
			Loop, parse, A_Loopfield, |
				{
					if (A_Index & 1)
						continue
					else
						{
							brush := DllCall("CreateSolidBrush", int, bcolor)
							DllCall("SelectObject", uint, hdcWin, uint, brush)
							if !(bordersize)
								{	
									Pen := DllCall("CreatePen", int, 0, int, 1, int, bcolor)
									DllCall("SelectObject", uint, hdcWin, uint, pen)
								}
							dangle += piece_size_deg * A_Loopfield
							rangle	:= dangle * .01745329252
							next_x := center_x + radius * cos(rangle-2pi/4)
							next_y := center_y + radius * sin(rangle-2pi/4)
							DllCall("Pie", uint, hdcWin, int, xpos, int, ypos, int, xpos + size, int, ypos + size, int, next_x, int, next_y, int, prev_x, int, prev_y)
							;show percentages if that parameter is set.
							If (showpercentages)
								{
									segment_percent := Round((A_LoopField / piece_count) * 100,1) "%"
									StringLen,segment_percentL, segment_percent
									tangle := dangle - (piece_size_deg * A_LoopField) /2
									rangle	:= tangle * .01745329252
									text_x := center_x + tradius * cos(rangle-2pi/4)
									text_y := center_y + tradius * sin(rangle-2pi/4)
									DllCall("SetBkColor", "Int", hdcWin, "Int", bcolor)
									DllCall("SetTextAlign", uint, hdcWin, int, 6)
									DllCall("TextOut", uint, hdcwin, int, text_x, int, text_y, uint, &segment_percent, int, segment_percentL)
								}
							
							prev_x := next_x
							prev_y := next_y
							DllCall("DeleteObject", uint, brush)
							if !(bordersize)
								DllCall("DeleteObject", uint, pen)
						}
				}
		}
DllCall("DeleteObject", uint, pen)
DllCall("ReleaseDC", uint, hdcWin)
}


#2 Guests

  • Guests

Posted 04 January 2012 - 08:26 AM

thanks, could be very useful!

#3 aaffe

aaffe
  • Members
  • 1024 posts

Posted 04 January 2012 - 08:36 AM

#Thanks!
Question: Why dont you display the Names of the data, eg. Internet Explorer, Firefox, Chrome etc.....?

#4 SoggyDog

SoggyDog
  • Members
  • 803 posts

Posted 04 January 2012 - 04:35 PM

Nice;
I'm a fan of graphing functions in AHK;
"Pie" is not typically my graph of choice, but now I know where to go if/when I need it.

Thanks.

#5 automaticman

automaticman
  • Members
  • 658 posts

Posted 12 February 2012 - 01:38 PM

So names are not used in the plot?

#6 User1654

User1654
  • Guests

Posted 16 July 2012 - 04:06 PM

Hello,

When I set Gui, Color, CCCCCC the chart dissapears. Is there a workaround?