Hi, hier eine einfache Funktion um Kuchendiagramme zu erstellen.
Die Einzelnen Stücke werden per Arrray übergeben. Dabei wird immer der End-Winkel und die Farbe angegeben. Der Anfangswinkel ist 0 und das erste Stück startet nach unten gegen den Uhrzeigersinn.
Das erste Stück könnte also 90, das zweite 135, das dritte 180 und das vierte 270 als Winkel angeben. Damit ein vollständiger Kreis entsteht muss zuletzt ein Stück mit 360 als Winkel angegeben werden.
Der Code funktioniert nur, wenn die Stücke in aufsteigender Reihenfolge ihrer Winkel angegeben werden und kein Winkel kleiner als 0 oder größer als 360 ist. Das Diagramm wird zeilenweise mit DrawLine aufgebaut. Bei BB waren Rects schneller als gerade Linien; wie das bei BM und den verschiedenen Treibern ist, weiß ich nicht. Kann also sein, dass man hier optimieren kann. Außerdem werden hier 2 For-Loops verschachtelt, das heißt der Code kann bei großen Radien oder vielen Stücken langsam werden.
Trotzdem, viel Spaß bei euren Statistiken
BlitzMax: [AUSKLAPPEN] [EINKLAPPEN] Function DrawPieChart(x:Float, y:Float, pieces:TPieChartPiece[], radius:Float) Local lastAngle:Float=0 For Local p:TPieChartPiece=EachIn pieces SetColor p.r,p.g,p.b For Local dy:Float= -radius To +radius Step 1 Local circleAngle:Float=ACos(dy/radius)
If circleAngle<90 If p.angle>circleAngle And circleAngle>lastAngle DrawLine x+Sin(circleAngle)*radius,y+dy,x+Tan(lastAngle)*dy,y+dy ElseIf p.angle<=circleAngle DrawLine x+Tan(p.angle)*dy,y+dy,x+Tan(lastAngle)*dy,y+dy EndIf Else Local dx:Int If p.angle<=180 dx=Tan(p.angle)*dy Else dx=0 EndIf If p.angle>circleAngle And circleAngle>lastAngle DrawLine x+dx,y+dy,x+Sin(circleAngle)*radius,y+dy ElseIf p.angle>=circleAngle And lastAngle<=180 DrawLine x+dx,y+dy,x+Tan(lastAngle)*dy,y+dy EndIf EndIf circleAngle=360-circleAngle
If circleAngle>270 If p.angle>circleAngle And circleAngle>lastAngle DrawLine Min(x,x-Sin(360-circleAngle)*radius),y+dy,Min(x,x-Tan(360-p.angle)*dy),y+dy ElseIf p.angle>=circleAngle DrawLine Min(x,x-Tan(360-p.angle)*dy),y+dy,Min(x,x-Tan(360-lastAngle)*dy),y+dy EndIf Else Local dx:Int If lastAngle>=180 dx=-Tan(360-lastAngle)*dy Else dx=0 EndIf If p.angle>circleAngle And circleAngle>lastAngle DrawLine x-Sin(360-circleAngle)*radius,y+dy,x+dx,y+dy ElseIf p.angle<=circleAngle And p.angle>180 DrawLine x+Tan(p.angle)*dy,y+dy,x+dx,y+dy EndIf EndIf Next DrawLine x,y,x+Sin(p.angle)*radius,y+Cos(p.angle)*radius DrawLine x,y,x+Sin(lastAngle)*radius,y+Cos(lastAngle)*radius lastAngle=p.angle Next End Function
Type TPieChartPiece Function Create:TPieChartPiece(angle:Float,r:Int,g:Int,b:Int) Local this:TPieChartPiece=New TPieChartPiece this.angle=angle this.r=r this.g=g this.b=b Return this End Function Field angle:Float Field r:Int,g:Int,b:Int End Type
|