changing vb.net chart xAxis maximum and minimum datetime type - vb.net

I am using chart control on vb.net windows form application.
I am loading data into chart1 and all looks good; I am using this data type:
Chart1.Series("test").XValueType = DataVisualization.Charting.ChartValueType.DateTime
Chart1.Series("test").YValueType = DataVisualization.Charting.ChartValueType.Int32
Then I am using a Trackbar1 control to change/zoom/rescale xAxis and using this code:
Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
ChartRanger(TrackBar1.Value)
End Sub
Having TrackBar1 min=0 and max=366 in Property window.
While the ChartRanger function looks like this:
Private Sub ChartRanger(theDays As Integer)
Chart1.ChartAreas(0).AxisX.IntervalType = 0
Chart1.ChartAreas(0).AxisX.Interval = 0
Chart1.ChartAreas(0).AxisX.Minimum = 0
Chart1.ChartAreas(0).AxisX.Maximum = theDays
End Sub
There is no debugging error and it looks like working; but the logic is not correct in the output.
i.e. What I am trying to achieve is to let app user define minimum datetime and maximum datetime for chart1 xAxis. having dataset contains a daily records.
Update: I have seen the other related posts, they suggest answers for ASP, VBA but can't find answer for VB.Net win forms; its more for the best logic here.

