ich bastelte an einem kleinen Programm rum und wollte eine grafische Auswertung (Vergleich als Balkendiagram). Hier ist der (hoffentlich selbsterklärende) Code:
Code: Alles auswählen
EnableExplicit
Enumeration
#DIAGRAM_IMG
#CONTAINER_GRAPHS
#IMG_GRAPHS
EndEnumeration
Structure DiagramData
name.s
value1.f
value2.f
EndStructure
Procedure.i CreateDiagramImage(Image.i, Title.s, List dData.DiagramData(), Value1Name.s="", Value2Name.s="", ShowValueAsFloat.i=#False, SortListByName.i=#True) ; Image.i=#Image
Protected startTime.i = ElapsedMilliseconds()
Protected n.i
Protected multiplier.f
Protected listEntries = ListSize(dData())
Protected size.RECT ; size of image
Protected fontTitle.i = LoadFont(#PB_Any, "Calibri", 10, #PB_Font_Bold|#PB_Font_HighQuality)
Protected fontX.i = LoadFont(#PB_Any, "Calibri", 8, #PB_Font_HighQuality)
Protected fontY.i = LoadFont(#PB_Any, "Calibri", 10, #PB_Font_HighQuality)
Protected colorBg.i = RGB(255, 248, 220)
Protected colorLine.i = RGB(0, 0, 0)
Protected colorHigh.i = RGB(230, 230, 230)
Protected colorHelp.i = RGB(220, 220, 220)
Protected colorVal1.i = RGB(178, 34, 34)
Protected colorVal2.i = RGB(34, 178, 34)
Protected highestValue.f
Protected highestValuePx.POINT
Protected longestText.s
Protected longestTextPx.POINT
Protected titlePx.RECT
Protected val1Px.RECT
Protected val2Px.RECT
Protected diagram.RECT ; the diagram size
Protected ySpace.i
Protected xSpace.i ; the space on axis between the names
Protected boxSize.i ; size of boxes in x-pixels
If listEntries = 0
ProcedureReturn 0
EndIf
; get size of container gadget ...
If IsGadget(#IMG_GRAPHS)
size\top = 0
size\left = 0
size\right = GadgetWidth(#CONTAINER_GRAPHS)-4
size\bottom = GadgetHeight(#CONTAINER_GRAPHS)-4
Else
ProcedureReturn 0
EndIf
; ... and resize image
If IsImage(Image)
ResizeImage(Image, size\right, size\bottom)
Else
CreateImage(Image, size\right, size\bottom)
EndIf
; check for diagram title
If Title = ""
Title = "Diagram"
EndIf
If Value1Name <> "" And Value2Name <> ""
Value1Name = " = "+Value1Name
Value2Name = " = "+Value2Name
EndIf
; sort list by NAME
If SortListByName
SortStructuredList(dData(), #PB_Sort_Descending, OffsetOf(DiagramData\name), #PB_Sort_String)
EndIf
; get highest values for text sizes
ForEach dData()
With dData()
If \value1 >= highestValue
highestValue = \value1
EndIf
If \value2 >= highestValue
highestValue = \value2
EndIf
If Len(\name) >= Len(longestText)
longestText = \name
EndIf
EndWith
Next
; get sizes of text
StartDrawing(ImageOutput(Image))
; diagram title
DrawingFont(FontID(fontTitle))
titlePx\right = TextWidth(Title)
titlePx\bottom = TextHeight(Title)
titlePx\left = (size\right - titlePx\right) / 2
titlePx\top = 5
; value 1 and 2 description
DrawingFont(FontID(fontX))
If Value1Name <> "" And Value2Name <> ""
val1Px\right = TextWidth(Value1Name)
val1Px\bottom = TextHeight(Value1Name)
val1Px\top = 5
val2Px\right = TextWidth(Value2Name)
val2Px\bottom = TextHeight(Value2Name)
val2Px\top = val1Px\top + val1Px\bottom + 5
If val1Px\right > val2Px\right
val1Px\left = size\right - val1Px\right - 10
val2Px\left = size\right - val1Px\right - 10
Else
val1Px\left = size\right - val2Px\right - 10
val2Px\left = size\right - val2Px\right - 10
EndIf
EndIf
; get name text sizes
longestTextPx\x = TextWidth(longestText)
longestTextPx\y = TextHeight(longestText)
; get value text sizes
DrawingFont(FontID(fontY))
If ShowValueAsFloat
highestValuePx\x = TextWidth(StrF(highestValue, 1))
Else
highestValuePx\x = TextWidth(Str(highestValue))
EndIf
highestValuePx\y = TextHeight(Str(highestValue))
StopDrawing()
; calculate the RECT for the whole diagram
diagram\left = 5 + highestValuePx\x + 5
If Value1Name = "" Or Value2Name = ""
diagram\top = titlePx\top + titlePx\bottom + 5
Else
diagram\top = val2Px\top + val2Px\bottom + 5
EndIf
diagram\right = size\right - diagram\left - 5
diagram\bottom = size\bottom - 5 - longestTextPx\y - 5
; now fill the image an draw the coordinate system
StartDrawing(ImageOutput(Image))
DrawingMode(#PB_2DDrawing_Transparent)
Box(size\left, size\top, size\right, size\bottom, colorBg)
DrawingFont(FontID(fontTitle))
DrawText(titlePx\left, titlePx\top, Title, colorLine)
If Value1Name <> "" And Value2Name <> ""
DrawingFont(FontID(fontX))
DrawText(val1Px\left, val1Px\top, Value1Name, colorLine)
DrawText(val2Px\left, val2Px\top, Value2Name, colorLine)
Box(val1Px\left, val1Px\top, -val1Px\bottom, val1Px\bottom, colorVal1)
Box(val2Px\left, val2Px\top, -val1Px\bottom, val1Px\bottom, colorVal2)
EndIf
LineXY(diagram\left, diagram\bottom+5, diagram\left, diagram\top-5, colorLine)
LineXY(diagram\left-5, diagram\bottom, diagram\right+5, diagram\bottom, colorLine)
StopDrawing()
; calculate x- and y-axis
xSpace = Round((diagram\right - diagram\left) / listEntries, #PB_Round_Up)
If highestValue < 5
ySpace = Round((diagram\bottom - diagram\top) / 5, #PB_Round_Up) : multiplier = 0.5
ElseIf highestValue >= 5 And highestValue < 10
ySpace = Round((diagram\bottom - diagram\top) / 10, #PB_Round_Up) : multiplier = 1
ElseIf highestValue >= 10 And highestValue < 100
ySpace = Round((diagram\bottom - diagram\top) / (highestValue / 10), #PB_Round_Up) : multiplier = 10
ElseIf highestValue >= 100 And highestValue < 1000
ySpace = Round((diagram\bottom - diagram\top) / (highestValue / 50), #PB_Round_Up) : multiplier = 50
ElseIf highestValue >= 1000 And highestValue < 10000
ySpace = Round((diagram\bottom - diagram\top) / (highestValue / 500), #PB_Round_Up) : multiplier = 500
ElseIf highestValue >= 10000
ySpace = Round((diagram\bottom - diagram\top) / (highestValue / 5000), #PB_Round_Up) : multiplier = 5000
EndIf
; draw x- and y-axis
StartDrawing(ImageOutput(Image))
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(fontX))
FirstElement(dData())
For n = 1 To listEntries
Line(diagram\left + (n * xSpace), diagram\bottom, 1, 5, colorLine)
DrawText(diagram\left + ((n-1) * xSpace) + ((xSpace - TextWidth(dData()\name)) / 2), diagram\bottom + 3, dData()\name, colorLine)
NextElement(dData())
Next
DrawingFont(FontID(fontY))
For n = 1 To (diagram\bottom / ySpace)
If diagram\top <= diagram\bottom - (n * ySpace)
Line(diagram\left, diagram\bottom - (n * ySpace), -5, 1, colorLine)
Line(diagram\left + 1, diagram\bottom - (n * ySpace), diagram\right - diagram\left, 1, colorHelp)
If ShowValueAsFloat
DrawText(diagram\left - 5 - highestValuePx\x, diagram\bottom - (n * ySpace) - (TextHeight(Str(n)) / 2), StrF(n*multiplier, 1), colorLine)
Else
DrawText(diagram\left - 5 - highestValuePx\x, diagram\bottom - (n * ySpace) - (TextHeight(Str(n)) / 2), Str(n*multiplier), colorLine)
EndIf
EndIf
Next
StopDrawing()
; calculate boxes and draw them
boxSize = Round(xSpace / 3, #PB_Round_Nearest)
StartDrawing(ImageOutput(Image))
DrawingMode(#PB_2DDrawing_Transparent)
DrawingFont(FontID(fontY))
FirstElement(dData())
For n = 1 To listEntries
Box(diagram\left + ((n-1) * xSpace) + (boxSize / 2), diagram\bottom, boxSize, -((dData()\value1 / multiplier) * ySpace), colorVal1)
If ShowValueAsFloat
If dData()\value1 <= 0
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + ((boxSize - TextWidth(StrF(dData()\value1, 1))) / 2), diagram\bottom - TextHeight(Str(dData()\value1)), StrF(dData()\value1, 1), colorLine)
Else
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + ((boxSize - TextWidth(StrF(dData()\value1, 1))) / 2), diagram\bottom - ((dData()\value1 / multiplier) * ySpace), StrF(dData()\value1, 1), colorHigh)
EndIf
Else
If dData()\value1 <= 0
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + ((boxSize - TextWidth(Str(dData()\value1))) / 2), diagram\bottom - TextHeight(Str(dData()\value1)), Str(dData()\value1), colorLine)
Else
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + ((boxSize - TextWidth(Str(dData()\value1))) / 2), diagram\bottom - ((dData()\value1 / multiplier) * ySpace), Str(dData()\value1), colorHigh)
EndIf
EndIf
Box(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + boxSize, diagram\bottom, boxSize, -((dData()\value2 / multiplier) * ySpace), colorVal2)
If ShowValueAsFloat
If dData()\value2 <= 0
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + boxSize + ((boxSize - TextWidth(StrF(dData()\value2, 1))) / 2), diagram\bottom - TextHeight(Str(dData()\value2)), StrF(dData()\value2, 1), colorLine)
Else
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + boxSize + ((boxSize - TextWidth(StrF(dData()\value2, 1))) / 2), diagram\bottom - ((dData()\value2 / multiplier) * ySpace), StrF(dData()\value2, 1), colorHigh)
EndIf
Else
If dData()\value2 <= 0
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + boxSize + ((boxSize - TextWidth(Str(dData()\value2))) / 2), diagram\bottom - TextHeight(Str(dData()\value2)), Str(dData()\value2), colorLine)
Else
DrawText(diagram\left + ((n-1) * xSpace) + (boxSize / 2) + boxSize + ((boxSize - TextWidth(Str(dData()\value2))) / 2), diagram\bottom - ((dData()\value2 / multiplier) * ySpace), Str(dData()\value2), colorHigh)
EndIf
EndIf
NextElement(dData())
Next
StopDrawing()
Debug "done in " + Str(ElapsedMilliseconds() - startTime) + " ms"
ProcedureReturn ImageID(Image)
EndProcedure
If OpenWindow(0, 0, 0, 800, 500, "Diagram Test", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If ContainerGadget(#CONTAINER_GRAPHS, 5, 5, WindowWidth(0)-10, WindowHeight(0)-10, #PB_Container_Raised)
ImageGadget(#IMG_GRAPHS, 0, 0, GadgetWidth(#CONTAINER_GRAPHS), GadgetHeight(#CONTAINER_GRAPHS), 0)
CloseGadgetList()
EndIf
Else
End
EndIf
NewList DiagramData.DiagramData()
AddElement(DiagramData())
DiagramData()\name = "Anbieter TEU"
DiagramData()\value1 = 51.9
DiagramData()\value2 = 0
AddElement(DiagramData())
DiagramData()\name = "Anbieter Mittel"
DiagramData()\value1 = 0
DiagramData()\value2 = 40.6
AddElement(DiagramData())
DiagramData()\name = "Anbieter SAUteu"
DiagramData()\value1 = 60.7
DiagramData()\value2 = 88.0
AddElement(DiagramData())
DiagramData()\name = "Anbieter Mittel"
DiagramData()\value1 = 45.6
DiagramData()\value2 = 0
AddElement(DiagramData())
DiagramData()\name = "Anbieter TEUA"
DiagramData()\value1 = 56.9
DiagramData()\value2 = 70.0
AddElement(DiagramData())
DiagramData()\name = "Anbieter BIL"
DiagramData()\value1 = 30.2
DiagramData()\value2 = 38.3
AddElement(DiagramData())
DiagramData()\name = "Anbieter BILIGA"
DiagramData()\value1 = 20.3
DiagramData()\value2 = 30.4
If CreateDiagramImage(#DIAGRAM_IMG, "Durchschnittliche Preise nach Anbieter", DiagramData(), "Bären", "Stiere", #True)
SetGadgetState(#IMG_GRAPHS, ImageID(#DIAGRAM_IMG))
Else
Debug "image creation failed"
EndIf
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
End