Visual Basic - Making a Line Chart

Viewed 962

This is my first post on stackoverflow so sorry in advance for anything I may have messed up, but for a project I am doing a simulator for projectile motion. I am only a beginner programmer and dont have much experience with charts, but there aren't any youtube videos that I find helpful.

The chart is plotting vertical displacement against horizontal displacement, and should look like an inverted parabola but it doesn't look anything like what it should.

I am struggling to set axis intervals correctly, each time the line should start from the origin but the x axis contains negative values for displacement, something which should definitely not be occurring. Each time a different simulation is done the axis should change so that each interval in the x axis is something along the lines of a tenth of the total range of the projectile.

Anything that could point me in the right direction would be incredibly useful.

Screenshot of chart on runtime

Code:

 Public Sub CreateDiagram(ByVal flightRange As Double, ByVal totalTime As Double, ByVal velocity 
 As Double, ByVal angle As Double, ByVal elevation As Double, ByVal heightOfProjectile As Double)

    Chart1.Titles.Add("Projectile Motion")
    Chart1.ChartAreas.Clear()
    Chart1.ChartAreas.Add("Default")

    Dim xAxisInterval As Integer = CInt(totalTime / 10)
    Dim yAxisInterval As Integer = CInt(heightOfProjectile / 10)

    With Chart1.ChartAreas("Default")
        .AxisX.Interval() = xAxisInterval
        .AxisY.Interval() = yAxisInterval

    End With

    Chart1.Series.Add("projection")
    Chart1.Series("projection").Color = Color.Black
    Chart1.Series("projection").ChartType = DataVisualization.Charting.SeriesChartType.Line


    For x = 0 To totalTime Step 0.1

        Dim xPos As Double = findXLocation(velocity, angle, x)
        Dim yPos As Double = findYLocation(velocity, angle, x, elevation)

        Chart1.Series("projection").Points.AddXY(xPos, yPos)

    Next

End Sub 

EDIT: findXLocation and findYLocation code:

Public Function findYLocation(ByVal velocity As Double, ByVal angle As Double, ByVal time As Double, ByVal elevation As Double) As Double
    Dim y As Double

    y = elevation + findVerticalVelocity(velocity, angle) - ((0.5 * gConstant) * (time ^ 2))
    y = Math.Round(y, 1)


    If y < 0 Then
        y = 0
    End If


    Return y

End Function
Public Function findXLocation(ByVal velocity As Double, ByVal angle As Double, ByVal time As Double) As Double
    Dim x As Double

    x = findHorizontalVelocity(velocity, angle) * time
    x = Math.Round(x, 1)

    If x < 0 Then
        x = 0
    End If

    Return x
End Function
1 Answers

If you want to explicitly set the minimum value of the X Axis you can use Axis.Minimum. In your case you would use it as Chart1.ChartAreas("Default").AxisX.Minimum = SomeValue Note that when you set the minimum in this way the axis will stop automatically rescaling.

If you want the minimum to always be zero when all x-values are positive, have a look at Axis.IsStartedFromZero

I hope i understood your question correctly because you mention intervals, but seem to be talking about the minimum value of your x axis.

As a further comment on your code unrelated to the question; it is unnecessary and inefficient to remove the ChartArea every time you want to update the graph, same goes for the Series. Doing this will result in having to re-format the chart on every update (like you are in fact doing with the series).

It suffices to call YourSeries.Points.Clear() and to then add the new points. This way you don't have to re-specify the series color and chartype on each update.

EDIT:

I also see that you round the x position to one decimal, presumably to prevent the x-axis from having long ugly numbers on it. However, a better way to do this is to specify a format for the axis:

chart1.ChartAreas.FirstOrDefault.AxisX.LabelStyle.Format = "{0:0.0}" in your case. This way your series will still store the exact value, but only one decimal will be displayed.

Related