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

x
?
Solved

Create a user editable line graph in vb.net

Posted on 2014-08-08
14
Medium Priority
?
1,046 Views
Last Modified: 2014-08-11
Hi

I hope this is not too complicated for a single question.

I want to create a graph with specific points that the user can drag up or down, with the mouse, within a rectangle. Just to set the context, the graph will determine the number of units available over 12 periods. Each moveable point is a circle shape. I have worked out how to get the shape to move up and down but I need help with:

How do I ensure that it only moves within the top and bottom boundaries of the rectangle?

Is it possible to have the line graph adjust in real time so that each line begins and ends in the centre of a circle?

I went over to the dark side for a while and managed to do this with 'Livecode', but I'm struggling with how to do it in VB.net.

The attached picture shows what the Livecode version of the graph looks like. Basically, the user can drag the circles and the lines of the graph move simultaneously.

Regards

Terry
Interactive-Graph.jpg
0
Comment
Question by:Terrygordon
  • 7
  • 7
14 Comments
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40251346
Try this:
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        AddHandler Chart1.MouseDown, AddressOf Chart_MouseDown
        AddHandler Chart1.MouseMove, AddressOf Chart_MouseMove
    End Sub

    Sub SetY(ByVal ch As Chart, ByVal e_X As Integer, ByVal e_Y As Integer)
        Try
            If e_X >= 0 And e_X < Chart1.Width And e_Y > 0 And e_Y < Chart1.Height Then
                Dim currentx As Integer = ch.ChartAreas(0).AxisX.PixelPositionToValue(e_X)
                If currentx < ch.ChartAreas(0).AxisX.Minimum Or currentx > ch.ChartAreas(0).AxisX.Maximum Then
                    currentx = -1
                End If
                Dim currenty As Integer = ch.ChartAreas(0).AxisY.PixelPositionToValue(e_Y)
                If currenty < ch.ChartAreas(0).AxisY.Minimum Or currenty > ch.ChartAreas(0).AxisY.Maximum Then
                    currenty = -1
                End If
                If currentx > -1 And currenty > -1 Then
                    ch.Series(0).Points.FindByValue(currentx, "X").SetValueY(currenty)
                    ch.Invalidate()
                End If
            End If
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try
    End Sub

    Private Sub Chart_MouseDown(sender As Object, e As MouseEventArgs)
        If e.Button = Windows.Forms.MouseButtons.Left Then
            SetY(CType(sender, Chart), e.X, e.Y)
        End If
    End Sub

    Private Sub Chart_MouseMove(sender As Object, e As MouseEventArgs)
        If e.Button = Windows.Forms.MouseButtons.Left Then
            SetY(CType(sender, Chart), e.X, e.Y)
        End If
    End Sub

Open in new window

0
 

Author Comment

by:Terrygordon
ID: 40251770
Hi Robert

I couldn't get this to work. Presumably I need to create chart1?

Regards

Terry
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40251775
Yes, I'm not sure what your form looks like but I tested it by just putting a chart on a form, that gets named Chart1 by default.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Terrygordon
ID: 40251814
Hi Robert

I'm getting an error "Type chart is not defined".

Regards

Terry
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40251818
Right, you probably need to add (at the very top of your file):
Imports System.Windows.Forms.DataVisualization.Charting

Open in new window

