[Solved] Chart annotation not showing on Mouse Move in Windows Application

elvisidrizi1
 
on Dec 23, 2020 12:16 AM
959 Views

Hi Everyone,

I have the vb.net chart that I see the last 12 months of expenses.

I tried this code but won't return anything.  Thank you for your patience and help.

This is the code that I use to see my data in the chart :

    Private Sub Chart2_MouseMove(sender As Object, e As MouseEventArgs) Handles Chart2.MouseMove
        Dim pos = e.Location
        If prevPosition.HasValue AndAlso pos = prevPosition.Value Then Return
        tooltip.RemoveAll()
        prevPosition = pos
        Dim results = Chart2.HitTest(pos.X, pos.Y, False, ChartElementType.DataPoint)
        For Each result In results
            If result.ChartElementType = ChartElementType.DataPoint Then
                Dim Month As String = result.Series.Points(result.PointIndex).XValue
                tooltip.BackColor = Color.LightGray
                tooltip.ToolTipTitle = "Data Information"
                tooltip.Show(GetDetail(Month), Chart1, pos.X, pos.Y - 15)
            End If
        Next
    End Sub

    Private Function GetData2() As DataTable
        Dim dtChartData As New DataTable()
        Using conn As New SqlConnection(ConfigurationManager.ConnectionStrings("db").ConnectionString)
            Using cmd As New SqlCommand("Chart_last12months", conn) ' Total working hours in the month -- step3
                cmd.CommandType = CommandType.StoredProcedure

                conn.Open()
                Dim reader As SqlDataReader = cmd.ExecuteReader()
                dtChartData.Load(reader)

            End Using
        End Using

        Return dtChartData

    End Function

    Private Function GetDetail(ByVal Month As String) As String
        Dim data As String = ""
        Dim constr As String = "Data Source=ELVIS\SQLEXPRESS;Initial Catalog=Expenses;Trusted_Connection=yes;"
        Dim query As String = "SELECT Sum(Price) AS Total,
                               DATEPART(MM, Date) AS [year],
                               Sum (CONVERT(INT, CONVERT(VARCHAR(MAX),quantity))) AS Lesh
                               FROM dbo.Expenses
                               WHERE Date BETWEEN DATEADD(MM, -12, GETDATE()) AND GETDATE()
                               GROUP BY DATEPART(MM, Date)"

        Dim dt As DataTable = New DataTable()
        Using con As SqlConnection = New SqlConnection(constr)
            Using command As New SqlCommand(query, con)
                command.CommandType = CommandType.Text

                Using sda As SqlDataAdapter = New SqlDataAdapter(command)
                    sda.Fill(dt)
                End Using
            End Using
        End Using

        For Each row As DataRow In dt.Rows
            Dim department As String = row("Department").ToString().Trim()
            Dim total As String = row("Total").ToString()
            data = data & " - " & " | " & total & " - " & " | " & " - " & " | " & department & Environment.NewLine
        Next
        Return data
    End Function

 

   Private Sub LoadYearData1()
       Chart2.DataSource = GetData2()
       Chart2.Series("Chart2").Points.Clear()
       Chart2.Series("Chart2").XValueMember = "Year"
       Chart2.Series("Chart2").YValueMembers = "Total"
       'Chart1.Series("Chart1").Color = Color.FromArgb(152, 251, 152)
 
       Chart2.Series("Chart2").IsValueShownAsLabel = True
       Chart2.Series("Chart2").BorderWidth = 2
       Chart2.Series("Chart2").ChartType = SeriesChartType.Spline
       ' Chart1.Series("Chart1").Points.DataBindXY(x, y)
       Chart2.Series("Chart2").LabelForeColor = Color.NavajoWhite
       Chart2.Series("Chart2").EmptyPointStyle.Color = Color.Red
       Chart2.Series("Chart2").EmptyPointStyle.AxisLabel = "Empty"
       Chart2.Series("Chart2").EmptyPointStyle.IsValueShownAsLabel = False
       Chart2.Legends(0).Enabled = False
       Dim MyData As Single() = New Single(Chart2.Series.Count - 1) {}
       For i = 0 To Chart2.Series.Count - 1
           MyData(i) = Convert.ToSingle(5 * Math.Sin(i / CDbl(2)))
           Dim withBlock = Chart2.Series(i)
           withBlock.BorderWidth = 2
           withBlock.MarkerStyle = MarkerStyle.Circle
           withBlock.MarkerSize = 8
           Chart2.Annotations.Add(New CalloutAnnotation())
       Next
   End Sub

 

Download FREE API for Word, Excel and PDF in ASP.Net: Download
dharmendr
 
on Dec 24, 2020 06:59 AM

With Chart2.DataSource property Annotation will not work. Since there is no DataPoint assigned for the chart.

You need to set using DataBindXY method.

Refer below sample code. Change the select query.

Code