I think your problem is Chart1.ChartAreas(0).AxisX.Maximum = theDays. The AxisX type is a Double representing a DateTime, while theDays is an Integer. You need to figure out what the maximum date for AxisX should be based on the value of theDays, and convert that date to a double using ToOADate().
Here's a working example:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Chart1.Series.Clear()
Dim s = Chart1.Series.Add("s")
s.ChartType = DataVisualization.Charting.SeriesChartType.Point
s.XValueType = DataVisualization.Charting.ChartValueType.DateTime
s.XValueType = DataVisualization.Charting.ChartValueType.Int32
For i As Integer = 0 To 100
s.Points.AddXY(Date.Today.AddDays(i), i)
Next
TrackBar1.Maximum = 100
End Sub
Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
Dim val As Integer = TrackBar1.Value
Chart1.ChartAreas(0).AxisX.Maximum = Date.Today.AddDays(val).ToOADate()
End Sub
End Class
Or if you don't know the min and max dates already, you can set the axis maximum relative to the position of the TrackBar:
Private Sub TrackBar1_Scroll(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
' Get min and max dates
Dim maxDate As Date = Date.FromOADate(Chart1.Series("s").Points.FindMaxByValue("X").XValue)
Dim minDate As Date = Date.FromOADate(Chart1.Series("s").Points.FindMinByValue("X").XValue)
' Get total days between dates
Dim totalDays = maxDate.Subtract(minDate).Days
' Get the bar position as a percent of 100
Dim barPct As Double = TrackBar1.Value / TrackBar1.Maximum
' Find the maximum day that should be displayed on the plot
Dim maxAxisDay As Integer = barPct * totalDays
' Get the date of the maximum day
Dim maxAxisDate = minDate.AddDays(maxAxisDay)
' Set maximum. Convert the date to a double using .ToOADate()
Chart1.ChartAreas(0).AxisX.Maximum = maxAxisDate.ToOADate()
End Sub
Edit:
Assuming that the trackbar maximum is set to the total number of days represented by the dataset, it's a bit easier:
Private Sub TrackBar1_Scroll_1(sender As Object, e As EventArgs) Handles TrackBar1.Scroll
' Get the first date
Dim minDate As Date = Date.FromOADate(Chart1.Series("s").Points.FindMinByValue("X").XValue)
' Assuming that the trackbar has the total number of days represented, the maximum date to display is the first date plus the
' days represented by the trackbar
Dim maxDisplayDate As Date = minDate.AddDays(TrackBar1.Value)
' Set the max axis
Chart1.ChartAreas(0).AxisX.Maximum = maxDisplayDate.ToOADate()
End Sub

Related

VB.Net guess user's number from 1 to 1000

I am trying to create a guessing game that guesses the user's number from 1 to 1000. The user inputs if the number is higher or lower than the computer's guess. Based on the user's input, the computer each time halves the amount of the guess (e.g. first guess is 500, second is 250, third 125, etc, etc)
However I have encountered a problem when I am running this program. After pressing 'higher' or 'lower' for a few times, I am unable to change the output any further. I suppose this is to do with amount = amount / 2 reaching a limit where it can barely be added or subtracted into intGuess. I have tried doing amount = (amount / 2) + 1, but that sometimes doesn't allow me to get to a number.
How would I counteract this problem?
Here is my code:
Dim intGuess As Integer = 500
Dim amount As Integer = 500
Dim count As Integer = 0
Private Sub btnLower_Click(sender As Object, e As EventArgs) Handles btnLower.Click
amount = amount / 2
intGuess = intGuess - amount
lblGuess.Text = $"Is your number {intGuess} ?"
count = count + 1
End Sub
Private Sub btnHigher_Click(sender As Object, e As EventArgs) Handles btnHigher.Click
amount = amount / 2
intGuess = intGuess + amount
lblGuess.Text = $"Is your number {intGuess} ?"
count = count + 1
End Sub
Just thought I should add this, but the first guess is 500.
I play this game verbally with my young son. I tell him to guess a number from 1 to 1000 and guarantee I can guess it in 10 or fewer guesses. It is a simple binary search. You can research binary search to come up with an algorithm. It's pretty simple and I've split it up into buttons like you have. Here is my form
The code to make it work is
Private guess As Integer
Private max As Integer
Private min As Integer
Private Sub StartButton_Click(sender As Object, e As EventArgs) Handles StartButton.Click
If Integer.TryParse(MaxTextBox.Text, max) AndAlso
Integer.TryParse(MinTextBox.Text, min) AndAlso
max > min Then
makeGuess()
Else
MessageBox.Show("Error in max or min, cannot continue! Fix max and min and try again.")
End If
End Sub
Private Sub HigherButton_Click(sender As Object, e As EventArgs) Handles HigherButton.Click
min = guess
makeGuess()
End Sub
Private Sub LowerButton_Click(sender As Object, e As EventArgs) Handles LowerButton.Click
max = guess
makeGuess()
End Sub
Private Sub JustRightButton_Click(sender As Object, e As EventArgs) Handles JustRightButton.Click
MessageBox.Show($"That's right, I found your number, it is {guess}!")
End Sub
Private Sub makeGuess()
guess = CInt((max - min) / 2 + min)
GuessLabel.Text = guess.ToString()
End Sub

Need to know why code is repeating itself

Public Class Form1
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim EvenNum, EvenNumCount, EvenNumAverage, Number, Result As Integer
Calculations(EvenNum, EvenNumCount)
GetInput(Number)
Output(Result)
End Sub
Sub GetInput(ByRef Number)
Number = txtInput.Text
End Sub
Sub Calculations(ByRef EvenNum, ByRef EvenNumCount)
Dim ListedNumbers, lstOutputSize As Integer
GetInput(lstOutputSize)
For i As Integer = 0 To lstOutputSize - 1
ListedNumbers = InputBox("Enter Numbers", "Input")
lstOutput.Items.Add(ListedNumbers)
Next
For i As Integer = 0 To lstOutput.Items.Count - 1
If (CInt(lstOutput.Items(i)) Mod 2 = 0) Then
EvenNum += lstOutput.Items(i)
EvenNumCount += 1
End If
Next
End Sub
Function Average(ByRef EvenNumAverage As Integer) As Integer
Dim EvenNum, EvenNumCount As Integer
Calculations(EvenNum, EvenNumCount)
EvenNumAverage = EvenNum / EvenNumCount
Return EvenNumAverage
End Function
Sub Output(ByRef EvenNumAverage)
lstOutput.Items.Add(Average(EvenNumAverage))
End Sub
The program is supposed to get input from a textbox for a desired number of numbers to be entered into a listbox from inputboxes.
It is then supposed to get the average of only the even numbers and then display that average into the listbox.
In it's current state the program will do what it is intended to do, it just repeats the calculation code. This only happens when I add the Output call statement under the button procedure.
You're calling Calculations twice
From btnCalculate_Click
From Average which is called by Output

parse rounds to whole

I am trying to parse a textbox.text with a input value of 15.75. Here is all the code.
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim lnVendorNo, lnInHouseID, lnInventoryPackID As Integer
Dim lcVendProdID, lcVendProdDesc, lcDeliverPack As String
Dim lnDelivPackCost, lnDelivPackCost2 As Short
Integer.TryParse(txtVendorNo.Text, lnVendorNo)
lcVendProdID = txtVendProdID.Text
Integer.TryParse(txtInHouseID.Text, lnInHouseID)
lcVendProdDesc = txtVendProdDesc.Text
lcDeliverPack = txtDeliverPack.Text
txtDeliverPackCost.Text = "15.75"
Decimal.TryParse(txtDeliverPackCost.Text, lnDelivPackCost)
' Value of lnDelivPackCost in watch window is 16 and type is short
lnDelivPackCost2 = Double.Parse(txtDeliverPackCost.Text)
' value of lnDelivPackCost2 in watch window is 16 and type is short
I have another sub with the following code that works just fine.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim value As String
Dim number As Decimal
Dim lnDelivPackCost As Decimal
' Parse a floating-point value with a thousands separator.
value = "1643.57"
If Decimal.TryParse(value, number) Then
Console.WriteLine(number) ' Value of number in watch = 1643.57
End If
txtDeliverPackCost.Text = "15.75"
Decimal.TryParse(txtDeliverPackCost.Text, lnDelivPackCost) ' Value on lnDelivPackCost in watch = 15.75D
End Sub
Can anyone tell me why the parses work on one sub and not the other sub. Is it because of parsing to integers earlier in the sub. I am going bonkers trying to figure this out. Any help would be appreciated.
Larry

multiple inputs in text box not totaling

I got another super basic question, im trying to total the subtotals of every entry in the txtPrice.Text the user enters, and then refresh the other lables with the updated tax, shipping, and grand total. Its not totaling the subTotal, everything else works fine. Whats up with that?
Private Sub btnCalc_Click(sender As Object, e As EventArgs) Handles btnCalc.Click
Dim sglSub As Single
Dim sglTotal As Single
Dim sglSalesTax As Single
Const TAX_RATE As Single = 0.02
Dim bytShippingCharge As SByte = 10
Dim sglCompTotal As Single
Single.TryParse(txtPrice.Text, sglSub)
sglTotal += sglSub
lblSubTotal.Text = sglTotal.ToString("C2")
sglSalesTax = (sglTotal * TAX_RATE)
lblTax.Text = sglSalesTax.ToString("C2")
If sglTotal >= 100 Then
bytShippingCharge = 0
End If
lblShipping.Text = bytShippingCharge.ToString("C2")
sglCompTotal = (sglTotal + sglSalesTax + bytShippingCharge)
lblTotal.Text = sglCompTotal.ToString("C2")
End Sub
Tips
In this line:
sglTotal += sglSub
-Every time you work with a total initialize it to zero before adding a value to it. If not it can leads to undesired result.
-When working with currency is better to use a decimal type instead.
If you want a variable keeps its value declare it shared.
This a little example of how you can use a shared field
Public Class Form1
Shared total As Decimal = 0D
Shared Sub calc()
total += 2
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
calc()
Label1.Text = total.ToString
End Sub
End Class

Change the datagridview colour based on date

i got a datagridview which displays data from database(MS Access)
the datagridview display the data correctly..
now i want to change the colour of the dgvReminder's row to yellow if current date is less than 2 days to the Date_Of_Pickup.
Date_Of_Pickup is in this format = 19-Dec-2013
So far i have test this code :-
Private Sub Home_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For i As Integer = 0 To dgvReminder.Rows.Count - 1
If dgvReminder.Rows(i).Cells("Quantity").Value < 2 Then
dgvReminder.Rows(i).Cells(2).Style.BackColor = Color.Yellow
End If
Next
End Sub
The whole Quantity column which has value less than 2 turn to yellow
but how can i do this with the Date_Of_Pickup column??
try something like this:
If DateDiff(DateInterval.Day,dgvReminder.Rows(i).Cells("Date_Of_Pickup").Value,Now()) > 2) Then
dgvReminder.Rows(i).Cells(2).Style.BackColor = Color.Yellow
End If
I did this one and it works , I just checked if the record is expired or about to expire within ongoing month. you can just change the date interval as your need. I used DataBinding Complete event of Data GridView
Private Sub grdMembersInfo_DataBindingComplete(sender As System.Object, e As System.Windows.Forms.DataGridViewBindingCompleteEventArgs) Handles grdMembersInfo.DataBindingComplete
For i = 0 To grdMembersInfo.Rows.Count - 1
Dim expDate As Date = grdMembersInfo.Rows(i).Cells("iCardExpiryDate").Value
If DateDiff(DateInterval.Month, Date.Now, expDate) <= 0 Then
grdMembersInfo.Rows(i).DefaultCellStyle.BackColor = Color.LightPink
Else
grdMembersInfo.Rows(i).DefaultCellStyle.BackColor = Color.LightGreen
End If
Next
End Sub