Why wrong datetime order in Zedgraph - zedgraph

I have the following code to plot value
StockPointList spl = new StockPointList();
for (int i = 0; i < dtTable.Rows.Count; i++)
{
dtDate = Convert.ToDateTime(dtTable.Rows[i]["DateTime"]);
XDate xDate = new XDate(dtDate.Year, dtDate.Month, dtDate.Day, dtDate.Hour, dtDate.Minute, dtDate.Second);
double x = xDate.XLDate;
double open = Convert.ToDouble(dtTable.Rows[i]["BarOpen"]);
double close = Convert.ToDouble(dtTable.Rows[i]["BarClose"]);
double hi = Convert.ToDouble(dtTable.Rows[i]["BarHigh"]);
double low = Convert.ToDouble(dtTable.Rows[i]["BarLow"]);
StockPt pt = new StockPt(x, hi, low, open, close, 100000);
pt.ColorValue = close > prevClose ? 2 : 1;
spl.Add(pt);
prevClose = close;
open = close;
}
myPane.XAxis.Type = AxisType.DateAsOrdinal;
myPane.XAxis.Scale.Format = "MM/dd/yyyy\nHH:MM:ss";
The column type of "DateTime" in the datatable is of "DateTime" format. I have also used a dataview to sort "DateTime" column.
When I plot to ZedGraph, its getting plotted in correct datetime order but the values that are plotted in the X-axis is in wrong order.
Any idea to resolve this?

Related

Deleting new lines once the price crosses it after the line was created

I have been creating new lines in pinescript that extend and want to delete them when the future price hits or crosses the line price. Any help will be appreciated.
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//#version=4
study("My RS", overlay=true)
float d = 1.0
t = time("60")
start = na(t[1]) or t > t[1]
ticker = syminfo.ticker
src=input(title="Source", type=input.source, defval=open)
float d_r = na
float d_s = na
if (start)
d_r := src + d
d_s := src - d
line lr = na
line ls = na
// drawing r/s lines every hour
if (start)
lr := line.new(x1 = bar_index, y1 = d_r, x2 = bar_index - 1, y2 = d_r, extend = extend.left, color = color.red, width = 2, style = line.style_dashed)
ls := line.new(x1 = bar_index, y1 = d_s, x2 = bar_index - 1, y2 = d_s, extend = extend.left, color = color.lime, width = 2, style = line.style_dashed)
// want to delete lines when the future price crosses the line, which is not working for me
for i = 0 to 100
if not na(lr[i]) and close < high[i]
line.delete(lr[i])
if not na(ls[i]) and close < low[i]
line.delete(ls[i])
you need to get the coordinate of the lines, so use inside a loop if line.get_y1(id[i]) < close if it true, line.delete(id[i]).
Is this what're you looking for?

How to get Excel Columns Range in Epplus and set its Column Width?

Example. How in Epplus?
Sheet.Cells["a1:d1"].Column.Width = 10;
In Excel Interop:
Sheet.get_Range("a1", "d1").ColumnWidth = 10;
You can set the widths but have to do it per column. You can do it over a range like this:
for (int c = 1; c <= ws.Cells["A1:D1"].Columns; c++)
ws.Column(c).Width = 10;
If you want to do it on ALL cells with data you can omit the range and Epplus will only return cells with actual data in it:
for (int c = 1; c <= ws.Cells.Columns; c++)
ws.Column(c).Width = 10;
And this to start in specific Column. Not Using ws.Cells[range]
int startColumn = 3; int endColumn = 10;
for (int a = startColumn; a <= endColumn; a++)
{
Sheet.Column(a).Width = 10;
}

calculate rank from student marks stored in datatable in vb. net

