The chart grid does change to suit the data, up to a point, plus the Canvas size is related to the Window (fixed) Size. If the range of data you wish to cater for is large, plonk the canvas on a ScrollGadget and have your code dynamically change the size of both gadgets as required.
Code: Select all
;Simple Bar Chart Graph. IdeasVacuum. Free to use, no restrictions.
Enumeration
#WinGraph
#CvsGraph
#FileIO
EndEnumeration
Structure Player
sPlayerName.s
iScore.i
iNameWidth.i
EndStructure
NewList Scores.Player()
Global igHighestScore.i = 0
Global igLongestName.i = 0
Global igWindowW.i = 700
Global igWindowH.i = 500
Global igCanvasW.i = (igWindowW - 20)
Global igCanvasH.i = (igWindowH - 20)
Global igWinBackColour.i = RGB(224,223,227) ;Classic Windows back colour
Global igFontID01.i = LoadFont(1, "Arial", 8, #PB_Font_Bold | #PB_Font_HighQuality + 2)
Global igFontID02.i = LoadFont(2, "Arial", 10, #PB_Font_Bold | #PB_Font_HighQuality + 2)
Macro RoundTo(i, s)
;-----------------
((s) * Round((i) / (s) + 0.5, #PB_Round_Down))
EndMacro
Procedure.i LoadInfo()
;--------------------
Shared Scores.Player()
Protected sVal.s = ""
Protected sScoresFile.s = "C:\MyGame\HighestScores.txt" ;<<-- Insert your own folder/file here
;Load the Player Data
;At the same time, get the Name length for right-alignment on graph later
If ReadFile(#FileIO,sScoresFile)
StartDrawing(CanvasOutput(#CvsGraph)) ;Needed for TextWidth function (nothing is drawn yet)
DrawingFont(igFontID02)
While Not Eof(#FileIO)
sVal = ReadString(#FileIO)
AddElement(Scores.Player())
Scores.Player()\sPlayerName = StringField(sVal, 1, Chr(44)) ;delimiter is a comma
Scores.Player()\iScore = ValD(StringField(sVal, 2, Chr(44)))
Scores.Player()\iNameWidth = TextWidth(Scores.Player()\sPlayerName)
If(Scores.Player()\iScore > igHighestScore) : igHighestScore = Scores.Player()\iScore : EndIf
If(Scores.Player()\iNameWidth > igLongestName) : igLongestName = Scores.Player()\iNameWidth : EndIf
Wend
StopDrawing()
CloseFile(#FileIO)
ProcedureReturn(#True)
Else
MessageRequester("Problem","Could not open HighestScores.txt file",#PB_MessageRequester_Ok | #MB_ICONERROR)
ProcedureReturn(#False)
EndIf
EndProcedure
Procedure DrawBarChart()
;-----------------------
;Draw a Chart on a Canvas, as though the Canvas is a sheet of paper
Shared Scores.Player()
Protected iTotalPlayers.i = 0
Protected iChartW.i = 0
Protected iChartH.i = 0
Protected iChartX0.i = 0
Protected iChartY0.i = 0
Protected iGridPitchX.i = 0
Protected iX.i = 0
Protected iTextCtrX.i = 0
Protected iLabelX.i = 0
Protected iLblX.i = 0
Protected iColour.i = 0
Protected iPreviousColour.i = 0
Protected dRatio.d = 0.00
Protected iGridPitchY.i = 0
Protected iY.i = 0
Protected iW.i = 0
Protected iTextX.i = 0
Protected iTextY.i = 0
Protected iTextCtrY.i = 0
Protected iHighestScore.i = 0
Protected iMulti.i = 100
If(igLongestName > 1) ;If it isn't, there was an issue with HighestScores.txt
StartDrawing(CanvasOutput(#CvsGraph))
DrawingFont(igFontID02)
BackColor(RGB(255,255,255))
DrawingMode(#PB_2DDrawing_Default)
;Draw shadow
Box(0,0,igCanvasW,igCanvasH,RGB(136,136,136)) ;Dark Grey
Box(-2,-2,igCanvasW + 4,10,igWinBackColour) ;(across top)
Box(-2,-2,10,igCanvasH + 4,igWinBackColour) ;(vertical left)
Box(0,0,igCanvasW -8,igCanvasH - 8,RGB(255,255,255)) ;White (Chart Region)
;Draw Canvas (paper) boundary
DrawingMode(#PB_2DDrawing_Outlined)
Box(0,0,igCanvasW -8,igCanvasH - 8,RGB(0,0,0)) ;Black
;Draw chart
;Chart has approx 15pix margin inside Canvas, all-round
iChartW = (igCanvasW - 40) - (igLongestName + 10)
iChartH = (igCanvasH - 65)
;Tweak Chart Height so that bars fit exact integer value (using double val = ugly bars)
iTotalPlayers = ListSize(Scores.Player())
iGridPitchY = (iChartH/iTotalPlayers)
iChartH = (iGridPitchY * iTotalPlayers)
iChartX0 = (igLongestName + 25)
iChartY0 = 15
;Tweak Chart Width so that grid lines fit exact integer value (using double val = ugly grid)
iGridPitchX = (iChartW/10)
iChartW = (iGridPitchX * 10)
DrawingMode(#PB_2DDrawing_Default)
Box(iChartX0,iChartY0,iChartW,iChartH,RGB(230,230,250)) ;Graph Background Lavenda
;Chart Grid Vertical Lines
DrawingMode(#PB_2DDrawing_Default)
iX = iChartX0
For i = 0 To 10
;X Y X2 Y2 Colour
If(iX < iChartW + iChartX0) : LineXY(iX,iChartY0,iX,(iChartH + 20),RGB(127,127,127)) : EndIf ;Grey Grid
;X Y X2 Y2 Colour
LineXY(iX,(iChartY0 + iChartH),iX,(iChartY0 + iChartH + 5),RGB(0,0,0)) ;Black 'comb'
iX + iGridPitchX
Next i
;Chart Labels along X
If(igHighestScore > 999) : iMulti = 1000 : EndIf
;Determine nearest 100 or 1000
iHighestScore = RoundTo(igHighestScore, iMulti)
If(igHighestScore > iHighestScore)
iHighestScore = ((igHighestScore - iHighestScore) + (iHighestScore + 20))
EndIf
iLabelX = (iHighestScore/10)
iLabelX = RoundTo(iLabelX, 5)
iLblX = 0
iX = iChartX0
For i = 0 To 11
iTextCtrX = (TextWidth(Str(iLblX)) / 2)
DrawText(iX - iTextCtrX,iChartH + 25,Str(iLblX),RGB(0,0,0))
iX + iGridPitchX
iLblX + iLabelX
Next i
;Chart Labels along Y + bars
iTextCtrY = (TextHeight("M") /2)
iTextY = (iChartY0 + (iGridPitchY/2)) - iTextCtrY
iY = iChartY0
dRatio = (iChartW/iHighestScore)
FirstElement(Scores.Player())
For i = 1 To iTotalPlayers
iTextX = ((iChartX0 - 5) - Scores.Player()\iNameWidth)
BackColor(RGB(255,255,255))
DrawingFont(igFontID02)
DrawText(iTextX,iTextY,Scores.Player()\sPlayerName,RGB(0,0,0))
iW = (dRatio * Scores.Player()\iScore)
iScoreX = ((iChartX0 + iW) - (TextWidth(StrD(Scores.Player()\iScore,0)) + 5))
iColour = RGB(Random(255),Random(255),Random(255))
If(iColour = iPreviousColour) : iColour = RGB(Random(255),Random(255),Random(255)) : EndIf
BackColor(iColour)
DrawingFont(igFontID01)
Box(iChartX0,iY,iW,iGridPitchY,iColour)
DrawText(iScoreX,iTextY,StrD(Scores.Player()\iScore,0),RGB(0,0,0))
NextElement(Scores.Player())
iPreviousColour = iColour
iY + iGridPitchY
iTextY + iGridPitchY
Next i
;Chart Grid Outline
DrawingMode(#PB_2DDrawing_Outlined)
Box(iChartX0,iChartY0,iChartW,iChartH,RGB(0,0,0)) ;Black
StopDrawing()
EndIf
EndProcedure
Procedure ShowWin()
;------------------
If OpenWindow(#WinGraph, 0, 0, igWindowW, igWindowH, "Highest Scores", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
SetWindowColor(#WinGraph,igWinBackColour)
CanvasGadget(#CvsGraph,10,10,igCanvasW,igCanvasH)
SetGadgetAttribute(#CvsGraph,#PB_Canvas_Cursor,#PB_Cursor_Hand)
Else
MessageRequester("Problem","Failed to open Window",#PB_MessageRequester_Ok | #MB_ICONERROR)
EndIf
EndProcedure
Procedure WaitForUser()
;----------------------
Protected iEvent.i = 0
Repeat
iEvent = WaitWindowEvent(1)
Until iEvent = #PB_Event_CloseWindow
EndProcedure
;## MAIN #############
ShowWin()
LoadInfo()
DrawBarChart()
WaitForUser()
;#####################
End
Cheryl,180
An Onymous,122
Beyonce,185
An Other,211
Joe Blogs,132
Will I Am,199
Rihanna,223
Ying Qin,285
Britney,180
John Smith,177
Lady Penelope, 252
Batman,99