none
How to display information of a line chart by doing mouse over

    Question

  • Hi,

    I want to do a line chart in Visual Studio that when te mouse goes over the line it "sticks" at it and shows the (x,y) values.

    The idea of this is that the user can move the mouse to the left or right and no big precision is needed to show the information. I would also work to make a point appear over the line by just having the mouse on the chart area and the point moves with the mouse no matter where the mouse's arrow is over or near the line.

    Here are two images to show what I mean.

    In both images, the mouse is inside the chart area and below the line. The point follows the position of the arrow across the line, no matter what position it has while it is in the chart area.

    Now, with this example, the (x,y) values are shown in two boxes up there. I would like to be shown in the point itself (like in a little box or something like that).

    Any ideas?

    Thanks in advance!

    Wednesday, April 19, 2017 8:24 PM

Answers

  • pp,

    Well you will just have to work through all that one step at a time. Only you know exactly what you want to do.

    tom,

    Thats right, but I have found the best way to illustrate it.

    I have tried with MouseMove, MouseHover, AnnotationPositionChanging, among others, but I have no success. Can you help me please?

    Ok then. Just a matter of adding a chart annotation at the proper moment.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form7
        Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim MyData(12) As Single
            For i = 1 To 12
                MyData(i) = CSng(5 * Math.Sin(i / 2))
            Next
    
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Time"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisX.Minimum = 0
                .AxisX.Maximum = 14
                .AxisX.Interval = 2
                .AxisX.LabelStyle.IsEndLabelVisible = False
    
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
                .AxisY.Minimum = -6
                .AxisY.Maximum = 6
                .AxisY.Interval = 2
    
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Monthy Data")
    
            With Chart1.Series(0)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
                .Color = Color.Blue
                .MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
                .MarkerSize = 8
                .IsVisibleInLegend = False
    
                For m = 1 To 12
                    .Points.AddXY(m, MyData(m))
                Next
            End With
    
            Dim PC As New CalloutAnnotation
            With PC
                Chart1.Annotations.Add(PC)
            End With
        End Sub
    
        Private Sub Chart1_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart1.MouseMove
    
            Dim result As HitTestResult = Chart1.HitTest(e.X, e.Y)
    
            If result.ChartElementType = ChartElementType.DataPoint Then
                Chart1.Series(0).Points(result.PointIndex).XValue.ToString()
    
                Dim thisPt As New PointF(CSng(Chart1.Series(0).Points(result.PointIndex).XValue),
                                        CSng(Chart1.Series(0).Points(result.PointIndex).YValues(0)))
                Dim ta As New CalloutAnnotation
                With ta
                    .AnchorDataPoint = Chart1.Series(0).Points(result.PointIndex)
                    .X = thisPt.X + 1
                    .Y = thisPt.Y + 1
                    .Text = thisPt.ToString
                    .CalloutStyle = CalloutStyle.SimpleLine
                    .ForeColor = Color.Red
                    .Font = New Font("Tahoma", 12, FontStyle.Bold)
                End With
                Chart1.Annotations(0) = ta
                Chart1.Invalidate()
            End If
        End Sub
    End Class

    • Marked as answer by ppsev Friday, April 21, 2017 1:13 PM
    Friday, April 21, 2017 11:14 AM

  • Thank you! Finally it worked! Thank you tom :)

    By the way, is there a way to remove the "{}" from the annotation? And how can I display a date in the X part of the annotation? Now it shows "{X=43081, Y = 260}" and I would like it to be "12-12-2017, 260".

    Well you just have to sort through the examples in the samples link I gave.

    Look under chart features - annotation.

    That's what I did.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form7
        Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Time"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisX.LabelStyle.IsEndLabelVisible = False
                .AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Days
    
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
                .AxisY.Minimum = 0
                .AxisY.Maximum = 10
                .AxisY.Interval = 2
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Monthy Data")
    
            With Chart1.Series(0)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
                .Color = Color.Blue
                .MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
                .MarkerSize = 8
                .IsVisibleInLegend = False
                Dim rand As New Random(Now.Millisecond)
                For m = 1 To 12
                    Dim [date] As DateTime = DateTime.Now.Date
                    [date] = [date].AddDays(m)
                    Chart1.Series(0).Points.AddXY([date], rand.Next(0, 10))
                Next
            End With
    
            Dim PC As New CalloutAnnotation
            With PC
                Chart1.Annotations.Add(PC)
            End With
        End Sub
    
        Private Sub Chart1_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart1.MouseMove
    
            Dim result As HitTestResult = Chart1.HitTest(e.X, e.Y)
    
            If result.ChartElementType = ChartElementType.DataPoint Then
                Chart1.Series(0).Points(result.PointIndex).XValue.ToString()
    
                Dim thisPt As New PointF(CSng(Chart1.Series(0).Points(result.PointIndex).XValue),
                                        CSng(Chart1.Series(0).Points(result.PointIndex).YValues(0)))
                Dim ta As New CalloutAnnotation
                With ta
                    .AnchorDataPoint = Chart1.Series(0).Points(result.PointIndex)
                    .X = thisPt.X + 1
                    .Y = thisPt.Y + 1
                    .Text = DateTime.FromOADate(thisPt.X).ToShortDateString &
                        vbLf & "Value: " & thisPt.Y.ToString
                    .ForeColor = Color.Red
                    .Font = New Font("Tahoma", 10, FontStyle.Bold)
                End With
                Chart1.Annotations(0) = ta
                Chart1.Invalidate()
            End If
        End Sub
    End Class



    • Edited by tommytwotrain Friday, April 21, 2017 2:08 PM
    • Marked as answer by ppsev Friday, April 21, 2017 2:18 PM
    Friday, April 21, 2017 2:07 PM

