Page 1 of 1

Drawing Series on Existing Chart

Posted: Wed Sep 02, 2020 12:16 am
by 15049432
I suspect there isn't an easy way to do what I want, but I thought I'd check before I set off trying something complicated! :D

I have an existing line series representing an elevation profile. I would like the user to be able to manually draw a number of new series on top of that profile such that:
  • The new series will 'stick' to the profile - the points of the new series are a sub-set of the profile series.
  • The start and end points of the new series are highlighted and distinct.
  • The start and end points should be draggable.
  • The new series' cannot overlap - dragging the end point of one should 'push' or 'pull' the endpoints of any adjacent series.
Profile.png
Profile.png (14.38 KiB) Viewed 26472 times
So in the above image the user has added the three green lines, the start points are indicated by a green splodge, then end points by a red splodge. The user can then drag these endpoints up and down the profile to make the green lines longer or shorter.

I think I could use a cursor tool fixed to the profile series in order to 'gather' the points for the new series initially, then a drag point tool to allow the start and end point interaction. But is there a way to restrict the dragged points to values of the existing profile series?

Cheers!

Re: Drawing Series on Existing Chart

Posted: Tue Sep 08, 2020 10:12 am
by yeray
Hello,

You can use extra line series to draw the green segments and extra point series to draw the start and end pointers for these segments.
Then, you can use mouse events (mousedown, mouseup, mousemove) to modify the series points as you require.
I've written a simple example to start with, but the difficulty here is to write the logic to control all the situations you described and I'm afraid there's no TeeChart feature designed to do it for you.

Code: Select all

Dim dragging As Integer

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
    
    .Zoom.Enable = False
    .Scroll.Enable = pmNone
    
    .Hover.Hide
    
    .AddSeries scArea
    .Series(0).FillSampleValues 100
    .Series(0).asArea.AreaPen.Visible = False
    .Series(0).Color = RGB(175, 50, 50)
    .Series(0).Transparency = 50
    
    .AddSeries scLine
    .Series(1).DataSource = .Series(0)
    .Series(1).asLine.LinePen.Width = 3
    .Series(1).Color = RGB(127, 0, 0)
    
    .AddSeries scPoint
    .Series(2).Color = vbRed
    .Series(2).asPoint.Pointer.SizeFloat = 2
    .Series(2).asPoint.Pointer.Style = psCircle
  End With

End Sub

Private Sub TChart1_OnClickSeries(ByVal SeriesIndex As Long, ByVal ValueIndex As Long, ByVal Button As TeeChart.EMouseButton, ByVal Shift As TeeChart.EShiftState, ByVal X As Long, ByVal Y As Long)
  Dim diff As Integer
  diff = 2
  If SeriesIndex = 1 Then
    TChart1.AddSeries scLine
    With TChart1.Series(TChart1.SeriesCount - 1)
      .Color = RGB(40, 160, 70)
      .asLine.LinePen.Width = 3
      For i = ValueIndex - diff + 1 To ValueIndex + diff
        .AddXY TChart1.Series(1).XValues.Value(i), TChart1.Series(1).YValues.Value(i), "", clTeeColor
      Next i
    End With
    TChart1.ExchangeSeries TChart1.SeriesCount - 1, TChart1.SeriesCount - 2
    With TChart1.Series(TChart1.SeriesCount - 2)
      TChart1.Series(TChart1.SeriesCount - 1).AddXY .XValues.Value(0), .YValues.Value(0), "", RGB(14, 75, 30)
      TChart1.Series(TChart1.SeriesCount - 1).AddXY .XValues.Value(.Count - 1), .YValues.Value(.Count - 1), "", vbRed
    End With
  End If
End Sub

Private Sub TChart1_OnMouseMove(ByVal Shift As TeeChart.EShiftState, ByVal X As Long, ByVal Y As Long)
  If dragging Or TChart1.Series(TChart1.SeriesCount - 1).Clicked(X, Y) > -1 Then
    SetCursor LoadCursor(0, IDC_HAND)
    If dragging Then
      ' Find line series related, find nearest point of the first series to the cursor, set all the points in the line series and set the dragging point to the nearest point found
    End If
  Else
    If TChart1.Series(1).Clicked(X, Y) > -1 Then
      Screen.MousePointer = vbCrosshair
    Else
      Screen.MousePointer = vbDefault
    End If
  End If
End Sub

Private Sub TChart1_OnMouseDown(ByVal Button As TeeChart.EMouseButton, ByVal Shift As TeeChart.EShiftState, ByVal X As Long, ByVal Y As Long)
  dragging = TChart1.Series(TChart1.SeriesCount - 1).Clicked(X, Y)
End Sub

Private Sub TChart1_OnMouseUp(ByVal Button As TeeChart.EMouseButton, ByVal Shift As TeeChart.EShiftState, ByVal X As Long, ByVal Y As Long)
  dragging = -1
End Sub
test.png
test.png (20.88 KiB) Viewed 26216 times

Re: Drawing Series on Existing Chart

Posted: Wed Sep 09, 2020 8:59 pm
by 16689453
Thanks Yeray - I tried this and got it working.

But then I found it was simpler to have fewer series' and use OnGetSeriesPointerStyle to do my end marks :)

Re: Drawing Series on Existing Chart

Posted: Thu Sep 10, 2020 2:04 pm
by yeray
Great, thanks for sharing!