Page 1 of 1

XVal to Yvalues collection (version 7)

Posted: Mon Jun 05, 2006 2:58 pm
by 9530819
If my bottom axis has a different numbr of points to the actual number of series points (as per the yvalues collection) then there is no way to relate the XVal parameter in the OnCursorToolChange event with the actual value plotted?

Meaning this line of code for example is invalid:
label.caption = tchart1.series(0).yavlues.value(xval)

Is there a way around this problem that does not require tons of unnecessary coding?

I tried associating the series with the Cursor tool in the hopes that the ValueIndex would then give me the right index to use in the yvalue collection but I only ever get -1 in the ValueIndex parameter of the OnCursorToolChange event.

Help...

Posted: Tue Jun 06, 2006 8:46 am
by narcis
Hi Rossmc,

You can try doing something like this:

Code: Select all

Private Sub TChart1_OnCursorToolChange(ByVal Tool As Long, ByVal X As Long, ByVal Y As Long, ByVal XVal As Double, ByVal YVal As Double, ByVal Series As Long, ByVal ValueIndex As Long)
    Dim Index As Integer
    
    Index = TChart1.Series(0).Clicked(X, Y)
    
    If Index <> -1 Then
        Label1.Caption = CStr(TChart1.Series(0).YValues.Value(Index))
    End If
End Sub
or

Code: Select all

Private Sub TChart1_OnCursorToolChange(ByVal Tool As Long, ByVal X As Long, ByVal Y As Long, ByVal XVal As Double, ByVal YVal As Double, ByVal Series As Long, ByVal ValueIndex As Long)
    Label1.Caption = CStr(TChart1.Axis.Left.CalcPosPoint(Y))
End Sub

RE: XVal to Yvalues collection

Posted: Tue Jun 06, 2006 10:30 am
by 9530819
Hi Narcis

Unfortunately those solutions don't give me what I really need.

My real problem is I need to know the YValue where the vertical TeeCursor intersects with the Series on the screen.

For your first solution:
> Index = TChart1.Series(0).Clicked(X, Y)
I won't get the right value unless the mouse cursor happens to be at the same point that the teecursor and series line are intersecting. If the Y parameter above could be converted to the Y position where the teecursor and series intersect then I would get the correct value.

The second solution simply gives me the y value on the axis relative to the mouse cursors position which as I said before is not really what I need.

Any other thoughts on this?

Posted: Tue Jun 06, 2006 11:33 am
by narcis
Hi Rossmc,
For your first solution:
> Index = TChart1.Series(0).Clicked(X, Y)
I won't get the right value unless the mouse cursor happens to be at the same point that the teecursor and series line are intersecting. If the Y parameter above could be converted to the Y position where the teecursor and series intersect then I would get the correct value.
Ok, then this can be easily solved by setting the cursor tool to snap:

Code: Select all

    TChart1.Tools.Items(0).asTeeCursor.Snap = True

RE: XVal to Yvalues collection

Posted: Fri Jun 23, 2006 9:29 am
by 9530819
Hi

Sorry, I keep coming back to this. With .Snap = True I now get a correct ValueIndex and at face value this looks like a solution.

The problem is the complexity of my chart. For example, I have a main line, three moving averages (each with a different period) and a further line as an overlay. I want to know the value of every point where the vertical teeCursor intersects them.

If we had something like .IntersectingValue(SeriesIndex) that returned the y-axis value where the teeCursor intersected the line that would be ideal.

Posted: Fri Jun 23, 2006 9:38 am
by narcis
Hi Rossmc,

Yes, to achieve what you request you can interpolate through each series X value doing something like this:

Code: Select all

Private Sub Form_Load()
    For i = 0 To TChart1.SeriesCount - 1
        TChart1.Series(i).FillSampleValues (i + 1) * 20
    Next
    
    
End Sub

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_OnCursorToolChange(ByVal Tool As Long, ByVal X As Long, ByVal Y As Long, ByVal XVal As Double, ByVal YVal As Double, ByVal Series As Long, ByVal ValueIndex As Long)
    TChart1.Header.Text.Clear
    For i = 0 To TChart1.SeriesCount - 1
        TChart1.Header.Text.Add ("Series" + CStr(i) + ": Y(" + CStr(XVal) + ")= " + _
                 CStr(InterpolateLineSeries(i, TChart1.Series(i).FirstValueIndex, TChart1.Series(i).LastValueIndex, XVal)))
                'CStr(InterpolateLineSeries(i, 0, TChart1.Series(i).Count - 1, XVal)))
    Next
End Sub