Code: Select all
;Demo program to plot x,y data using scaling
;Uses keyboard and scroll bar input to change plot
Global xsize.f,ysize.f,xleft.f,xright.f,ylow.f,yhigh.f,xratio.f,yratio.f,BottomMargin.f
Global scrx,scry,scrw,scrh
Enumeration 100
#HBar
#HScrollPoint
#xytext
#tbox
EndEnumeration
Procedure ScrnScale(xl.f,xh.f,yl.f,yh.f) ;Calculate Scaling Parameters, call before ScrnX or ScrnY and after opening a screen
;Parameters are x1,x2,y1,y2 of Screen to plot on
xsize=ScreenWidth()-1 ;Note screen width is number of pixels
ysize=ScreenHeight()-BottomMargin-1 ;-1 because OpenWindowedScreen(100,100,10,10) screen is 10 wide
xleft=xl : xright=xh ;but there will be 11 pixels 0,1,...10
ylow=yl : yhigh=yh
xratio=xsize/(xright-xleft)
yratio=ysize/(yhigh-ylow)
EndProcedure
Procedure.f ScrnX(x.f) ;Return scaled x value of Screen
ProcedureReturn (x-xleft)*xratio
EndProcedure
Procedure.f ScrnY(y.f) ;Return scaled y value of Screen
ProcedureReturn ysize-(y-ylow)*yratio
EndProcedure
Procedure BindHScroll() ;Needed to display value while scrolling x axis
If IsGadget(#HBar)=0 :ListViewGadget(#HBar,300,620,125,20) : EndIf
ClearGadgetItems(#HBar)
AddGadgetItem(#HBar,0,"New End Point = "+Str(GetGadgetState(#HScrollPoint)))
EndProcedure
NumberofElements=2000 ;max 10,000 due to scroll bar limit
NumberofCycles=4
Dim SineWave.f(NumberofElements)
PiScale.f=2*3.1416*NumberofCycles/NumberofElements
For i=0 To NumberofElements ;Generate a sine wave
SineWave(i)=Sin(i*PiScale)
Next
endpoint=NumberofElements
ymin=-1: ymax=1
BottomMargin=25 ;this space can be used for botttom tick marks and x axis notation
Font1 = LoadFont(#PB_Any, "Arial" , 10)
Font2 = LoadFont(#PB_Any, "Arial" , 14)
If InitSprite() = 0 Or InitKeyboard()=0
MessageRequester("Error", "Can't open screen & sprite environment!", 0)
End
EndIf
OpenWindow(0, 0, 0, 1000, 800, "Show plotting using scaling", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
SetWindowColor(0,$E9F2C7)
TextGadget(50,300,50,400,35,"Hit D,Y,R and see what happens"+#CRLF$+"click on graph to display x,y data")
SetGadgetColor(50,#PB_Gadget_BackColor,$E9F2C7):SetGadgetFont(50,font2)
TextGadget(51,250,650,400,15,"Move slider and observe")
SetGadgetColor(51,#PB_Gadget_BackColor,$E9F2C7):SetGadgetFont(51,font2)
OpenWindowedScreen(WindowID(0), 100, 100, 501, 501)
ScrollBarGadget(#HScrollPoint,100, 600, 500, 20, 0, endpoint, 0)
SetGadgetState(#HScrollPoint,endpoint)
BindGadgetEvent(#HScrollPoint, @BindHScroll()) ;so can read scroll bar while scrolling
TextGadget(#tbox,50,50,20,15,"00")
AddWindowTimer(0,1,1000)
Gosub plot ;draw first plot, then wait for input
Repeat
WaitWindowEvent()
Event = WindowEvent()
If event= #PB_Event_CloseWindow
End
EndIf
If event = #PB_Event_Gadget
If EventGadget() = #HScrollPoint ;xaxis scroll moved change lastpoint
If IsGadget(#HBar) ;only display mass box while scrolling
FreeGadget(#HBar)
EndIf
endpoint=GetGadgetState(#HScrollPoint) ;move end of x axis to scroll point
Gosub plot
EndIf
EndIf
ExamineKeyboard()
If KeyboardReleased(#PB_Key_D) ;half x range
endpoint=endpoint/2
SetGadgetAttribute(#HScrollPoint,#PB_ScrollBar_Maximum,endpoint)
SetGadgetState(#HScrollPoint,endpoint)
Gosub plot
ElseIf KeyboardReleased(#PB_Key_Y) ;double y range
ymin=ymin*2 :ymax=ymax*2
Gosub plot
ElseIf KeyboardReleased(#PB_Key_R) ;reset x,y ranges
ymin=-1:ymax=1 :endpoint=NumberofElements
SetGadgetAttribute(#HScrollPoint,#PB_ScrollBar_Maximum,endpoint)
SetGadgetState(#HScrollPoint,endpoint)
Gosub plot
ElseIf Event=#PB_Event_LeftClick ;Show info about point clicked on graph display
x.f=WindowMouseX(0)-100
pt=Round(endpoint*x/ScreenWidth(),#PB_Round_Nearest)
If pt>=0 And pt=<endpoint
TextGadget(#xytext, 300, 110, 50, 50,"X= "+Str(pt)+#CRLF$+"Y= "+StrD(sinewave(pt),3))
SetGadgetColor(#xytext,#PB_Gadget_BackColor,$FFFFFF)
EndIf
EndIf
If event=#PB_Event_Timer ;note: no updates during scrolling
SetGadgetText(#tbox,Str(a))
a=a+1
EndIf
ForEver
Plot:
ClearScreen($FFFFFF)
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent | #PB_2DDrawing_Outlined)
LineXY(0,0,500,500,0) ;draw line not using scaling procedures, note lower right corner is 500,500
ScrnScale(0,500,0,500)
LineXY(ScrnX(0),Scrny(0),Scrnx(500),Scrny(0),0) ;Draw axes, lower right corner is now 500,0
LineXY(ScrnX(0),Scrny(0),Scrnx(0),ScrnY(500),0)
LineXY(ScrnX(0),Scrny(500),Scrnx(500),Scrny(500),0)
LineXY(ScrnX(500),Scrny(0),Scrnx(500),Scrny(500),0)
Ticksize=0.015*xsize ;draw tick marks
For i=1 To 9
xpoint.f=i*xsize/10.0: ypoint.f=i*ysize/10.0
LineXY(xpoint,ysize+TickSize,xpoint,ysize,0) ;bottom ticks
LineXY(0,ypoint,TickSize,ypoint,0) ;left ticks
LineXY(xpoint,0,xpoint,TickSize,0) ;top ticks
LineXY(xsize,ypoint,xsize-TickSize,ypoint,0) ;right ticks
Next
ScrnScale(0,100,0,100)
LineXY(ScrnX(0),Scrny(0),Scrnx(100),Scrny(100),$41FC32) ;Draw a diagonal line
ScrnScale(0,endpoint,ymin,ymax) ;set scale to plot sine wave values
lastx=scrnx(0):lasty=scrny(SineWave(0))
FrontColor($FF0000)
For i=0 To endpoint
xpoint=scrnx(i):ypoint=scrny(SineWave(i))
LineXY(lastx,lasty,xpoint,ypoint)
lastx=xpoint:lasty=ypoint
Next
DrawingFont(FontID(font1)) ;label axes
tsize=TextWidth("1234")
DrawText(3,480,"0",0)
DrawText(250-tsize/2,480,RSet(Str(endpoint/2),4),0)
DrawText(495-tsize,480,RSet(Str(endpoint),5),0)
DrawText(3,3,StrF(ymax,2),0)
DrawText(3,460,StrF(ymin,2),0)
StopDrawing()
FlipBuffers()
Return
End