I am working on examination result system in vb.net which requires to calculate student ranks based on marks obtained. Subject marks data is stored in database. I am loading the subject marks in a datatable
da.Fill(dt) 'added to a datagridview.
DataGridView1.DataSource = dt
then Add New columns in dt to show result:
dt.Columns.Add("Obtained Marks", GetType(String))
dt.Columns.Add("Percent", GetType(String))
dt.Columns.Add("Result", GetType(String))
dt.Columns.Add("Rank", GetType(Integer))
Then calculated total of all the subjects & added in obtained marks columns by looping through rows & columns of datatable.
For s As Integer = 0 To dt.Rows.Count - 1
For t As Integer = 0 To dt.Columns.Count - 1
obtmarks += CDbl(dt.Rows(s).Item(t))
Next
dt.Rows(s)("Obtained Marks") = obtmarks
dt.Rows(s)("Result") = "PASS"
dt.Rows(s)("Rank") = 'RANK OF STUDENT
Next
How can i calculate rank/position of students on the basis of total marks contained in datatable column "Obtained Marks".
i.e.
Student with marks 436 Rank should be 1
Student with marks 429.5 Rank should be 2
Student with marks 412 Rank should be 3 ....
so on until all the rows in record. (Image atttached)
if there is any function for datatable which can help here or how can i add the logic in the loop to calculate rank of students and add the value in rank column. Thanks
P.S. I dnt want to sort the rows on obtained marks, but want to Add rank of each student in front of his/her marks, which is already order by their Roll No.
You could use this code to set the Rank column in your table
DataView dv = new DataView(dt, "", "ObtainedMarks desc", DataViewRowState.CurrentRows);
for(int x = 0; x < dv.Count; x++)
dv[x].Row["Rank"] = x+1;
This could be done only after you have completed the code that calculates the column ObtainedMarks
Also, I suggest to execute all before setting the DataSource of the DataGridView to avoid unnecessary delays in the grid repainting itself when you have not yet finished with it
EDIT
To have the same rank for persons with the same marks you could try something like this
int lastMark = -1;
int currentRank = 0;
int atSameRank = 1;
DataView dv = new DataView(dt, "", "ObtainedMarks desc", DataViewRowState.CurrentRows);
for(int x = 0; x < dv.Count; x++)
{
int currentMark = Convert.ToInt32(dv["ObtainedMarks"]);
if(currentMark != lastMark)
{
lastMark = currentMark;
currentRank = currentRank + atSameRank;
atSameRank = 0;
}
else
atSameRank++;
dv[x].Row["Rank"] = currentRank;
}
WARNING, I am not at a PC where I could test it.

Show WinForm below a cell