Public Class Form1
    Dim constr As String = "Data Source=.;Initial Catalog=Expences;UID=sa;PWD=pass@123;"
    Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        LoadYearData1()
    End Sub

    Private Sub LoadYearData1()
        Dim dt As DataTable = GetData2()
        Dim years As List(Of Int32) = (From p In dt.AsEnumerable()
                                       Select p.Field(Of Int32)("Year")).ToList()

        Dim total As List(Of Decimal) = (From p In dt.AsEnumerable()
                                         Select p.Field(Of Decimal)("Total")).ToList()

        If Chart2.Series.Count() = 1 Then
            Chart2.Series.Remove(Chart2.Series(0))
        End If
        Chart2.Series.Clear()

        Chart2.Series.Add(New Series("Chart2"))
        Chart2.Series("Chart2").IsValueShownAsLabel = True
        Chart2.Series("Chart2").BorderWidth = 2
        Chart2.Series("Chart2").ChartType = SeriesChartType.Spline
        Chart2.Series("Chart2").Points.DataBindXY(years, total)
        Chart2.Series("Chart2").LabelForeColor = Color.NavajoWhite
        Chart2.Series("Chart2").EmptyPointStyle.Color = Color.Red
        Chart2.Series("Chart2").EmptyPointStyle.AxisLabel = "Empty"
        Chart2.Series("Chart2").EmptyPointStyle.IsValueShownAsLabel = False

        Chart2.Legends(0).Enabled = True
        Dim MyData As Single() = New Single(Chart2.Series.Count - 1) {}
        For i = 0 To Chartday.Series.Count - 1
            MyData(i) = Convert.ToSingle(5 * Math.Sin(i / CDbl(2)))
            Dim withBlock = Chart2.Series(i)
            withBlock.BorderWidth = 2
            withBlock.MarkerStyle = MarkerStyle.Circle
            withBlock.MarkerSize = 8
            Chart2.Annotations.Add(New CalloutAnnotation())
        Next
    End Sub

    Private Function GetData2() As DataTable
        Dim dtChartData As New DataTable()
        Using conn As New SqlConnection(constr)
            Dim query As String = "SELECT Sum(Price) AS Total,
                                    DATEPART(MM, Date) As [Year],
                                    Sum(Convert(Int, Convert(VARCHAR(MAX), quantity))) As Lesh
                                   From dbo.Expenses
                                   WHERE Date BETWEEN DATEADD(MM, -12, GETDATE()) AND GETDATE()
                                   GROUP BY DATEPART(MM, Date)"
            Using cmd As New SqlCommand(query, conn) ' Total working hours in the month -- step3
                cmd.CommandType = CommandType.Text
                conn.Open()
                Dim reader As SqlDataReader = cmd.ExecuteReader()
                dtChartData.Load(reader)
            End Using
        End Using

        Return dtChartData
    End Function

    Private prevPosition As Point? = Nothing
    Private tooltip As ToolTip = New ToolTip()
    Private Sub Chart1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Chart2.MouseMove
        Dim pos = e.Location
        If prevPosition.HasValue AndAlso pos = prevPosition.Value Then Return
        tooltip.RemoveAll()
        prevPosition = pos
        Dim results = Chart2.HitTest(pos.X, pos.Y, False, ChartElementType.DataPoint)
        For Each result In results
            If result.ChartElementType = ChartElementType.DataPoint Then
                'Dim department As String = result.Series.Name
                Dim Month As String = result.Series.Points(result.PointIndex).XValue
                Dim total As Double = result.Series.Points(result.PointIndex).YValues(0)
                Dim yVal = result.ChartArea.AxisY.PixelPositionToValue(pos.Y)
                tooltip.BackColor = Color.LightGray
                tooltip.ToolTipTitle = "Data Information"
                tooltip.Show(GetDetails(Month), Chartday, pos.X, pos.Y - 15)
            End If
        Next
    End Sub

    Private Sub toolTip_Draw(ByVal sender As Object, ByVal e As DrawToolTipEventArgs)
        Dim f As Font = New Font("Arial", 8.0F)
        Dim b As Brush = New SolidBrush(tooltip.BackColor)
        e.Graphics.FillRectangle(b, e.Bounds)
        e.DrawBackground()
        e.DrawBorder()
        e.Graphics.DrawString(e.ToolTipText, f, SystemBrushes.ActiveCaptionText, e.Bounds)
    End Sub

    Private Function GetDetails(ByVal Month As String) As String
        Dim data As String = ""
        Dim query As String = "SELECT SUM(Price) AS Total,Department FROM [dbo].[Expenses] "
        query += "WHERE DATEPART(Month,Date) = @Month "
        query += "AND DATEPART(Year,Date) = @Year "
        query += "GROUP BY Department"
        Dim dt As DataTable = New DataTable()
        Using con As SqlConnection = New SqlConnection(constr)
            Using command As New SqlCommand(query, con)
                command.CommandType = CommandType.Text
                command.Parameters.AddWithValue("@Month", Month)
                command.Parameters.AddWithValue("@Year", DateTime.Now.Year)
                Using sda As SqlDataAdapter = New SqlDataAdapter(command)
                    sda.Fill(dt)
                End Using
            End Using
        End Using

        For Each row As DataRow In dt.Rows
            Dim department As String = row("Department")
            Dim total As String = row("Total").ToString()
            data += data & " - " & " | " & total & " - " & " | " & " - " & " | " & department & Environment.NewLine
        Next
        Return data
    End Function
End Class