
Basic 2D pie charts for programmers

jeremybb
jeremy@bergsman.org
Function SimplePieChart(CenterX, CenterY, Radius, Values, Labels) //Potentially useful demonstration function for the associated pie-chart functions //Designed to create a pie chart at the given coordinates and size, from paired text and numeric waves containing the values and labels //Values assumed to represent 100% of data //Wedge "colors" limited to up to 5 shades of gray //Some effort is spent to make the shading work out nicely for arbitrary numbers of wedges //I have been using in the absolute coordinate system, may need some fixing to be coordinate-system agnostic Variable CenterX, CenterY, Radius Wave Values Wave /T Labels Variable Loop1, NumShades, Color, AltTags=.03, ArcMidPnt //AltTags value is the amount to space out a tag from the pie when it gets too crowded Duplicate /O Values, Degrees Integrate/P Values /D=Degrees Degrees=Degrees*360/sum(Values) if (numpnts(Values)<6) NumShades=numpnts(Values) AltTags=0 else if (mod(numpnts(Values),5)!=1) //what's bad is if there is one left at the end, which would get the starting color NumShades=5 else if (mod(numpnts(Values),4)!=1) NumShades=4 else NumShades=3 endif endif endif DrawWedge(CenterX, CenterY, 0, Degrees[0], Radius, 36000, 36000, 36000) ArcMidPnt=Degrees[0]/2 LabelWedge("\Z08"+Labels[0], CenterX, CenterY, ArcMidPnt, Radius, AltTags*((Degrees[1]-Degrees[0])<30)) for (Loop1=0;Loop1<numpnts(Values)-1;Loop1+=1) Color=36000+mod(Loop1+1,NumShades)*(24000/(NumShades-1)) DrawWedge(CenterX, CenterY, Degrees[Loop1], Degrees[Loop1+1], Radius, Color, Color, Color) ArcMidPnt=(Degrees[Loop1]+Degrees[Loop1+1])/2 LabelWedge("\Z08"+Labels[Loop1+1], CenterX, CenterY, ArcMidPnt, Radius, AltTags*mod(Loop1,2)*((Degrees[Loop1+1]-Degrees[Loop1])<30)) endfor End Function DrawWedge(CenterX, CenterY, StartAngle, EndAngle, Radius, Red, Green, Blue) //Draw a wedge with the given center position through the given angles //Wedges have black line border and the given color //Angles in degrees, Center and radius graph relative //End Angle must be > Start Angle Variable CenterX, CenterY, StartAngle, EndAngle, Radius, Red, Green, Blue if (EndAngle-StartAngle>180) SetDrawEnv fillfgc=(Red,Green,Blue), linethick=0 DrawPoly CenterX, CenterY, 1, 1, {0, 0, Radius*cos((StartAngle+180)*pi/180), Radius*sin((StartAngle+180)*pi/180), Radius*cos(EndAngle*pi/180), Radius*sin(EndAngle*pi/180), 0, 0} SetDrawEnv fillfgc=(Red,Green,Blue) DrawArc /X/Y CenterX, CenterY, Radius, StartAngle, StartAngle+180 SetDrawEnv fillfgc=(Red,Green,Blue) DrawArc /X/Y CenterX, CenterY, Radius, StartAngle+180, EndAngle else SetDrawEnv fillfgc=(Red,Green,Blue), linethick=0 DrawPoly CenterX, CenterY, 1, 1, {0, 0, Radius*cos(StartAngle*pi/180), Radius*sin(StartAngle*pi/180), Radius*cos(EndAngle*pi/180), Radius*sin(EndAngle*pi/180), 0, 0} SetDrawEnv fillfgc=(Red,Green,Blue) DrawArc /X/Y CenterX, CenterY, Radius, StartAngle, EndAngle endif DrawLine CenterX, CenterY, CenterX+Radius*cos(StartAngle*pi/180), CenterY+Radius*sin(StartAngle*pi/180) DrawLine CenterX, CenterY, CenterX+Radius*cos(EndAngle*pi/180), CenterY+Radius*sin(EndAngle*pi/180) End Function LabelWedge(LabelText, CenterX, CenterY, ArcMidPnt, Radius, Offset) //Place a text label on a wedge. //Location is coded using the same kind of variables as DrawWedge for convenience //If Offset is non-zero, the label is placed at radius+offset, connected to the point at radius with a line String LabelText Variable CenterX, CenterY, ArcMidPnt, Radius, Offset if (Offset>0) DrawLine CenterX+Radius*cos(ArcMidPnt*pi/180), CenterY+Radius*sin(ArcMidPnt*pi/180), CenterX+(Offset+Radius)*cos(ArcMidPnt*pi/180), CenterY+(Offset+Radius)*sin(ArcMidPnt*pi/180) Radius+=Offset endif if ((ArcMidPnt>0)&&(ArcMidPnt<=90)) //This could be improved by creating 4 more compass points for angles very near 0, 90... TextBox /A=LT/B=1/E=2/F=0/X=(100*(CenterX+Radius*cos((ArcMidPnt)*pi/180)))/Y=(100*(CenterY+Radius*sin((ArcMidPnt)*pi/180))) LabelText elseif ((ArcMidPnt>90)&&(ArcMidPnt<=180)) TextBox /A=RT/B=1/E=2/F=0/X=(100*(1-CenterX-Radius*cos((ArcMidPnt)*pi/180)))/Y=(100*(CenterY+Radius*sin((ArcMidPnt)*pi/180))) LabelText elseif ((ArcMidPnt>180)&&(ArcMidPnt<=270)) TextBox /A=RB/B=1/E=2/F=0/X=(100*(1-CenterX-Radius*cos((ArcMidPnt)*pi/180)))/Y=(100*(1-CenterY-Radius*sin((ArcMidPnt)*pi/180))) LabelText elseif ((ArcMidPnt>270)&&(ArcMidPnt<=360)) TextBox /A=LB/B=1/E=2/F=0/X=(100*(CenterX+Radius*cos((ArcMidPnt)*pi/180)))/Y=(100*(1-CenterY-Radius*sin((ArcMidPnt)*pi/180))) LabelText endif End

Forum

Support

Gallery
Igor Pro 9
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More