Kuchendiagramm

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

Silver_Knee

Betreff: Kuchendiagramm

BeitragFr, Mai 01, 2015 14:43
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Smile

BlitzMax: [AUSKLAPPEN]
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
'right half - cut to right half with Max here
Local circleAngle:Float=ACos(dy/radius) 'min 0 / max 180

If circleAngle<90
'bottom
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
'top
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

'left half - cut to left half with Min here
circleAngle=360-circleAngle

If circleAngle>270
'bottom
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
'top
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

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group