|
|
Selecting an interval
Problem
The user shall be able to interactively set the left and right boundaries of an interval on the abscissa.
Solution
There are several ways to
achieve this. The fastest and easiest method is to use the cursors. As an alternative, a pair of vertical marker lines can be used. A third option is to use an inactive tolerance line with the filled
bands curve style to highlight the selected interval.
This application note will demonstrate all three methods.
|
 |
Using the cursors |
Using the cursors is fast because DynaPlot only restores the hidden parts beneath the cursor line and
does not have to redraw the complete picture every time a cursor is moved.
The code below demonstrates how to initialize the chart and how to get at the cursor positions. Only
the coordinates of the active cursor are accessible. To get at the coordinates of the second cursor
you have to activate it first. This done by setting property Cursors.ActiveCursorIndex.We might also have called DynaPlot1.Action.CallActionFunction dpsTOGGLECURSORS to make the cursors swap their
roles. This is demonstrated in routine Command1_Click.
|
Const NumberOfPoints = 200
Dim Y(NumberOfPoints - 1) As Double
Private Sub Form_Load() Dim i As Long Dim xBegin As Double, xEnd As Double, yCursor As Double
With DynaPlot1.Axes xBegin = .XAxis.From + (.XAxis.To - .XAxis.From) * 0.25 xEnd = .XAxis.From + (.XAxis.To - .XAxis.From) * 0.75
yCursor = (.YAxis.From + .YAxis.To) / 2 End With
' some curve data For i = 0 To NumberOfPoints - 1
Y(i) = 50 * Sin(i * 0.1) Next
DynaPlot1.DataCurves.AddParametric "Curve1", 0, 0.1, Y, -1
' switch cursors on
DynaPlot1.Cursors.Enable.State = True DynaPlot1.Cursors.Type = dpsCURSOR_VERTLINE
DynaPlot1.Cursors.Floating.State = True
' position first cursor
DynaPlot1.Cursors.Move xBegin, yCursor
' show and activate second cursor DynaPlot1.Cursors.ActiveCursorIndex = 1 ' position second cursor
DynaPlot1.Cursors.Move xEnd, yCursor
' activate first cursor again DynaPlot1.Cursors.ActiveCursorIndex = 0
End Sub
Private Sub Command1_Click()
Dim xBegin As Double, xEnd As Double
xBegin = DynaPlot1.Cursors.PositionX DynaPlot1.Action.CallActionFunction dpsTOGGLECURSORS
xEnd = DynaPlot1.Cursors.PositionX DynaPlot1.Action.CallActionFunction dpsTOGGLECURSORS
MsgBox "Now doing something with the selected curve portion from " & xBegin & " to " & xEnd
End Sub
|
|
 |