How can I show I winform that I create in VB.NET just below the active cell?
I have no idea how to solve this. I found the following promising solutions:
Excel addin: Cell absolute position
-The accepted solution seems too complicated to work reliably. I got an error on the first row (Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long)
-The second solution looked promising, but it didn't give me the right positions for my windows form.
The following adaptations of the second proposed solution does not create any errors but does not put the windows form in the correct position:
Public Sub GetScreenPositionFromCell(cell As Excel.Range, excel As Excel.Application)
Dim x As Double
Dim y As Double
If Not excel.ActiveWindow Is Nothing Then
x = excel.ActiveWindow.PointsToScreenPixelsX(cell.Left)
y = excel.ActiveWindow.PointsToScreenPixelsY(cell.Top)
End If
Me.Left = x
Me.Top = y
Me.Show()
Me.TopMost = True
End Sub
EDIT: #Loating, here is how I have used your code. It's great and I am very happy that you are taking your time to help me with a solution. The x-coordinates seems to work while the x-coordinates are a bit off and more or less off depending on the zoom level.
Public Sub ShowMeBelowActiveCell()
Dim ExcelApp As Excel.Application = CType(AddinExpress.MSO.ADXAddinModule.CurrentInstance, AddinModule).ExcelApp
Dim excelWindow = ExcelApp.ActiveWindow
Dim cell = ExcelApp.ActiveCell
Dim zoomFactor As Double = excelWindow.Zoom / 100
Dim ws = cell.Worksheet
' PointsToScreenPixels returns different values if the scroll is not currently 1
' Temporarily set the scroll back to 1 so that PointsToScreenPixels returns a
' value we know how to handle.
Dim origScrollCol = excelWindow.ScrollColumn
Dim origScrollRow = excelWindow.ScrollRow
excelWindow.ScrollColumn = 1
excelWindow.ScrollRow = 1
' (x,y) are screen coordinates for the top left corner of the top left cell
Dim x As Integer = excelWindow.PointsToScreenPixelsX(0)
' e.g. window.x + row header width
Dim y As Integer = excelWindow.PointsToScreenPixelsY(0)
' e.g. window.y + ribbon height + column headers height
Dim dpiX As Single = 0
Dim dpiY As Single = 0
Using g = Drawing.Graphics.FromHwnd(IntPtr.Zero)
dpiX = g.DpiX
dpiY = g.DpiY
End Using
' Note: Each column width / row height has to be calculated individually.
' Before, tried to use this approach:
' var r2 = (Microsoft.Office.Interop.Excel.Range) cell.Worksheet.Cells[origScrollRow, origScrollCol];
' double dw = cell.Left - r2.Left;
' double dh = cell.Top - r2.Top;
' However, that only works when the zoom factor is a whole number.
' A fractional zoom (e.g. 1.27) causes each individual row or column to round to the closest whole number,
' which means having to loop through.
For i As Integer = origScrollCol To cell.Column - 1
Dim col = DirectCast(ws.Cells(cell.Row, i), Microsoft.Office.Interop.Excel.Range)
Dim ww As Double = col.Width * dpiX / 72
Dim newW As Double = zoomFactor * ww
x += CInt(Math.Round(newW))
Next
For i As Integer = origScrollRow To cell.Row - 1
Dim row = DirectCast(ws.Cells(i, cell.Column), Microsoft.Office.Interop.Excel.Range)
Dim hh As Double = row.Height * dpiY / 72
Dim newH As Double = zoomFactor * hh
y += CInt(Math.Round(newH))
Next
excelWindow.ScrollColumn = origScrollCol
excelWindow.ScrollRow = origScrollRow
Me.StartPosition = Windows.Forms.FormStartPosition.Manual
Me.Location = New Drawing.Point(x, y)
Me.Show()
End Sub
End Class
When the ScrollColumn and ScrollRow are both 1, then PointsToScreenPixelsX/Y seems to return the top left point of the top left visible cell in screen coordinates. Using this, the offset width and height to the active cell is calculated, taking into consideration the zoom setting.
var excelApp = Globals.ThisAddIn.Application;
var excelWindow = excelApp.ActiveWindow;
var cell = excelApp.ActiveCell;
double zoomFactor = excelWindow.Zoom / 100;
var ws = cell.Worksheet;
var ap = excelWindow.ActivePane; // might be split panes
var origScrollCol = ap.ScrollColumn;
var origScrollRow = ap.ScrollRow;
excelApp.ScreenUpdating = false;
// when FreezePanes == true, ap.ScrollColumn/Row will only reset
// as much as the location of the frozen splitter
ap.ScrollColumn = 1;
ap.ScrollRow = 1;
// PointsToScreenPixels returns different values if the scroll is not currently 1
// Temporarily set the scroll back to 1 so that PointsToScreenPixels returns a
// value we know how to handle.
// (x,y) are screen coordinates for the top left corner of the top left cell
int x = ap.PointsToScreenPixelsX(0); // e.g. window.x + row header width
int y = ap.PointsToScreenPixelsY(0); // e.g. window.y + ribbon height + column headers height
float dpiX = 0;
float dpiY = 0;
using (var g = Graphics.FromHwnd(IntPtr.Zero)) {
dpiX = g.DpiX;
dpiY = g.DpiY;
}
int deltaRow = 0;
int deltaCol = 0;
int fromCol = origScrollCol;
int fromRow = origScrollRow;
if (excelWindow.FreezePanes) {
fromCol = 1;
fromRow = 1;
deltaCol = origScrollCol - ap.ScrollColumn; // Note: ap.ScrollColumn/Row <> 1
deltaRow = origScrollRow - ap.ScrollRow; // see comment: when FreezePanes == true ...
}
// Note: Each column width / row height has to be calculated individually.
// Before, tried to use this approach:
// var r2 = (Microsoft.Office.Interop.Excel.Range) cell.Worksheet.Cells[origScrollRow, origScrollCol];
// double dw = cell.Left - r2.Left;
// double dh = cell.Top - r2.Top;
// However, that only works when the zoom factor is a whole number.
// A fractional zoom (e.g. 1.27) causes each individual row or column to round to the closest whole number,
// which means having to loop through.
for (int i = fromCol; i < cell.Column; i++) {
// skip the columns between the frozen split and the first visible column
if (i >= ap.ScrollColumn && i < ap.ScrollColumn + deltaCol)
continue;
var col = ((Microsoft.Office.Interop.Excel.Range) ws.Cells[cell.Row, i]);
double ww = col.Width * dpiX / 72;
double newW = zoomFactor * ww;
x += (int) Math.Round(newW);
}
for (int i = fromRow; i < cell.Row; i++) {
// skip the columns between the frozen split and the first visible column
if (i >= ap.ScrollRow && i < ap.ScrollRow + deltaRow)
continue;
var row = ((Microsoft.Office.Interop.Excel.Range) ws.Cells[i, cell.Column]);
double hh = row.Height * dpiY / 72;
double newH = zoomFactor * hh;
y += (int) Math.Round(newH);
}
ap.ScrollColumn = origScrollCol;
ap.ScrollRow = origScrollRow;
excelApp.ScreenUpdating = true;
Form f = new Form();
f.StartPosition = FormStartPosition.Manual;
f.Location = new Point(x, y);
f.Show();