0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40251836
Here's some more code I have to make it look like your example a bit more.
    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        Dim dt As New DataTable
        dt.Columns.AddRange({New DataColumn("X", GetType(Integer)), New DataColumn("Y", GetType(Integer))})
        Dim r As New Random
        For i As Integer = 1 To 12
            dt.Rows.Add({i, r.Next(1000, 49000)})
        Next
        Chart1.DataSource = dt
        Chart1.BackColor = Color.FromArgb(58, 80, 184)
        Chart1.BackSecondaryColor = Color.FromArgb(111, 128, 206)
        Chart1.BackGradientStyle = GradientStyle.TopBottom
        Chart1.ChartAreas(0).AxisX.Minimum = 1
        Chart1.ChartAreas(0).AxisX.Maximum = 12
        Chart1.ChartAreas(0).AxisX.MajorGrid.LineColor = Color.Silver
        Chart1.ChartAreas(0).AxisX.LabelStyle.ForeColor = Color.White
        Chart1.ChartAreas(0).AxisY.Maximum = 50000
        Chart1.ChartAreas(0).AxisY.MajorGrid.LineColor = Color.Silver
        Chart1.ChartAreas(0).AxisY.MajorGrid.Interval = 5000
        Chart1.ChartAreas(0).AxisY.LabelStyle.ForeColor = Color.White
        Chart1.ChartAreas(0).BackGradientStyle = GradientStyle.TopBottom
        Chart1.ChartAreas(0).BackColor = Color.FromArgb(150, 165, 221)
        Chart1.ChartAreas(0).BackSecondaryColor = Color.FromArgb(69, 93, 194)
        Chart1.Series(0).XValueMember = "X"
        Chart1.Series(0).YValueMembers = "Y"
        Chart1.Series(0).ChartType = SeriesChartType.Line
        Chart1.Series(0).Color = Color.White
        Chart1.Series(0).BorderWidth = 2
        Chart1.Series(0).MarkerImage = "marker.png"
        Chart1.Series(0).MarkerImageTransparentColor = Color.FromArgb(1, 0, 1)
        Chart1.Legends(0).Enabled = False
        AddHandler Chart1.MouseDown, AddressOf Chart_MouseDown
        AddHandler Chart1.MouseMove, AddressOf Chart_MouseMove
    End Sub

Open in new window

0
 

Author Comment

by:Terrygordon
ID: 40252040
Hi Robert

Still getting lots of errors with this (unhandled exception of type system.ArgumentOutOfRangeException).  Additional information says - Must be non-negative and less than the size of the collection. It is highlighting the line:

Chart1.Legends(0).Enabled = False

Then, when I break or continue, all instances of Chart1 are highlighted.

I have also tried again with your original code and am getting an error in line 21:

 ch.Series(0).Points.FindByValue(currentx, "X").SetValueY(currenty)

The error is: Object reference not set to an instance of an object.


Regards

Terry
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40252063
I'm not sure from those messages what's missing. Can you try this project?
EE-Q-28493650.ZIP
0
 

Author Comment

by:Terrygordon
ID: 40252069
Hi Robert

Works and looks great on your version. I will have a play around with it tomorrow and award the points once I've figured it out. :-)

Regards

Terry
0
 
LVL 35

Expert Comment

by:Robert Schutt
ID: 40252072
Ok, Terry that's good news. Any questions, don't hesitate.
0
 

Author Comment

by:Terrygordon
ID: 40253315
Hi Robert

I have recreated form1 and Chart1in my own project and it is now working great.

I was getting an error "Cannot load image from this location" when it tried to load marker.png, but this seems to have been resolved by copying the marker.png file into the bin/debug folder.

In the next stage I am adding multiple charts to the form and have started by just adding a new datatable, random numbers, properties, etc. for Chart2, in the form1 load sub.

This displays perfectly and allows me to drag the points on both charts independently, even though I haven't amended any of the other subs.

Do I need to make any changes to the other subs? For example, the SetY sub refers to Chart1, but none of the other subs (MouseDown, MouseMove, Customize) do.

I am more than happy with your solution so far so, if you prefer, I can post this as a separate question.

Regards

Terry
0
 
LVL 35

Accepted Solution

by:
Robert Schutt earned 2000 total points
ID: 40253381
resolved by copying the marker.png file into the bin/debug folder
Normally this should be done as a build action, the file marker.png should be added to the project, then in the solution explorer, select it and right click to go to properties, then choose the appropriate copy action
captureThe reference to Chart1 in SetY was a later addition and I did that too fast... it should refer to "ch" (the first argument to the sub), and then everything should be independent of the actual chart the mousexxx functions are handling. So the correct code would be:
    Sub SetY(ByVal ch As Chart, ByVal e_X As Integer, ByVal e_Y As Integer)
        Try
            If e_X >= 0 And e_X < ch.Width And e_Y > 0 And e_Y < ch.Height Then
...

Open in new window

0
 

Author Comment

by:Terrygordon
ID: 40253546
Thanks Robert. Not only a brilliant solution, but saved me a load of time by not having to redesign the charts.

Regards

Terry
0
 

Author Closing Comment

by:Terrygordon
ID: 40253558
An excellent solution with some design thrown in and very fast response times.
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses
Course of the Month20 days, 13 hours left to enroll

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question