All replies

  • This example gets the point from the plotted line and displays the value. Is that what you mean?

    'show mouse pointer position in chart coordinates
    Imports System.Windows.Forms.DataVisualization.Charting
    Public Class MouseChartCoordinates
        Private r As New Random
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Chart1.Legends.Clear()
            Chart1.Series.Clear()
    
            Chart1.ChartAreas(0).AxisX.Minimum = -500
            Chart1.ChartAreas(0).AxisX.Maximum = 500
            Chart1.ChartAreas(0).AxisY.Minimum = -1200
            Chart1.ChartAreas(0).AxisY.Maximum = 3600
    
            Chart1.ChartAreas(0).AxisY.Interval = 300
            Chart1.ChartAreas(0).AxisX.Interval = 125
    
            Chart1.Series.Add("Series1")
            Chart1.Series("Series1").ChartType = SeriesChartType.FastLine
            Chart1.Series("Series1").BorderWidth = 0
    
            'just to add some random data points
            Dim v As Double = 400
            For i As Integer = -500 To 500
                v += r.Next(-50, 51)
                Chart1.Series("Series1").Points.AddXY(i, v)
            Next
        End Sub
    
        Private Sub Chart1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseMove
            Dim ht As DataVisualization.Charting.HitTestResult = Chart1.HitTest(e.X, e.Y)
            If Not ht.ChartElementType = ChartElementType.Nothing Then
                Dim xx As Double = ht.ChartArea.AxisX.PixelPositionToValue(e.X)
                Dim yy As Double = ht.ChartArea.AxisY.PixelPositionToValue(e.Y)
                If xx >= Chart1.ChartAreas(0).AxisX.Minimum And xx <= Chart1.ChartAreas(0).AxisX.Maximum And
                    yy >= Chart1.ChartAreas(0).AxisY.Minimum And yy <= Chart1.ChartAreas(0).AxisY.Maximum Then
    
                    Me.Text = xx.ToString & "   " & yy.ToString
                End If
            End If
        End Sub
    End Class
    

    Thursday, April 20, 2017 12:50 AM
  • Now, with this example, the (x,y) values are shown in two boxes up there. I would like to be shown in the point itself (like in a little box or something like that).

    Any ideas?

    How about this?
    (1) add a Label
    (2) handle MouseDown and MouseUp
    (3) when MouseDown fires, get Label to be visible
         when MouseUp, Label invisible

    (a) location of Label: 
    Dim mouseDownPos as point = System.Windows.Forms.Cursor.Position
    Label.Location = New Point(mouseDownPos.X + 10, mouseDownPos.Y + 10)

    (b) contents of Label:
    as a reference, use/modify "Chart1_MouseMove" in tommytwotrain's answer.
    ________________
    Ashidacchi
    • Edited by Ashidacchi Thursday, April 20, 2017 4:58 AM modify: ToolTip > Label
    Thursday, April 20, 2017 4:55 AM
  • This example gets the point from the plotted line and displays the value. Is that what you mean?

    'show mouse pointer position in chart coordinates
    Imports System.Windows.Forms.DataVisualization.Charting
    Public Class MouseChartCoordinates
        Private r As New Random
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Chart1.Legends.Clear()
            Chart1.Series.Clear()
    
            Chart1.ChartAreas(0).AxisX.Minimum = -500
            Chart1.ChartAreas(0).AxisX.Maximum = 500
            Chart1.ChartAreas(0).AxisY.Minimum = -1200
            Chart1.ChartAreas(0).AxisY.Maximum = 3600
    
            Chart1.ChartAreas(0).AxisY.Interval = 300
            Chart1.ChartAreas(0).AxisX.Interval = 125
    
            Chart1.Series.Add("Series1")
            Chart1.Series("Series1").ChartType = SeriesChartType.FastLine
            Chart1.Series("Series1").BorderWidth = 0
    
            'just to add some random data points
            Dim v As Double = 400
            For i As Integer = -500 To 500
                v += r.Next(-50, 51)
                Chart1.Series("Series1").Points.AddXY(i, v)
            Next
        End Sub
    
        Private Sub Chart1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseMove
            Dim ht As DataVisualization.Charting.HitTestResult = Chart1.HitTest(e.X, e.Y)
            If Not ht.ChartElementType = ChartElementType.Nothing Then
                Dim xx As Double = ht.ChartArea.AxisX.PixelPositionToValue(e.X)
                Dim yy As Double = ht.ChartArea.AxisY.PixelPositionToValue(e.Y)
                If xx >= Chart1.ChartAreas(0).AxisX.Minimum And xx <= Chart1.ChartAreas(0).AxisX.Maximum And
                    yy >= Chart1.ChartAreas(0).AxisY.Minimum And yy <= Chart1.ChartAreas(0).AxisY.Maximum Then
    
                    Me.Text = xx.ToString & "   " & yy.ToString
                End If
            End If
        End Sub
    End Class

    Hi tommytwotrain,

    Not really, since it seems that you need to click at the point to get the value. What I'm looking for is more like this

    http://www.elmercurio.com/inversiones/herramientas/monedas.aspx

    In that website you can find the chart where I took the image. If you click in "3 meses" or "6 meses" in the bar that is just slightly below the chart (right under the timeline) you will see what I'm aiming for.

    Thank you!


    • Edited by ppsev Thursday, April 20, 2017 5:46 AM website hyperlink added
    Thursday, April 20, 2017 5:18 AM
  • Hi tommytwotrain,

    You can display the X and Y values while doing any Mouse Events like MouseUp, MouseDown, MouseHover, MouseLeave on the chart by using the methods GetValueByPoint which returns the X and Y values of the ChartSeries calculated from the mousepoint and GetPointByValue which returns the X and Y values of the mousepoint calculated from the ChartPoint. Using tooltip we can display the above data

    Code:

    Private Sub chartControl_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ChartControl1.MouseMove
    'This gives the corresponding X and Y coordinates of the mouse point.
    Dim mousePoint As Point = New Point(e.X, e.Y)
    'The GetValueByPoint method returns the X and Y values of the ChartSeries calculated from the mousepoint.
    Dim chpt As ChartPoint = ChartControl1.ChartArea.GetValueByPoint(New Point(e.X, e.Y))
    'The GetPointByValue method returns the X and Y values of the mousepoint calculated from the ChartPoint.
    Dim pt As Point = ChartControl1.ChartArea.GetPointByValue(chpt)
    Dim [text] As String = "Mouse point: " + mousePoint.ToString() + vbLf + "Result of method GetValueByPoint: {" + chpt.X.ToString() + "," + chpt.YValues(0).ToString() + "}" + vbLf + "Result of method GetPointByValue: " + pt.ToString()
    'As mouse moves over the chartcontrol this displays the values as ToolTip.
    ToolTip1.SetToolTip(Me.ChartControl1, text)
    End Sub

    Hope it is helpful to you.

    Best Regards,

    Cherry Bu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, April 20, 2017 6:32 AM
    Moderator
  • I found a guy posting the same question in 2015 and the answers he was given were pretty much the same.

    https://social.msdn.microsoft.com/Forums/en-US/4b2319f2-428a-40d8-977c-a6829f026d94/points-coordinates-of-chart-during-move-the-mouse?forum=MSWinWebChart

     
    Thursday, April 20, 2017 11:29 AM
  • I found a guy posting the same question in 2015 and the answers he was given were pretty much the same.

    https://social.msdn.microsoft.com/Forums/en-US/4b2319f2-428a-40d8-977c-a6829f026d94/points-coordinates-of-chart-during-move-the-mouse?forum=MSWinWebChart

     

    Well I think there are several ways to do what you want, set a range of dates. Here I just changed the axis max mins. You can also use the built in zoom. You will have to play with it for exactly what you want.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form5
        Private Sub Form5_Load(sender As Object, e As EventArgs) Handles Me.Load
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Date"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
    
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Val 1")
            Chart1.Series(0).IsVisibleInLegend = False
    
            Dim random As New Random()
            Dim [date] As DateTime = #1/1/2016 12:00 PM#
            Dim pointIndex As Integer
            For pointIndex = 0 To 365
                [date] = [date].AddDays(1)
                Chart1.Series(0).Points.AddXY([date], random.Next(5, 95))
            Next
    
            'Chart1.ChartAreas(0).AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Months
    
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'year
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 1, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 12, 31).ToOADate()
            Chart1.Invalidate()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            'month
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 3, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 4, 1).ToOADate()
            Chart1.Invalidate()
        End Sub
    
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            'week
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 3, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 3, 7).ToOADate()
            Chart1.Invalidate()
    
        End Sub
    End Class

    Thursday, April 20, 2017 12:42 PM
  • I found a guy posting the same question in 2015 and the answers he was given were pretty much the same.

    https://social.msdn.microsoft.com/Forums/en-US/4b2319f2-428a-40d8-977c-a6829f026d94/points-coordinates-of-chart-during-move-the-mouse?forum=MSWinWebChart

     

    Well I think there are several ways to do what you want, set a range of dates. Here I just changed the axis max mins. You can also use the built in zoom. You will have to play with it for exactly what you want.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form5
        Private Sub Form5_Load(sender As Object, e As EventArgs) Handles Me.Load
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Date"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
    
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Val 1")
            Chart1.Series(0).IsVisibleInLegend = False
    
            Dim random As New Random()
            Dim [date] As DateTime = #1/1/2016 12:00 PM#
            Dim pointIndex As Integer
            For pointIndex = 0 To 365
                [date] = [date].AddDays(1)
                Chart1.Series(0).Points.AddXY([date], random.Next(5, 95))
            Next
    
            'Chart1.ChartAreas(0).AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Months
    
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'year
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 1, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 12, 31).ToOADate()
            Chart1.Invalidate()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            'month
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 3, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 4, 1).ToOADate()
            Chart1.Invalidate()
        End Sub
    
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            'week
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 3, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 3, 7).ToOADate()
            Chart1.Invalidate()
    
        End Sub
    End Class

    Thank you tommytwotrain, but I don't want to change the axis range or anything related with that. What I want is to put the cursor over the graph and to show a dot on the line that follows the cursor along the line. Ideally, it should also display the values of (x,y) without the need of clicking anywhere (like a permanent annotation that follows the mouse displaying the values of x and y). You can see what I mean here:

    http://www.elmercurio.com/inversiones/herramientas/monedas.aspx

    Thursday, April 20, 2017 1:21 PM
  • I found a guy posting the same question in 2015 and the answers he was given were pretty much the same.

    https://social.msdn.microsoft.com/Forums/en-US/4b2319f2-428a-40d8-977c-a6829f026d94/points-coordinates-of-chart-during-move-the-mouse?forum=MSWinWebChart

     

    Well I think there are several ways to do what you want, set a range of dates. Here I just changed the axis max mins. You can also use the built in zoom. You will have to play with it for exactly what you want.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form5
        Private Sub Form5_Load(sender As Object, e As EventArgs) Handles Me.Load
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Date"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
    
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Val 1")
            Chart1.Series(0).IsVisibleInLegend = False
    
            Dim random As New Random()
            Dim [date] As DateTime = #1/1/2016 12:00 PM#
            Dim pointIndex As Integer
            For pointIndex = 0 To 365
                [date] = [date].AddDays(1)
                Chart1.Series(0).Points.AddXY([date], random.Next(5, 95))
            Next
    
            'Chart1.ChartAreas(0).AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Months
    
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'year
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 1, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 12, 31).ToOADate()
            Chart1.Invalidate()
        End Sub
    
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            'month
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 3, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 4, 1).ToOADate()
            Chart1.Invalidate()
        End Sub
    
        Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            'week
            Chart1.ChartAreas(0).AxisX.Minimum = New DateTime(2016, 3, 1).ToOADate()
            Chart1.ChartAreas(0).AxisX.Maximum = New DateTime(2016, 3, 7).ToOADate()
            Chart1.Invalidate()
    
        End Sub
    End Class

    Thank you tommytwotrain, but I don't want to change the axis range or anything related with that. What I want is to put the cursor over the graph and to show a dot on the line that follows the cursor along the line. Ideally, it should also display the values of (x,y) without the need of clicking anywhere (like a permanent annotation that follows the mouse displaying the values of x and y). You can see what I mean here:

    http://www.elmercurio.com/inversiones/herramientas/monedas.aspx

    That's not what your link example shows.

    How can I write your code for you if you cant describe what you want?

    You start it and if you have questions show us the code you have done.

    Thursday, April 20, 2017 1:26 PM

  • Thank you tommytwotrain, but I don't want to change the axis range or anything related with that. What I want is to put the cursor over the graph and to show a dot on the line that follows the cursor along the line. Ideally, it should also display the values of (x,y) without the need of clicking anywhere (like a permanent annotation that follows the mouse displaying the values of x and y). You can see what I mean here:

    http://www.elmercurio.com/inversiones/herramientas/monedas.aspx

    That's not what your link example shows.

    How can I write your code for you if you cant describe what you want?

    You start it and if you have questions show us the code you have done.

    PS I guess what you want is what I showed here more or less:

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/d38f5857-0763-4ff2-a83a-b67f28f64a52/add-horizontal-line-to-line-chart?forum=vbgeneral

    Thursday, April 20, 2017 1:46 PM

  •  That's not what your link example shows.

    How can I write your code for you if you cant describe what you want?

    You start it and if you have questions show us the code you have done.

    I'm sorry tommytwotrain, maybe I have not been clear enough with what I'm asking. English is not my mother language, so if thats the case I apologize. 

    The image below shows in a better way (I hope) what I'm looking for. You can see that the mouse pointer is in the chart area and there is a blue point (which I circled in red) that is in the X position of the mouse pointer and in the Y position of the Y-axis of the graph. Notice that it does not matter if it is above or under the line, the blue dot is in the line.

    Now, the values of X and Y are shown above (in the inside the red rectangle). It would be nice to have those values in near the blue dot, like an annotation or something like that.

    I really hope that now my request is clear and you can help me.

    Sorry for any inconvenience.

    Thursday, April 20, 2017 2:02 PM
  • pp,

    I think between the examples I have shown you can do what you describe. One example gets a data point from the line and the other uses the mouse pointer coordinates.

    If you want to make a chart annotation with the point your return that is something else and just a chart annotation.

    So you can use the mouse cords shown here:

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/d38f5857-0763-4ff2-a83a-b67f28f64a52/add-horizontal-line-to-line-chart?forum=vbgeneral

    Or the chart data point shown in my first example.

    Then once you have that point you can add annotation and how you do that depends if its in mouse cords or chart cords and you just need to convert as reqd. There are lots of annotation methods depending on exactly what you want. Or you can draw it on the chart or put it in a label.


    Thursday, April 20, 2017 2:53 PM
  • pp,

    This example shows how to annotate a chart data point. It defines the points in kmz then add annotations you see for the points with the black color arrows.

    So I don't know if you can sort it out with the three examples. But you have to make a start to define the basics defined exactly and then we can help more with any specific questions.

    Get the point you want to annotate working using whatever coordinate window you want, then add the annotations. You may need to redraw the chart each time you add annotations depending on exactly what you end up doing.

    Then there are several annotation styles if you don't like arrow and box.

    You should get this doc and look it over:

    'chart annotation example 4
    Option Strict On
    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class AnnotationsLoadStress
        Private num As Integer = 18
        Private MtotF(num) As Double
        Private PF(num) As Double
        Private ph1(num) As Double
        Private ph2(num) As Double
    
        Private Sub Form5_Load(sender As Object, e As EventArgs) Handles Me.Load
            Text = "{c} 2016 Sandia Software"
            InitializeChart()
            InputData()
            Calculate()
        End Sub
    
        Private Sub Calculate()
            Dim Angle, Stress, MaxStress, Load, LoadFactor As Double
            Dim LoadIndex As Integer
    
    
            For series = 2 To 4 Step 2
                Select Case series
                    Case 2 : Angle = 45 : LoadIndex = 1
                    Case 4 : Angle = 30 : LoadIndex = 3
                End Select
                LoadFactor = 5 * (Chart1.Series(LoadIndex).Points(num).YValues(0) _
                        - Chart1.Series(LoadIndex).Points(0).YValues(0)) / num
    
                For Kmz = 0 To num
                    'calc the stress for this load and add to stress series
                    Load = Chart1.Series(LoadIndex).Points(Kmz).YValues(0)
                    Stress = 6 * Load * Math.Cos(Angle / 57.3)
    
                    Chart1.Series(series).Points.AddXY((-num * 10 / 2) + (Kmz * 10), Stress)
                    Chart1.Series(series).Points(Kmz).Label = Kmz.ToString
    
                    'calc the max at the angle
                    MaxStress = Math.Sqrt((MtotF(Kmz) ^ 2) + (PF(Kmz) ^ 2))
    
                    'annotate stress inside max stress circle
                    If Math.Abs(Stress) < MaxStress Then
                        Dim PC As New CalloutAnnotation
                        With PC
                            .CalloutStyle = CalloutStyle.SimpleLine
                            .ForeColor = Color.Maroon
                            .Font = New Font("Tahoma", 10)
                            .Text = "Load " & (Kmz).ToString & ": " & Load.ToString & " kips" _
                                & vbLf & Chart1.Series(series).Points(Kmz).YValues(0).ToString("f1") & " ksi  " & Angle & " deg"
    
                            'this tells chart what axis to use it can be any point
                            .AnchorDataPoint = Chart1.Series(series).Points(Kmz)
    
                            'this tells chart where to locate the anno
                            .X = Chart1.Series(series).Points(Kmz).XValue
                            .Y = Chart1.Series(series).Points(Kmz).YValues(0)
    
                            Chart1.Annotations.Add(PC)
                        End With
                    End If
                Next Kmz
            Next
        End Sub
    
        Private Sub InputData()
            'allowable stress circle
            For i As Integer = 0 To num
                MtotF(i) = 32 * Math.Cos((i * 360 / num) / 57.3)
                PF(i) = 22 * Math.Sin((i * 360 / num) / 57.3)
                Chart1.Series(0).Points.AddXY(MtotF(i), PF(i))
            Next
    
            'loads
            For i As Integer = 0 To num
                ph1(i) = -num + (2 * i)
                Chart1.Series(1).Points.AddXY(-(10 * num / 2) + (10 * i), ph1(i))
    
                ph2(i) = -(3 * num / 2) + (3 * i)
                Chart1.Series(3).Points.AddXY(-(10 * num / 2) + (10 * i), ph2(i))
            Next
        End Sub
    
        Private Sub InitializeChart()
            Chart1.Annotations.Clear()
            Chart1.Series.Clear()
            Chart1.Series.Add("Allowable Stress")
            Chart1.Series.Add("L1")
            Chart1.Series.Add("L1 Stress 45 deg")
            Chart1.Series.Add("L2")
            Chart1.Series.Add("L2 Stress 30 deg")
    
            Dim smax = 40
    
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Stress X ksi"
                .AxisX.MajorGrid.LineColor = Color.LightGray
                .AxisX.LabelStyle.Font = New Font("Arial", 8)
                .AxisX.Maximum = smax
                .AxisX.Minimum = -smax
                .AxisX.Interval = 10
    
                '.AxisX2.Enabled = AxisEnabled.True
                '.AxisX2.Title = "Stress X ksi"
                '.AxisX2.MajorGrid.LineColor = Color.LightGray
                '.AxisX2.LabelStyle.Font = New Font("Arial", 8)
                '.AxisX2.Maximum = smax '/ 10
                '.AxisX2.Minimum = -smax '/ 10
                '.AxisX2.Interval = 10
    
    
                .AxisY.Title = "Load"
                .AxisY.MajorGrid.LineColor = Color.LightGray
                .AxisX.LabelStyle.Font = New Font("Arial", 8)
                .AxisY.Maximum = smax
                .AxisY.Minimum = -smax
                .AxisY.Interval = 10
                .AxisY.LabelStyle.IsEndLabelVisible = False
    
                .AxisX.ScrollBar.Enabled = True
                .CursorX.IsUserEnabled = True
                .CursorX.IsUserSelectionEnabled = True
                .AxisX.ScaleView.Zoomable = True
    
            End With
    
            Chart1.Legends(0).Position.Auto = False
            Chart1.Legends(0).Position = New ElementPosition(5, -4, 100, 20)
            Chart1.Legends(0).BackColor = Color.Transparent
    
            'allowable stress ellipse
            Chart1.Series(0).ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline
            Chart1.Series(0).Color = Color.Red
            Chart1.Series(0).IsVisibleInLegend = True
    
            'load 1
            Chart1.Series(1).ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column
            Chart1.Series(1).IsVisibleInLegend = True
            Chart1.Series(1).Color = Color.LightGreen
            'Chart1.Series(1).MarkerBorderWidth = 1
    
            ''actual stress for load 1 and angle 45
            Chart1.Series(2).IsVisibleInLegend = True
            Chart1.Series(2).ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line
            Chart1.Series(2).Color = Color.Green
            Chart1.Series(2).MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
            Chart1.Series(2).MarkerSize = 5
    
            'load 2
            Chart1.Series(3).ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column
            Chart1.Series(3).IsVisibleInLegend = True
            Chart1.Series(3).Color = Color.LightBlue
            'Chart1.Series(1).MarkerBorderWidth = 1
    
            'actual stress for load 2 and angle 30
            Chart1.Series(4).IsVisibleInLegend = True
            Chart1.Series(4).ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line
            Chart1.Series(4).Color = Color.Blue
            Chart1.Series(4).MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
            Chart1.Series(4).MarkerSize = 5
        End Sub
    
    End Class

    Thursday, April 20, 2017 3:23 PM
  • pp,

    This example shows how to annotate a chart data point. It defines the points in kmz then add annotations you see for the points with the black color arrows.

    So I don't know if you can sort it out with the three examples. But you have to make a start to define the basics defined exactly and then we can help more with any specific questions.

    Get the point you want to annotate working using whatever coordinate window you want, then add the annotations. You may need to redraw the chart each time you add annotations depending on exactly what you end up doing.

    Then there are several annotation styles if you don't like arrow and box.

    You should get this doc and look it over:

    Thank you tom. I used the doc you suggested me and got some ideas. Im trying now two things, but I haven't had any success yet.

    I can put an annotation in the ChartArea2 (which is intended) but two things happens:

    1) The annotation appears either I click the ChartArea1 or ChartArea2.

    2) It creates two annotations instead of one.

    The code I'm using is as follows.

    To create the chart with the chart areas and the series:

    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
            Dim cargo As String = ComboBox1.Text
            Dim fi As Date = DateTimePicker1.Text
            Dim ff As Date = DateTimePicker2.Text
            Dim tabla As New DataTable
            Dim fechas As New DataTable
            Dim k As Integer
            Dim green As Integer
            Dim posX, posY, width, height As Single
            Dim numberOfAreas As Integer = 2
    
    
            green = RGB(118, 183, 3)
    
            cn.ConnectionString = ""
            Try
                tabla.Clear()
                fechas.Clear()
    
                Dim sql = ("select p.nombre, s.servicio_nombre, dp.etapa, dp.carga, fecha_inicial, fecha_final, extract (epoch from fecha_final - fecha_inicial)/86400 as duracion 
                            from desarrolloproyecto dp natural join cargo c natural join proyecto p natural join servicio s 
                            where nombre_cargo = '" & cargo & "' AND fecha_inicial BETWEEN '" & fi & "' AND '" & ff & "'
                            OR
                            nombre_cargo = '" & cargo & "' AND fecha_final BETWEEN '" & fi & "' AND '" & ff & "'
                            order by p.nombre desc")
                Dim sqlf = ("select t1.fechas, t1.carga from 
                            (select (generate_series(fecha_inicial, fecha_final, '1 day'::interval))::date AS fechas, sum(dp.carga) as carga
                            FROM desarrolloproyecto dp NATURAL JOIN cargo c NATURAL JOIN proyecto p NATURAL JOIN servicio s 
                            where  nombre_cargo = '" & cargo & "'
                            group by fechas
                            order by fechas)t1
                            where t1.fechas BETWEEN '" & fi & "' AND '" & ff & "'
                            order by t1.fechas")
    
                Dim da As New Npgsql.NpgsqlDataAdapter(sql, cn)
                Dim daf As New Npgsql.NpgsqlDataAdapter(sqlf, cn)
    
                cn.Open()
                da.Fill(tabla)
                daf.Fill(fechas)
    
                With Chart1
                    .Series.Clear()
                    .Series.Add("fechas")
                    .Series.Add(cargo)
                    .Series.Add("fech")
                    .Series(cargo).ChartArea = "ChartArea1"
                    .Series("fechas").ChartArea = "ChartArea1"
                    .Series("fech").ChartArea = "ChartArea2"
    
    
    
    
                    .Legends("Legend1").Alignment = StringAlignment.Center
                    .Legends("Legend1").Docking = Docking.Bottom
                    .Series("fechas").IsVisibleInLegend = False
                    .Series("fech").IsVisibleInLegend = False
                    .Series("fechas").Color = Color.Transparent
                    .Series(cargo).Color = Color.FromArgb(118, 183, 3)
                    .Series(cargo).CustomProperties = "DrawingStyle = Cylinder"
                    .Series("fech").Color = Color.FromArgb(118, 183, 3)
    
                    .Series("fech").ChartType = SeriesChartType.Line
                    .Series("fechas").ChartType = SeriesChartType.StackedBar
                    .Series(cargo).ChartType = SeriesChartType.StackedBar
    
                    .ChartAreas("ChartArea1").Position = New ElementPosition(0, 0, 95, 70)
                    .ChartAreas("ChartArea1").CursorX.IsUserEnabled = True
                    .ChartAreas("ChartArea1").CursorX.IsUserSelectionEnabled = True
                    .ChartAreas("ChartArea1").AxisX.ScaleView.Zoomable = True
                    .ChartAreas("ChartArea1").AxisX.ScrollBar.IsPositionedInside = False
                    .ChartAreas("ChartArea1").CursorY.IsUserEnabled = True
                    .ChartAreas("ChartArea1").CursorY.IsUserSelectionEnabled = True
                    .ChartAreas("ChartArea1").AxisY.ScaleView.Zoomable = True
                    .ChartAreas("ChartArea1").AxisY.ScrollBar.IsPositionedInside = False
                    .ChartAreas("ChartArea1").AxisY.Minimum = fi.ToOADate 'valores minimos y maximos de ejes x e y
                    .ChartAreas("ChartArea1").AxisY.Maximum = ff.ToOADate
                    .ChartAreas("ChartArea1").AxisY.IntervalType = DateTimeIntervalType.Auto
                    .ChartAreas("ChartArea1").AxisX.IntervalOffset = 0
                    .ChartAreas("ChartArea1").AxisX.Interval = 1
    
                    
                    .ChartAreas("ChartArea2").Position = New ElementPosition(0, 70, 95, 25)
                    .ChartAreas("ChartArea2").CursorX.IsUserEnabled = True
                    .ChartAreas("ChartArea2").CursorY.IsUserEnabled = True
                    .ChartAreas("ChartArea2").AxisX.Minimum = fi.ToOADate
                    .ChartAreas("ChartArea2").AxisX.Maximum = ff.ToOADate
                    .ChartAreas("ChartArea2").AxisX.IntervalType = DateTimeIntervalType.Auto
    
    
    
                    .Series("fech").SmartLabelStyle.Enabled = True
    
    
                    For k = 0 To tabla.Rows.Count - 1
                        .Series("fechas").Points.AddXY(tabla.Rows(k).Item(0) & "-" & tabla.Rows(k).Item(1) & "-E" & tabla.Rows(k).Item(2), tabla.Rows(k).Item(4))
                        .Series(cargo).Points.AddY(tabla.Rows(k).Item(6))
                    Next
    
                    For k = 0 To fechas.Rows.Count - 1
                        .Series("fech").Points.AddXY(fechas.Rows(k).Item(0), fechas.Rows(k).Item(1))
                        If k = 0 Then
                            posY = fechas.Rows(0).Item(1)
                            posX = fechas.Rows(0).Item(1)
                        Else
                            posY = Min(posY, fechas.Rows(k).Item(1))
                            posX = Max(posX, fechas.Rows(k).Item(1))
                        End If
    
                    Next
                    .ChartAreas("ChartArea2").AxisY.Minimum = posY - 25
                    .ChartAreas("ChartArea2").AxisY.Maximum = posX + 25
                    
    
    
                End With
                Label1.Focus()
    
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
            cn.Close()
        End Sub


    Now, for the annotation part it goes as follows:

    Private Sub Chart1_CursorPositionChanging(sender As Object, e As CursorEventArgs) Handles Chart1.CursorPositionChanging
    
            
            Dim a As CalloutAnnotation = New CalloutAnnotation()
            a.AnchorDataPoint = Chart1.Series("fech").Points(0)
            a.Text = "Select this Annotation Object\nand move the Anchor point"
            Chart1.Annotations.Add(a)
    
        End Sub

    So I guess I have 3 questions now.

    1) How can I make the annotations appear only when I move the mouser over the ChartArea2? (The idea is not to click the ChartArea2.)

    2) How can I make only to appear one annotation?

    3) How can I make the annotation move when I move the mouse pointer along the X-axis? I would like that the annotation coordenates were x = mouse pointer value and y = y-axis value.

    On the other hand, I took your advice into account and I'm also trying to make only one annotation that the user can move along the line, but somehow the annotation disappears as soon as I move its anchor. Here is an image of that I'm doing and the code I'm using to achieve it.

    Private Sub Chart1_AnnotationPositionChanging(sender As Object, e As AnnotationPositionChangingEventArgs) Handles Chart1.AnnotationPositionChanging
    
    
            ' Get the annotation object from the AnnotationPositionChangingEventArgs
            Dim annotation As Annotation = e.Annotation
    
            If Not Single.IsNaN(e.NewAnchorLocationX) Then
                ' Get the nearest point to the new location
                Dim point As PointF = FindNearestDataPoint(e.NewAnchorLocationX, e.NewAnchorLocationY)
    
                calloutAnnotation.AnchorDataPoint = Chart1.Series("fech").Points((CInt(point.X) - 1))
                e.NewAnchorLocationX = point.X
                e.NewAnchorLocationY = point.Y
            End If
        End Sub 'Chart1_AnnotationPositionChanging
    
    Private Function FindNearestDataPoint(X As Double, Y As Double) As PointF
            ' Get the int portion of the X value
            Dim curIndex As Integer = CInt(Math.Round(X))
    
            ' If curIndex is less than 1 curIndex is set to 1
            curIndex = CInt(Math.Max(curIndex, 1))
    
            ' If curIndex is greater than 5 curIndex is set to 5 (X Value of max point in series)
            curIndex = CInt(Math.Min(curIndex, 5))
    
            ' Return the point value of the nearest point
            Return New PointF(curIndex, CSng(Chart1.Series("fech").Points((curIndex - 1)).YValues(0)))
        End Function 'FindNearestDataPoint

    I'm sorry for doing a such a long post, but I posted all the information I could.

    Once again, thank you very much!

    Thursday, April 20, 2017 9:08 PM
  • pp,

    LOL.

    Well you will just have to work through all that one step at a time. Only you know exactly what you want to do.

    I guess you have to test you are in the bounds of the chart you want and then show only that data. The first example has testing etc.

    Not sure what you mean one at a time but have one place where the anno is added to the chart and set a variable of the anno props even make a class etc and then even a sub show anno() you draw the anno once with the current data.

    If you can break your questions down to simple terms then we can be more help.

    Thursday, April 20, 2017 9:18 PM
  • pp,

    Well you will just have to work through all that one step at a time. Only you know exactly what you want to do.

    tom,

    Thats right, but I have found the best way to illustrate it.

    I have tried with MouseMove, MouseHover, AnnotationPositionChanging, among others, but I have no success. Can you help me please?

    Friday, April 21, 2017 2:40 AM
  • pp,

    Well you will just have to work through all that one step at a time. Only you know exactly what you want to do.

    tom,

    Thats right, but I have found the best way to illustrate it.

    I have tried with MouseMove, MouseHover, AnnotationPositionChanging, among others, but I have no success. Can you help me please?

    Ok then. Just a matter of adding a chart annotation at the proper moment.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form7
        Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim MyData(12) As Single
            For i = 1 To 12
                MyData(i) = CSng(5 * Math.Sin(i / 2))
            Next
    
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Time"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisX.Minimum = 0
                .AxisX.Maximum = 14
                .AxisX.Interval = 2
                .AxisX.LabelStyle.IsEndLabelVisible = False
    
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
                .AxisY.Minimum = -6
                .AxisY.Maximum = 6
                .AxisY.Interval = 2
    
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Monthy Data")
    
            With Chart1.Series(0)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
                .Color = Color.Blue
                .MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
                .MarkerSize = 8
                .IsVisibleInLegend = False
    
                For m = 1 To 12
                    .Points.AddXY(m, MyData(m))
                Next
            End With
    
            Dim PC As New CalloutAnnotation
            With PC
                Chart1.Annotations.Add(PC)
            End With
        End Sub
    
        Private Sub Chart1_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart1.MouseMove
    
            Dim result As HitTestResult = Chart1.HitTest(e.X, e.Y)
    
            If result.ChartElementType = ChartElementType.DataPoint Then
                Chart1.Series(0).Points(result.PointIndex).XValue.ToString()
    
                Dim thisPt As New PointF(CSng(Chart1.Series(0).Points(result.PointIndex).XValue),
                                        CSng(Chart1.Series(0).Points(result.PointIndex).YValues(0)))
                Dim ta As New CalloutAnnotation
                With ta
                    .AnchorDataPoint = Chart1.Series(0).Points(result.PointIndex)
                    .X = thisPt.X + 1
                    .Y = thisPt.Y + 1
                    .Text = thisPt.ToString
                    .CalloutStyle = CalloutStyle.SimpleLine
                    .ForeColor = Color.Red
                    .Font = New Font("Tahoma", 12, FontStyle.Bold)
                End With
                Chart1.Annotations(0) = ta
                Chart1.Invalidate()
            End If
        End Sub
    End Class

    • Marked as answer by ppsev Friday, April 21, 2017 1:13 PM
    Friday, April 21, 2017 11:14 AM
  • pp,

    Well you will just have to work through all that one step at a time. Only you know exactly what you want to do.

    tom,

    Thats right, but I have found the best way to illustrate it.

    I have tried with MouseMove, MouseHover, AnnotationPositionChanging, among others, but I have no success. Can you help me please?

    Ok then. Just a matter of adding a chart annotation at the proper moment.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form7
        Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim MyData(12) As Single
            For i = 1 To 12
                MyData(i) = CSng(5 * Math.Sin(i / 2))
            Next
    
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Time"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisX.Minimum = 0
                .AxisX.Maximum = 14
                .AxisX.Interval = 2
                .AxisX.LabelStyle.IsEndLabelVisible = False
    
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
                .AxisY.Minimum = -6
                .AxisY.Maximum = 6
                .AxisY.Interval = 2
    
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Monthy Data")
    
            With Chart1.Series(0)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
                .Color = Color.Blue
                .MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
                .MarkerSize = 8
                .IsVisibleInLegend = False
    
                For m = 1 To 12
                    .Points.AddXY(m, MyData(m))
                Next
            End With
    
            Dim PC As New CalloutAnnotation
            With PC
                Chart1.Annotations.Add(PC)
            End With
        End Sub
    
        Private Sub Chart1_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart1.MouseMove
    
            Dim result As HitTestResult = Chart1.HitTest(e.X, e.Y)
    
            If result.ChartElementType = ChartElementType.DataPoint Then
                Chart1.Series(0).Points(result.PointIndex).XValue.ToString()
    
                Dim thisPt As New PointF(CSng(Chart1.Series(0).Points(result.PointIndex).XValue),
                                        CSng(Chart1.Series(0).Points(result.PointIndex).YValues(0)))
                Dim ta As New CalloutAnnotation
                With ta
                    .AnchorDataPoint = Chart1.Series(0).Points(result.PointIndex)
                    .X = thisPt.X + 1
                    .Y = thisPt.Y + 1
                    .Text = thisPt.ToString
                    .CalloutStyle = CalloutStyle.SimpleLine
                    .ForeColor = Color.Red
                    .Font = New Font("Tahoma", 12, FontStyle.Bold)
                End With
                Chart1.Annotations(0) = ta
                Chart1.Invalidate()
            End If
        End Sub
    End Class

    Thank you! Finally it worked! Thank you tom :)

    By the way, is there a way to remove the "{}" from the annotation? And how can I display a date in the X part of the annotation? Now it shows "{X=43081, Y = 260}" and I would like it to be "12-12-2017, 260".

    Friday, April 21, 2017 1:13 PM

  • Thank you! Finally it worked! Thank you tom :)

    By the way, is there a way to remove the "{}" from the annotation? And how can I display a date in the X part of the annotation? Now it shows "{X=43081, Y = 260}" and I would like it to be "12-12-2017, 260".

    Well you just have to sort through the examples in the samples link I gave.

    Look under chart features - annotation.

    That's what I did.

    Imports System.Windows.Forms.DataVisualization.Charting
    
    Public Class Form7
        Private Sub Form6_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            'setup the chart
            With Chart1.ChartAreas(0)
                .AxisX.Title = "Time"
                .AxisX.MajorGrid.LineColor = Color.LightBlue
                .AxisX.LabelStyle.IsEndLabelVisible = False
                .AxisX.LabelStyle.IntervalType = DateTimeIntervalType.Days
    
                .AxisY.Title = "Value"
                .AxisY.MajorGrid.LineColor = Color.LightGray
                .AxisY.Minimum = 0
                .AxisY.Maximum = 10
                .AxisY.Interval = 2
                .BackColor = Color.AntiqueWhite
                .BackSecondaryColor = Color.White
                .BackGradientStyle = GradientStyle.HorizontalCenter
                .BorderColor = Color.Blue
                .BorderDashStyle = ChartDashStyle.Solid
                .BorderWidth = 1
                .ShadowOffset = 2
            End With
    
            Chart1.Series.Clear()
            Chart1.Series.Add("Monthy Data")
    
            With Chart1.Series(0)
                .ChartType = DataVisualization.Charting.SeriesChartType.Line
                .BorderWidth = 2
                .Color = Color.Blue
                .MarkerStyle = DataVisualization.Charting.MarkerStyle.Circle
                .MarkerSize = 8
                .IsVisibleInLegend = False
                Dim rand As New Random(Now.Millisecond)
                For m = 1 To 12
                    Dim [date] As DateTime = DateTime.Now.Date
                    [date] = [date].AddDays(m)
                    Chart1.Series(0).Points.AddXY([date], rand.Next(0, 10))
                Next
            End With
    
            Dim PC As New CalloutAnnotation
            With PC
                Chart1.Annotations.Add(PC)
            End With
        End Sub
    
        Private Sub Chart1_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart1.MouseMove
    
            Dim result As HitTestResult = Chart1.HitTest(e.X, e.Y)
    
            If result.ChartElementType = ChartElementType.DataPoint Then
                Chart1.Series(0).Points(result.PointIndex).XValue.ToString()
    
                Dim thisPt As New PointF(CSng(Chart1.Series(0).Points(result.PointIndex).XValue),
                                        CSng(Chart1.Series(0).Points(result.PointIndex).YValues(0)))
                Dim ta As New CalloutAnnotation
                With ta
                    .AnchorDataPoint = Chart1.Series(0).Points(result.PointIndex)
                    .X = thisPt.X + 1
                    .Y = thisPt.Y + 1
                    .Text = DateTime.FromOADate(thisPt.X).ToShortDateString &
                        vbLf & "Value: " & thisPt.Y.ToString
                    .ForeColor = Color.Red
                    .Font = New Font("Tahoma", 10, FontStyle.Bold)
                End With
                Chart1.Annotations(0) = ta
                Chart1.Invalidate()
            End If
        End Sub
    End Class



    • Edited by tommytwotrain Friday, April 21, 2017 2:08 PM
    • Marked as answer by ppsev Friday, April 21, 2017 2:18 PM
    Friday, April 21, 2017 2:07 PM
  • Thank you Tom,

    It was this part what I was missing.

    .Text = DateTime.FromOADate(thisPt.X).ToShortDateString &
                        vbLf & "Value: " & thisPt.Y.ToString

    Thank for your patience. This is the first time I use Visual Studio and I'm pretty new to all this programming stuff.

    Friday, April 21, 2017 2:18 PM
  • Thank you Tom,

    It was this part what I was missing.

    .Text = DateTime.FromOADate(thisPt.X).ToShortDateString &
                        vbLf & "Value: " & thisPt.Y.ToString

    Thank for your patience. This is the first time I use Visual Studio and I'm pretty new to all this programming stuff.

    You are welcome.

    Yes I know that's what you were missing.  Also note I changed my example to use dates on the x axis instead of just integer or single.

    One has to be careful about the data types.  And that fromOADate is an old windows OLE thing that the chart control uses but not really part of vb. I had to hunt for it.

    That's the way it goes. Half of learning to program is learning to use the documentation and where to look for answers.

    Friday, April 21, 2017 2:27 PM