Page 1 of 1
Drawing line between two cursors?
Posted: Tue Oct 13, 2020 9:08 pm
by 16689453
I have two series on my chart, each with a cursor. Is there a way to draw a vertical line between the cursors to indicate the difference between the series values? (ideally, if I could display the value of the difference by the line that would be great).
Something like the yellow line here:
- Untitled.png (6.55 KiB) Viewed 40388 times
Or is there another way to do this?
Re: Drawing line between two cursors?
Posted: Wed Oct 14, 2020 2:04 pm
by yeray
Hello,
You should calculate the Interpolation points and draw the line manually. You could use the AnnotationTool to draw the difference value.
Here a simple example:
Code: Select all
Dim XPos, YVal1, YVal2 As Double
Private Sub Form_Load()
With TChart1
.Aspect.View3D = False
.Legend.Visible = False
.Panel.Gradient.Visible = False
.Panel.Color = vbWhite
.Walls.Back.Gradient.Visible = False
.Walls.Back.Color = vbWhite
.Axis.Left.GridPen.Visible = False
.Axis.Bottom.GridPen.Visible = False
.AddSeries scFastLine
.Series(0).FillSampleValues 25
.AddSeries scFastLine
.Series(1).FillSampleValues 25
.Tools.Add tcAnnotate
End With
XPos = -1
End Sub
Function InterpolateSeries(ByVal SeriesIndex As Long, ByVal XValue As Double) As Double
InterpolateSeries = InterpolateLineSeries(SeriesIndex, TChart1.Series(SeriesIndex).FirstValueIndex, TChart1.Series(SeriesIndex).LastValueIndex, XValue)
End Function
Function InterpolateLineSeries(ByVal SeriesIndex As Long, FirstIndex As Integer, LastIndex As Integer, XValue As Double) As Double
Dim index As Integer
Dim dx, dy, val As Double
index = FirstIndex
Do While ((TChart1.Series(SeriesIndex).XValues.Value(index) <= XValue) And (index < LastIndex))
index = index + 1
Loop
' safeguard
If (index < 1) Then
index = 1
ElseIf (index >= TChart1.Series(SeriesIndex).Count) Then
index = TChart1.Series(SeriesIndex).Count - 1
End If
' y=(y2-y1)/(x2-x1)*(x-x1)+y1
dx = TChart1.Series(SeriesIndex).XValues.Value(index) - TChart1.Series(SeriesIndex).XValues.Value(index - 1)
dy = TChart1.Series(SeriesIndex).YValues.Value(index) - TChart1.Series(SeriesIndex).YValues.Value(index - 1)
If (dx <> 0) Then
InterpolateLineSeries = dy * (XValue - TChart1.Series(SeriesIndex).XValues.Value(index - 1)) / dx + TChart1.Series(SeriesIndex).YValues.Value(index - 1)
Else
InterpolateLineSeries = 0
End If
End Function
Private Sub TChart1_OnAfterDraw()
With TChart1.Axis
If XPos > -1 Then
TChart1.Canvas.Pen.Style = psSolid
TChart1.Canvas.Pen.Color = vbBlack
TChart1.Canvas.DrawLine XPos, .Left.CalcYPosValue(YVal1), XPos, .Left.CalcYPosValue(YVal2)
End If
End With
End Sub
Private Sub TChart1_OnMouseMove(ByVal Shift As TeeChart.EShiftState, ByVal X As Long, ByVal Y As Long)
XPos = X
XVal = TChart1.Axis.Bottom.CalcPosPoint(XPos)
YVal1 = InterpolateSeries(0, XVal)
YVal2 = InterpolateSeries(1, XVal)
TChart1.Tools.Items(0).asAnnotation.Text = Format$(YVal1 - YVal2, "#,##0.##")
TChart1.Tools.Items(0).asAnnotation.Left = XPos + 5
TChart1.Tools.Items(0).asAnnotation.Top = TChart1.Axis.Left.CalcYPosValue(YVal1) + (TChart1.Axis.Left.CalcYPosValue(YVal2) - TChart1.Axis.Left.CalcYPosValue(YVal1)) / 2
TChart1.Repaint
End Sub
Re: Drawing line between two cursors?
Posted: Fri Oct 16, 2020 12:20 am
by 16689453
Thanks Yeray - I used your example and it's working, up to a point.
If I want the line to follow the cursor (e.g., draw it in OnCursorToolChange), how do I erase the previous line before drawing the next one?
So far it just keeps drawing lines...
EDIT:
OK - I found I can remove the old lines by adding an m_Chart.Repaint() call - but that makes the update really jerky and erases the info when I stop moving the cursor. How can I help that?
EDIT 2:
Moving the m_Chart.Repaint() call - fixes the erasure on 'stop' problem. But the screen update is still super laggy
Re: Drawing line between two cursors?
Posted: Fri Oct 23, 2020 6:25 am
by yeray
Hello,
It would help if you could arrange a simple example project to see what you are exactly doing.