how to check what the first character of a string is in vb

I have the following code, which reads the date and time from some DateTimePickers in VB.
I need to be able to determine if the first value is a 0 or a 1, (eg 09:12... or 12:13...) and if it starts with a 0 to remove that character from the string.
this is what i have so far, but it takes the first character regardless.
DateFrom = Form1.DateTimePickerFrom.Value.ToString
DateTo = Form1.DateTimePickerTo.Value.ToString
VarTimeFrom = Form1.HourTimePickerFrom.Value.ToString
VarTimeTo = Form1.HourTimePickerTo.Value.ToString
Dim DateFromManipulated = Left(DateFrom, 10)
Dim DateToManipulated = Left(DateTo, 10)
Dim TimeFromManipulated = Right(VarTimeFrom, 9)
Dim TimeToManipulated = Right(VarTimeTo, 9)
If Left(DateFromManipulated, 1) = 0 Then
TimeFromMan = TimeFromManipulated.Remove(0, 1)
Else
TimeFromMan = TimeFromManipulated
End If
If Left(TimeFromManipulated, 1) = 0 Then
TimeToMan = TimeToManipulated.Remove(0, 1)
Else
TimeToMan = TimeToManipulated
End If
Console.WriteLine(DateFromManipulated)
Console.WriteLine(TimeToMan)
Console.WriteLine(TimeFromManipulated)
Console.WriteLine(TimeFromMan)
Console.WriteLine(DateToManipulated)
Console.WriteLine(TimeToManipulated)
I get the following:
09/11/2012
1:36:00
06:36:00
6:36:00
08/01/2013
11:36:00
Thanks in advance!
Mike
A string in VB.NET won't compare as equal to an integer. You could just reference character zero, though:
If DateFromManipulated(0) = "0"c Then DateFromManipulated = DateFromManipulated.Substring(1)
... however, you should be just formatting your date the way you want it to begin with:
Dim dateFrom As String = DateTimePickerFrom.Value.ToString("M/dd/yyyy H:mm:ss")
... for example. (M doesn't have a leading zero, as opposed to MM; same with H.) You can find all the format strings here: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx