ProEssentials charting components provides simple features to efficiently handle your oscilloscope-type real-time and strip-chart data. This information shows code in VB.NET; working C#, Visual Basic and MFC examples are available when downloading our evaluation.
Real-Time Strip-Charting Prerequisites: It is recommended that one first studies our basic initial walk-throughs on learning how to create your first ProEssentials hello-world type application.
Real-Time charts can be implemented in a variety of ways.
All ProEssentials objects can be used in real-time scenarios. What we mean by real-time is the repeated process of changing the control's data and/or properties and refreshing the image.
The Pego charting control will be used when your real-time data does not have XData, but is a simple list of YData values with optional string PointLabel data that describes the piece of YData. The properties AppendYData and AppendPointLabelData are the only features needed to implement a strip chart. The direction of the shift is controlled with the property AppendToEnd.
When downloading our canned demo or evaluation, search for example and string to find content related to a simple Pego real-time example implementation. Viewing this example in action will help you understand this overview.
An oscilloscope type implementation is shown in our demo project example 115, using the Pesgo chart and Direct3D / DirectX rendering. In this mode, you will not use AppendYData, but completely repass the entire data with each update.
The below animated image shows a few frames, an initial empty frame, and then frames after 5 more updates each. The chart shows data across entire chart after 20 updates.
Below is the example code that will produce this real-time strip chart. The first section is used to initialize the chart, preparing for real-time operation, and generally located in a Window Show or Page or Control Load type event.. The second section is used in a timer or other repeated event. C#, C/C++, Pascal VCL code will be similar in structure.
Note: The following example assumes a simple project, one form, one Pego control and one Timer control on the form.
'// No Flicker //
Pego1.PeConfigure.PrepareImages = True
Pego1.PeConfigure.CacheBmp = True
'// Set Subsets and Points //
Pego1.PeData.Subsets = 2 '// set number of subsets
Pego1.PeData.Points = 200 '// number of data points
Pego1.PeUserInterface.Scrollbar.PointsToGraph = 20
Pego1.PeUserInterface.Scrollbar.PointsToGraphInit = PointsToGraphInit.Last
Pego1.PePlot.Method = GraphPlottingMethod.Point
'// Main Title
Pego1.PeString.MainTitle = "Graph Real Time Example"
Pego1.PeString.SubTitle = "" '// no subtitle
'// Manually configure scales //
Pego1.PeGrid.Configure.ManualScaleControlY = ManualScaleControl.MinMax
Pego1.PeGrid.Configure.ManualMinY = 1.0
Pego1.PeGrid.Configure.ManualMaxY = 100.0
Pego1.PeGrid.Configure.ManualMaxDataString = "000.000"
Pego1.PeGrid.Configure.ManualMaxPointLabel = "00:00:00xx"
Pego1.PePlot.Allow.StackedData = False
Pego1.PeUserInterface.Dialog.PointsToGraph = False
Pego1.PePlot.Allow.Histogram = False
Pego1.PeUserInterface.Allow.FocalRect = False
Pego1.PeGrid.LineControl = GridLineControl.None
Pego1.PeData.Precision = 1
'// Needed to allocate point labels so append has something to rotate //
'// Set last point label, Points - 1 //
Pego1.PeString.PointLabels(199) = ""
'// Reset first four data points, default 0 is null and hides, see NullDataValue
Pego1.PeData.Y(0, 0) = 0
Pego1.PeData.Y(0, 1) = 0
Pego1.PeData.Y(0, 2) = 0
Pego1.PeData.Y(0, 3) = 0
'// Set a few colors and etc //
Pego1.PeColor.BitmapGradientMode = False
Pego1.PeColor.QuickStyle = QuickStyle.DarkNoBorder
Pego1.PeFont.Fixed = True
Pego1.PeColor.SubsetColors(0) = Color.FromArgb(255, 0, 198, 0)
Pego1.PeColor.SubsetColors(1) = Color.FromArgb(255, 255, 255, 255)
'// Finish Initialization //
Timer1.Interval = 250
Timer1.Enabled = True
Real-Time Chart Initialization Explanation
Setting PrepareImages to TRUE is important and gives you flicker-free output.
Next, Subsets and Points define how much data the object will hold, PointsToGraph is set to 20 and controls how much data the user will see. There will be a horizontal scrollbar to pan left and right through data. PointsToGraphInit controls whether the first 20 or last 20 points are initially displayed.
Next, the graph's y axis is manually configured. This is because during the control's real-time operation, it will not automatically adjust the scales. However, if you do want the chart's scale to adjust during real-time, this is possible and is discussed later. ManualMaxDataString and ManualMaxPointLabel are used to set a string which would represent the largest string in either the table or PointLabels respectively. This is used to reserve space during the object's image construction process to prevent overlapping text.
Next, a few properties are set which are recommended for real-time operation.
Next, the last PointLabel element is set to a null string. This allocates memory for all PointLabels and this is necessary for the append logic to work correctly. If memory is not pre-allocated, there will be nothing to shift.
Next, the first four default data points are set to zero. The default NullDataValue is zero so these lines of code essentially empty the graph of all data. Thus starting with an empty chart.
Finally, the chart control is initialized with PeFunction.ReinitializeResetImage, and the timer mechanism is started.
Dim CurrentTime As String
'// prepare new point label //
CurrentTime = Now.Hour.ToString + ":" + Now.Minute.ToString + ":" + Now.Second.ToString
'// prepare new YData //
Dim NewData(2) As Single
NewData(0) = (Rnd() * 20) + 2
NewData(1) = (Rnd() * 40) + 60
'// transfer new point label //
PEvsetW(Pego1.PeSpecial.hObject, DllProperties.APPENDPOINTLABELDATA, CurrentTime, 1)
'// transfer new YData, this will also update and show new image //
PEvsetW(Pego1.PeSpecial.hObject, DllProperties.APPENDYDATA, NewData, 1)
Strip-Chart Timer Explanation
Within the timer event, we prepare new PointLabels and YData to append to the chart.
CurrentTime is a string which will show below the new data value. One will use PEvsetW and AppendPointLabelData to pass the address of a null-terminated string to append to the PointLabels property array.
New YData is also prepared and also passed by reference. Since this control contains 2 subsets, and we will be updating one sample's worth of data, 2 pieces of data are prepared for appending to the YData array. Note that the last argument in the PEvsetW call is 1. This stands for 1 new sample. Since the control knows how many subsets are included in the object (2), it will automatically look for 2 pieces of data. This is different in how PEvsetW is used with the non-appending type properties. If more than one sample's worth of data is being appended, you still format the data in a single dimension array. In this case you will prepare all of the first subset's data, followed by the second subset's data and so on. Using PEvsetW with AppendYData also has a special function of resetting and updating the image. Because of this, you will always use AppendYData after AppendPointLabelData.
If you need the graph to update the y axis while in a real-time operation, call PeFunction.ReintializeResetImage() and Refresh() at the end of the timer event.