[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 343
  • Last Modified:

Drawing String Characters as Points on a line graph in Visual Basic 2008 Express.

I have a line graph running, with the help from some EE experts.

Now, I would like to use String Characters such as 'X' or 'O' in my graph as points instead of rectangles.

Also, some EE experts say I should be using a class instead of what has been implemented in the code below.

500 points goes to the EE expert with the most complete answer. I will split points on improvements to the code; please include commentary on the changes.

Thanks in advance!

1 form
1 picturebox
1 label named lblL

=NerdsOfTech
Imports System.Drawing.Drawing2D
Public Class Form1
    Private GridDist As Integer = 20
    Private LPoints As New SortedList(Of Integer, Integer)
 
    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        Dim x As Integer = Math.Round(e.X / GridDist) * GridDist
        Dim y As Integer = Math.Round(e.Y / GridDist) * GridDist
        If (x / GridDist >= 1 And x / GridDist <= 11) And (y / GridDist >= 1 And y / GridDist <= 19) Then
            If (e.Button = Windows.Forms.MouseButtons.Right) Then
                If (LPoints.ContainsKey(x)) Then
                    If LPoints(x) = y Then
                        LPoints.Remove(x)
                    End If
                End If
            Else
                LPoints(x) = Math.Round(e.Y / GridDist) * GridDist
            End If
            PictureBox1.Refresh()
        End If
    End Sub
 
    Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave
        lblL.Text = ""
    End Sub
 
    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Dim x As Integer = Math.Round(e.X / GridDist)
        Dim y As Integer = Math.Round(e.Y / GridDist)
        If (x >= 1 And x <= 11) And (y >= 1 And y <= 19) Then
            lblL.Visible = True
            lblL.Text = x & "," & y
            lblL.Left = e.X
            lblL.Top = e.Y - 5
        Else
            lblL.Visible = False
        End If
    End Sub
 
    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim gp As New GraphicsPath
        Dim pts As New List(Of Point)
        For Each pair In LPoints
            Dim pt As Point = New Point(pair.Key, pair.Value)
            pts.Add(pt)
            Dim rc As New Rectangle(pt.X, pt.Y, 1, 1)
            rc.Inflate(3, 3)
            gp.AddRectangle(rc)
        Next
 
        For x As Integer = 0 To (GridDist * 12) Step GridDist
            e.Graphics.DrawLine(Pens.LightBlue, x, 0, x, (GridDist * 20))
 
        Next
        For y As Integer = 0 To (GridDist * 20) Step GridDist
            e.Graphics.DrawLine(Pens.LightBlue, 0, y, (GridDist * 12), y)
        Next
 
        If LPoints.Count >= 2 Then
            e.Graphics.DrawLines(Pens.Blue, pts.ToArray)
        End If
        e.Graphics.FillPath(Brushes.Blue, gp)
        e.Graphics.DrawPath(Pens.Black, gp)
    End Sub
End Class

Open in new window

Current-progress.png
0
NerdsOfTech
Asked:
NerdsOfTech
  • 3
1 Solution
 
käµfm³d 👽Commented:
I added another sorted list to keep track of which symbol a point should display. Now, if you click on the same point a second time, the symbol should change.
Imports System.Drawing.Drawing2D
Public Class Form1
    Private GridDist As Integer = 20
    Private LPoints As New SortedList(Of Integer, Integer)
    Private Symbols As New SortedList(Of Integer, String)
 
    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        Dim x As Integer = Math.Round(e.X / GridDist) * GridDist
        Dim y As Integer = Math.Round(e.Y / GridDist) * GridDist
 
        If (x / GridDist >= 1 And x / GridDist <= 11) And (y / GridDist >= 1 And y / GridDist <= 19) Then
            If (e.Button = Windows.Forms.MouseButtons.Right) Then
                If (LPoints.ContainsKey(x)) Then
                    If LPoints(x) = y Then
                        LPoints.Remove(x)
                    End If
                End If
            Else
                LPoints(x) = Math.Round(e.Y / GridDist) * GridDist
 
                If Symbols.ContainsKey(x) Then
                    If Symbols(x) = "X" Then
                        Symbols(x) = "O"
                    Else
                        Symbols(x) = "X"
                    End If
                Else
                    Symbols.Add(x, "X")
                End If
            End If
            PictureBox1.Refresh()
        End If
    End Sub
 
    Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave
        lblL.Text = ""
    End Sub
 
    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Dim x As Integer = Math.Round(e.X / GridDist)
        Dim y As Integer = Math.Round(e.Y / GridDist)
        If (x >= 1 And x <= 11) And (y >= 1 And y <= 19) Then
            lblL.Visible = True
            lblL.Text = x & "," & y
            lblL.Left = e.X
            lblL.Top = e.Y - 5
        Else
            lblL.Visible = False
        End If
    End Sub
 
    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim gp As New GraphicsPath
        Dim pts As New List(Of Point)
        For Each pair In LPoints
            Dim pt As Point = New Point(pair.Key, pair.Value)
            pts.Add(pt)
            Dim rc As New Rectangle(pt.X, pt.Y, 1, 1)
            gp.AddString(Symbols(pt.X), FontFamily.GenericMonospace, FontStyle.Bold, _
                 12, New PointF(pt.X - 6, pt.Y - 6), StringFormat.GenericDefault)
        Next
 
        For x As Integer = 0 To (GridDist * 12) Step GridDist
            e.Graphics.DrawLine(Pens.LightBlue, x, 0, x, (GridDist * 20))
 
        Next
        For y As Integer = 0 To (GridDist * 20) Step GridDist
            e.Graphics.DrawLine(Pens.LightBlue, 0, y, (GridDist * 12), y)
        Next
 
        If LPoints.Count >= 2 Then
            e.Graphics.DrawLines(Pens.Blue, pts.ToArray)
        End If
        e.Graphics.FillPath(Brushes.Blue, gp)
        e.Graphics.DrawPath(Pens.Black, gp)
    End Sub
End Class

Open in new window

0
 
käµfm³d 👽Commented:
Forgot the remove section and I also made it so that if you click on the same X but different Y, the symbol does not change. Only when you click directly on an existing point will the symbol change.
Imports System.Drawing.Drawing2D
Public Class Form1
    Private GridDist As Integer = 20
    Private LPoints As New SortedList(Of Integer, Integer)
    Private Symbols As New SortedList(Of Integer, String)
 
    Private Sub PictureBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
        Dim x As Integer = Math.Round(e.X / GridDist) * GridDist
        Dim y As Integer = Math.Round(e.Y / GridDist) * GridDist
 
        If (x / GridDist >= 1 And x / GridDist <= 11) And (y / GridDist >= 1 And y / GridDist <= 19) Then
            If (e.Button = Windows.Forms.MouseButtons.Right) Then
                If (LPoints.ContainsKey(x)) Then
                    If LPoints(x) = y Then
                        LPoints.Remove(x)
                        Symbols.Remove(x)
                    End If
                End If
            Else
                If Symbols.ContainsKey(x) Then
                    If Symbols(x) = "X" AndAlso LPoints(x) = y Then
                        Symbols(x) = "O"
                    ElseIf Symbols(x) = "O" AndAlso LPoints(x) = y Then
                        Symbols(x) = "X"
                    End If
                Else
                    Symbols.Add(x, "X")
                End If
 
                LPoints(x) = Math.Round(e.Y / GridDist) * GridDist
            End If
            PictureBox1.Refresh()
        End If
    End Sub
 
    Private Sub PictureBox1_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles PictureBox1.MouseLeave
        lblL.Text = ""
    End Sub
 
    Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        Dim x As Integer = Math.Round(e.X / GridDist)
        Dim y As Integer = Math.Round(e.Y / GridDist)
        If (x >= 1 And x <= 11) And (y >= 1 And y <= 19) Then
            lblL.Visible = True
            lblL.Text = x & "," & y
            lblL.Left = e.X
            lblL.Top = e.Y - 5
        Else
            lblL.Visible = False
        End If
    End Sub
 
    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
        Dim gp As New GraphicsPath
        Dim pts As New List(Of Point)
        For Each pair In LPoints
            Dim pt As Point = New Point(pair.Key, pair.Value)
            pts.Add(pt)
            Dim rc As New Rectangle(pt.X, pt.Y, 1, 1)
            gp.AddString(Symbols(pt.X), FontFamily.GenericMonospace, FontStyle.Bold, _
                 12, New PointF(pt.X - 6, pt.Y - 6), StringFormat.GenericDefault)
        Next
 
        For x As Integer = 0 To (GridDist * 12) Step GridDist
            e.Graphics.DrawLine(Pens.LightBlue, x, 0, x, (GridDist * 20))
 
        Next
        For y As Integer = 0 To (GridDist * 20) Step GridDist
            e.Graphics.DrawLine(Pens.LightBlue, 0, y, (GridDist * 12), y)
        Next
 
        If LPoints.Count >= 2 Then
            e.Graphics.DrawLines(Pens.Blue, pts.ToArray)
        End If
        e.Graphics.FillPath(Brushes.Blue, gp)
        e.Graphics.DrawPath(Pens.Black, gp)
    End Sub
End Class

Open in new window

0
 
NerdsOfTechTechnology ScientistAuthor Commented:
Excellent work! Thank you for the complete code example.
0
 
käµfm³d 👽Commented:
Glad to help :)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now