I needed to graph simple quantities, so tried to use the gb.Chart component. Unfortunately (at the time of writing) this does not appear to work.
So, inspired by an old paper chart pen recorder, I created this simple chart class.
To play with this, just create a new Gambas project, add a new (blank) class and name it "clsPaperChart", then copy & paste the class code at the bottom of this post.
On the main project form, add a Timer and a DrawingArea.
In the main form:-
'Declare a new chart object
PUBLIC myChart AS NEW clsPaperChart
PUBLIC SUB Form_Open()
WITH myChart
.DrawArea = DrawingArea1
.intMarkerWidth = 3
.intMaxYaxis = 100
.fAlarmLevel = 90
.blnSelfTest=TRUE
END WITH
Timer1.Delay=1000
Timer1.Start()
END
PUBLIC SUB Timer1_Timer()
myChart.PlotPoint(0)
ME.Caption = myChart.strLastDataPoint
END
When you run this program, myChart will generate its own random data. If you set blnSelfTest=FALSE you will need to supply your own data via the PlotPoint method.
Depending upon the size of your Drawing Area and the number of data points (intMaxPoints) you may find the plot does not reach the bottom of the drawing area. You can adjust this by changing the bar width (intMarkerWidth) or increasing the number of data points ((intMaxPoints). You could also modify the class to scale this automatically.
The clsPaperChart class:-
' Gambas class file
'
'clsPaperChart
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'A simple class to plot a chart similar to a paper chart pen recorder.
'
'Steve Davis
'December 2009
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
PROPERTY DrawArea AS DrawingArea 'where we draw our chart
PRIVATE dArea AS DrawingArea
PROPERTY intMaxYaxis AS Integer 'chart scale
PRIVATE intMaxY AS Integer
PROPERTY strUnits AS String 'examples; "%", "kHz"
PRIVATE strUnitType AS String
PROPERTY intMarkerWidth AS Integer 'chart data marker or bar width
PRIVATE intMarkWidth AS Integer
PROPERTY intMaxPoints AS Integer 'max number of data points
PRIVATE intMaxPts AS Integer
PROPERTY fAlarmLevel AS Float 'value=0 to disable
PRIVATE fAlarm AS Float
PROPERTY blnSelfTest AS Boolean 'generate random data for chart
PRIVATE bTest AS Boolean
PROPERTY READ strLastDataPoint AS String 'Data point + units + timestamp
PRIVATE strLastPoint AS String
PRIVATE fPoints AS Float[] 'array of data points
PRIVATE intPoints AS Integer 'number of data points
PRIVATE CONST FULL_SCALE AS Float = 1 'using full chart width
PUBLIC SUB _new()
fPoints = NEW Float[]
'set defaults
intMaxPts = 100
intMaxY = 100
END
PUBLIC SUB PlotPoint(fData AS Float)
DIM index AS Integer
DIM fScale AS Float 'use to scale data to plot
DIM fAlarming AS Float 'scaled alarm level
fScale = FULL_SCALE * dArea.Width / CFloat(intMaxY)
fAlarming = fscale * fAlarm
fPoints.Resize(intPoints + 1)
IF fPoints.Max > intMaxPts THEN fPoints.Resize(intMaxPts)
FOR index = fPoints.Max TO 1 STEP -1
fPoints[index] = fPoints[index - 1]
NEXT
IF bTest THEN 'use random test data
fData = Rnd(0, intMaxY)
ENDIF
fPoints[0] = fscale * fData
INC intPoints
strLastPoint = "Last: " & Round(fData, 0) & strUnitType & " @" & Format(Now(), "hh:mm:ss")
' lblRange.Text = intRange & strUnits
dArea.Clear
draw.Begin(dArea)
draw.LineWidth = 1
IF intMarkWidth < 1 THEN intMarkWidth = 1
IF fAlarming > 0 THEN 'create a red alarm line
draw.ForeColor = Color.Red
draw.Line(fAlarming, 0, fAlarming, dArea.ClientH)
ENDIF
draw.ForeColor = Color.LightGray
draw.Line(0.75 * FULL_SCALE * dArea.ClientWidth, 0, 0.75 * FULL_SCALE * dArea.ClientWidth, dArea.ClientH)
draw.Line(0.5 * FULL_SCALE * dArea.ClientWidth, 0, 0.5 * FULL_SCALE * dArea.ClientWidth, dArea.ClientH)
draw.Line(0.25 * FULL_SCALE * dArea.ClientWidth, 0, 0.25 * FULL_SCALE * dArea.ClientWidth, dArea.ClientH)
'Plot data
FOR index = 0 TO fPoints.Max
IF fAlarming > 0 AND fPoints[index] > fscale * fAlarm THEN
draw.ForeColor = color.Red 'red bars
ELSE
draw.ForeColor = color.Blue 'blue bars
ENDIF
draw.LineWidth = intMarkWidth
draw.Line(0, (index + 1) * intMarkWidth, fPoints[index], (index + 1) * intMarkWidth)
NEXT
Draw.End
END
'++++Class Properties+++++++++++++++++++++++++++++++++
PRIVATE FUNCTION DrawArea_Read() AS DrawingArea
RETURN dArea
END
PRIVATE SUB DrawArea_Write(Value AS DrawingArea)
dArea = Value
dArea.Cached = TRUE
dArea.Border = 2
END
PRIVATE FUNCTION intMaxYaxis_Read() AS Integer
RETURN intMaxY
END
PRIVATE SUB intMaxYaxis_Write(Value AS Integer)
intMaxY = Value
END
PRIVATE FUNCTION strUnits_Read() AS String
RETURN strUnitType
END
PRIVATE SUB strUnits_Write(Value AS String)
strUnitType = Value
END
PRIVATE FUNCTION intMarkerWidth_Read() AS Integer
RETURN intMarkWidth
END
PRIVATE SUB intMarkerWidth_Write(Value AS Integer)
intMarkWidth = Value
END
PRIVATE FUNCTION intMaxPoints_Read() AS Integer
RETURN intMaxPts
END
PRIVATE SUB intMaxPoints_Write(Value AS Integer)
intMaxPts = Value
END
PRIVATE FUNCTION blnSelfTest_Read() AS Boolean
RETURN bTest
END
PRIVATE SUB blnSelfTest_Write(Value AS Boolean)
bTest = Value
END
PRIVATE FUNCTION strLastDataPoint_Read() AS String
RETURN strLastPoint
END
PRIVATE FUNCTION fAlarmLevel_Read() AS Float
RETURN fAlarm
END
PRIVATE SUB fAlarmLevel_Write(Value AS Float)
fAlarm = Value
END