Try this modification:
TheText &= SName & ": " & vbLf &
"Value: " & thisPt.Y.ToString("F0") & vbLf &
"Date: " & Date.FromOADate(thisPt.X)
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
Below is sample code, with sample values. Uses a Form with a Chart object ("Chart1") X-Axis is the date and there are 2 Y values. If the mouse passes over the line(s) I want to display which series, the value and the date, several show as "Unknown" because the value passed to the Function is slightly off the actual value. I'd rather NOT use the function I created anyway, I would rather get it direct from the HitTest results if that is possible.
Option Strict On
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Private TheDate As New List(Of Date)
Private Series1 As New List(Of Integer)
Private Series2 As New List(Of Integer)
Private Function DateFromOtherData(SName As String, Data As Integer) As String
Dim DataIndex As Integer = -1
If SName = "Series1" Then
DataIndex = Series1.IndexOf(Data)
Else
DataIndex = Series2.IndexOf(Data)
End If
If DataIndex > -1 Then
Return TheDate(DataIndex).ToShortDateString
Else
Return "Unknown"
End If
End Function
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Add some saple data
Dim Temp As New List(Of String)
Temp.Add("2020-03-07")
Series1.Add(428)
Series2.Add(19)
Temp.Add("2020-03-31")
Series1.Add(188461)
Series2.Add(4304)
Temp.Add("2020-04-24")
Series1.Add(909853)
Series2.Add(51360)
Temp.Add("2020-05-18")
Series1.Add(1515593)
Series2.Add(90414)
Temp.Add("2020-06-11")
Series1.Add(2036500)
Series2.Add(113980)
Temp.Add("2020-07-05")
Series1.Add(2910782)
Series2.Add(129941)
Temp.Add("2020-07-29")
Series1.Add(4433633)
Series2.Add(151172)
Temp.Add("2020-09-15")
Series1.Add(6614318)
Series2.Add(195689)
Temp.Add("2020-10-09")
Series1.Add(7719211)
Series2.Add(213595)
Temp.Add("2020-11-02")
Series1.Add(9377208)
Series2.Add(231480)
Temp.Add("2020-11-26")
Series1.Add(12954294)
Series2.Add(263339)
Temp.Add("2020-12-20")
Series1.Add(17880478)
Series2.Add(317810)
Temp.Add("2021-01-13")
Series1.Add(23135194)
Series2.Add(384824)
Temp.Add("2021-02-06")
Series1.Add(26958807)
Series2.Add(462052)
Temp.Add("2021-03-02")
Series1.Add(28738501)
Series2.Add(515710)
Temp.Add("2021-03-26")
Series1.Add(30172762)
Series2.Add(547621)
Temp.Add("2021-04-19")
Series1.Add(31754642)
Series2.Add(567314)
Temp.Add("2021-05-13")
Series1.Add(32868084)
Series2.Add(583991)
Temp.Add("2021-06-06")
Series1.Add(33329413)
Series2.Add(596803)
Temp.Add("2021-06-30")
Series1.Add(33639764)
Series2.Add(604446)
Temp.Add("2021-07-24")
Series1.Add(34469200)
Series2.Add(610400)
Temp.Add("2021-08-17")
Series1.Add(37133674)
Series2.Add(623237)
Temp.Add("2021-09-10")
Series1.Add(40914456)
Series2.Add(658865)
Temp.Add("2021-10-04")
Series1.Add(43826566)
Series2.Add(703362)
Temp.Add("2021-10-28")
Series1.Add(45797078)
Series2.Add(743050)
Temp.Add("2021-11-21")
Series1.Add(47692614)
Series2.Add(771871)
Temp.Add("2021-12-15")
Series1.Add(50346987)
Series2.Add(801037)
'For i = 0 To Series1.Count - 1 'This lowers each value in Series1
'Series1(i) = CInt(Series1(i) / 50) 'and makes getting the date work
'Next 'Not acceptable, just an example
For Each S As String In Temp
TheDate.Add(CDate(S))
Next
End Sub
Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
Chart1.Series.Clear()
Chart1.Series.Add("Series1")
Chart1.Series.Add("Series2")
Chart1.Series(0).YAxisType = AxisType.Primary
Chart1.Series(1).YAxisType = AxisType.Secondary
Chart1.ChartAreas(0).AxisY.MajorGrid.LineWidth = 0
Chart1.ChartAreas(0).AxisY2.MajorGrid.LineWidth = 0
Chart1.ChartAreas(0).AxisX.MajorGrid.LineWidth = 0
Chart1.ChartAreas(0).AxisX2.MajorGrid.LineWidth = 0
Chart1.ChartAreas(0).AxisX.Interval = 21
Chart1.ChartAreas(0).AxisX2.Interval = 21
Chart1.ChartAreas(0).AxisY.LabelStyle.ForeColor = Color.Blue
Chart1.ChartAreas(0).AxisY.LabelStyle.Font = New Font("Arial", 12, FontStyle.Bold)
Chart1.ChartAreas(0).AxisY2.LabelStyle.ForeColor = Color.Red
Chart1.ChartAreas(0).AxisY2.LabelStyle.Font = New Font("Arial", 12, FontStyle.Bold)
Chart1.Series(0).Name = "Series1"
Chart1.Series(0).Points.DataBindXY(TheDate.ToArray, Series1.ToArray)
Chart1.Titles.Clear()
Chart1.Series(1).Name = "Series2"
Chart1.Series(1).Points.DataBindXY(TheDate.ToArray, Series2.ToArray)
Chart1.Series(0).ChartType = SeriesChartType.Line
Chart1.Series(0).BorderWidth = 5
Chart1.Series(1).ChartType = SeriesChartType.Line
Chart1.Series(1).BorderWidth = 2
Chart1.Series(0).Color = Color.Blue
Chart1.Series(1).Color = Color.Red
Chart1.Visible = True
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)
Dim Ndx As Integer
Dim thisPt As New PointF
Dim ta As New CalloutAnnotation
Dim TheText As String = ""
Chart1.Annotations.Clear()
If result.ChartElementType = ChartElementType.DataPoint Then
Dim SName As String = result.Series.Name
If SName = "Series1" Then
Ndx = 0
Else
Ndx = 1
End If
thisPt = New PointF(CSng(Chart1.Series(Ndx).Points(result.PointIndex).XValue),
CSng(Chart1.Series(Ndx).Points(result.PointIndex).YValues(0)))
ta.CalloutStyle = CalloutStyle.Rectangle
ta.AnchorDataPoint = Chart1.Series(Ndx).Points(result.PointIndex)
ta.Alignment = ContentAlignment.MiddleLeft
ta.TextStyle = TextStyle.Default
ta.Font = New Font("Arial", 10, FontStyle.Bold)
TheText &= SName & ": " & vbLf &
"Value: " & thisPt.Y.ToString("F0") & vbLf &
"Date: " & DateFromOtherData(SName, CInt(thisPt.Y))
ta.Text = TheText
Chart1.Annotations.Add(ta)
Chart1.Invalidate()
Me.Text = "ThisPt.X = " & thisPt.X.ToString
End If
End Sub
End Class
Try this modification:
TheText &= SName & ": " & vbLf &
"Value: " & thisPt.Y.ToString("F0") & vbLf &
"Date: " & Date.FromOADate(thisPt.X)
Hi @Devon Nullman ,
The problem occurs in lines 165 and 166 of your code.
When DataPoint.XValue is converted from double type to single type, the precision is lost and the data is distorted.
You can choose to use List(Of Double) to avoid this problem.
Here is the code I modified based on your code.
Private Series1 As New List(Of Double)
Private Series2 As New List(Of Double)
Private Function DateFromOtherData(SName As String, Data As Double) As String
Dim DataIndex As Integer = -1
If SName = "Series1" Then
DataIndex = Series1.IndexOf(Data)
Else
DataIndex = Series2.IndexOf(Data)
End If
If DataIndex > -1 Then
Return TheDate(DataIndex).ToShortDateString
Else
Return "Unknown"
End If
End Function
Private Sub Chart1_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart1.MouseMove
Dim result As HitTestResult = Chart1.HitTest(e.X, e.Y)
Dim Ndx As Integer
Dim ta As New CalloutAnnotation
Dim TheText As String = ""
Chart1.Annotations.Clear()
If result.ChartElementType = ChartElementType.DataPoint Then
Dim SName As String = result.Series.Name
If SName = "Series1" Then
Ndx = 0
Else
Ndx = 1
End If
ta.CalloutStyle = CalloutStyle.Rectangle
ta.AnchorDataPoint = Chart1.Series(Ndx).Points(result.PointIndex)
ta.Alignment = ContentAlignment.MiddleLeft
ta.TextStyle = TextStyle.Default
ta.Font = New Font("Arial", 10, FontStyle.Bold)
TheText &= SName & ": " & vbLf &
"Value: " & Chart1.Series(Ndx).Points(result.PointIndex).YValues(0) & vbLf &
"Date: " & DateFromOtherData(SName, Chart1.Series(Ndx).Points(result.PointIndex).YValues(0))
ta.Text = TheText
Chart1.Annotations.Add(ta)
Chart1.Invalidate()
Me.Text = "ThisPt.X = " & Chart1.Series(Ndx).Points(result.PointIndex).XValue
End If
End Sub
Hope the code above could be helpful.
Best Regards.
Jiachen Li
----------
If the answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.