Marker lines |
Instead of the built-in cursors marker lines can be used to set the boundaries of the interval. Markers
have a text field which can be used to grab the line with the mouse and move it to the desired position. This method is more convenient than the first method where a cursor has to be activated
before it can be moved. Notice however, that because the complete chart has to be redrawn every time a marker is moved, this method is slower than the first one.
This first block of code for this example shows the important parts of the Load subroutine. Two
markers with vertical lines as marker symbols are added to DynaPlot's marker collection. The text
field of the first marker contains text "Begin" and is positioned to the left of the line. The second
marker is labeled "End" and its text field appears to the right of the vertical line. Both markers are
made active so that a rectangle is drawn around the text when the mouse is over it and it is included in the list of markers which are tested in method HitTest.
|
Const NumberOfPoints = 200
Const BeginLabel = "Begin" Const EndLabel = "End" Dim Y(NumberOfPoints - 1) As Double Dim LockedToMarker As Integer
Private Sub Form_Load()
Dim i As Long Dim M As Marker Dim xBegin As Double, xEnd As Double, yMarker As Double Dim MarkerSymbol As DYNAPLOT3Lib.dpsMARKERTYPE
With DynaPlot1.Axes.XAxis xBegin = .From + (.To - .From) * 0.25 xEnd = .From + (.To - .From) * 0.75 End With
With DynaPlot1.Axes.YAxis yMarker = (.From + .To) / 2 End With
MarkerSymbol = dpsMARKER_VERTLINE
LockedToMarker = -1 ' locked to nothing
For i = 0 To NumberOfPoints - 1 Y(i) = 50 * Sin(i * 0.1) Next
DynaPlot1.DataCurves.AddParametric "Curve1", 0, 0.1, Y, -1
Set M = DynaPlot1.Markers.Add(xBegin, yMarker, vbYellow, MarkerSymbol)
M.TextPosition = dpsPOSITION_LEFT M.Active = True M.Name = BeginLabel
Set M = DynaPlot1.Markers.Add(xEnd, yMarker, vbYellow, MarkerSymbol)
M.TextPosition = dpsPOSITION_RIGHT M.Active = True M.Name = EndLabel
MarkerText(0).Text = Str(xBegin) MarkerText(1).Text = Str(xEnd)
End Sub
|
When a mouse button is pressed, we check if the mouse is over one of the markers and store its
index number in variable LockedToMarker.
|
Private Sub
DynaPlot1_MouseDown(Button As Integer, Shift As Integer, X As Long, Y As Long) LockedToMarker = DynaPlot1.Markers.HitTest(X, Y) End Sub
|
We use this information in the MouseMove handler function. If LockedToMarker is a valid marker
index, we move the respective marker to the current mouse position.
|
Private Sub
DynaPlot1_MouseMove(Button As Integer, Shift As Integer, X As Long, Y As Long)
If LockedToMarker >= 0 Then Dim NewPositionX As Double
NewPositionX = DynaPlot1.Axes.XAxis.PhysicalCoordinate(X) MarkerText(LockedToMarker).Text = Str(NewPositionX)
DynaPlot1.Markers.Item(LockedToMarker).PositionX = NewPositionX End If End Sub
|
Finally, if the user releases the mouse button. We simply set LockedToMarker=-1 to disable this
mechanism.
|
Private Sub
DynaPlot1_MouseUp(Button As Integer, Shift As Integer, X As Long, Y As Long) LockedToMarker = -1 End Sub
|
We are nearly finished now. To keep the text labels vertically centered in the plot area, even if the
user scrolls the chart, we need to add some code in the Zoomed event handler.
|
' called when the
scale boundaries change due to a zoom, scroll or pan operation Private Sub DynaPlot1_Zoomed(ByVal XLeft As Double, ByVal XRight As Double, ByVal YBottom As Double, ByVal YTop As
Double) ' move the markers so they remain centered vertically DynaPlot1.Markers(0).PositionY = (YBottom + YTop) / 2#
DynaPlot1.Markers(1).PositionY = DynaPlot1.Markers(0).PositionY End Sub
|
|
 |
Highlighted band |
This method is similar to the preceding one. We use a pair of markers as handles to grab the left and
right boundaries of a highlighted band. The band is an inactive tolerance curve with curve styles dpsCURVESTYLE_BANDFROMBOTTOM and dpsCURVESTYLE_FILLEDBAND set. The curve consists of
only two points sitting at the upper left and upper right corners of the visible band.
I
In order to activate the band we have to make a few modifications in our program. In subroutine
Load add the following code. We can do without the vertical marker lines now, so MarkerSymbol can be set to dpsCURSOR_NONE. Arrays xarr and yarr contain the coordinates of the two curve points.
|
Dim T As TolCurve
Dim xarr(1) As Double Dim yarr(1) As Double xarr(0) = xBegin xarr(1) = xEnd yarr(0) = DynaPlot1.Axes.YAxis.To yarr(1) = DynaPlot1.Axes.YAxis.To
MarkerSymbol = dpsMARKER_NONE
Set T = DynaPlot1.TolCurves.Add("Highlight", xarr, yarr, -1, dpsTOL_NONE, False, True)
T.Curve.CurveStyle = dpsCURVESTYLE_BANDFROMBOTTOM + dpsCURVESTYLE_FILLEDBAND
|
In handler Cursor_Moved add this line to let the curve points follow the current mouse position.
|
DynaPlot1.TolCurves.Item(0).Curve.Xval(LockedToMarker) = NewPositionX
|
In event handler Zoomed add these lines to ensure that the curve points stay at the upper boundary of
the visible scale.
|
' move the tolerance curve to the new top of the scale
' we don't have to care about the bottom because ' the curve style is band from bottom DynaPlot1.TolCurves(0).Curve.Yval(0) = YTop
DynaPlot1.TolCurves(0).Curve.Yval(1) = YTop
|
Selecting rectangular regions
The above methods can be readily extended to two dimensions
|
 |
Marker lines |
Two more markers lines were added.
|
 |
Highlighted rectangle |
The tolerance curve now has the curve style attribute dpsCURVESTYLE_BANDFROMBOTTOM unset
which lets you define the base line of the band.
Download VB example projects
SelectPortion3.zip
SelectRectRegion3.zip
|