I just wonder if anyone knows how to change the LineStyle of the Major and Minor grid for a ZedGraph?
For example I have:
graphPane.XAxis.MinorGrid.IsVisible = true;
I want something along this line:
graphPane.XAxis.MinorGrid.LineStyle => solid line.
I've done a lot of research today but could not find the answer.
Thank you in advance for your time.
You probably have autoscaling set to true if you switch this off you can then set steps which you wish to use its best to stick with some numbers which are easily divisible otherwise you can get some strange numbers.
myPane.XAxis.Scale.MajorStepAuto = False
myPane.XAxis.Scale.MajorStep = 100
zg1.AxisChange()
zg1.refresh()
The above code is fully x-axis I'm fairly sure it will be similar to change the y-axis. I would start with a major axis and get the right first and you may find that the minor ones work well automatically.
The co code below is probably doing something very similar to what you're looking for and at the end of the case I've just switched on the XAxis.Scale.MajorStepAuto just in case we get some strange number
Select Case CDbl(maxNumber)
Case Is <= 100
myPane.XAxis.Scale.MajorStep = 10
Case Is <= 300
myPane.XAxis.Scale.MajorStep = 25
Case Is <= 1000
myPane.XAxis.Scale.MajorStep = 50
Case Is <= 5000
myPane.XAxis.Scale.MajorStep = 100
Case Is <= 10000
myPane.XAxis.Scale.MajorStep = 250
Case Is <= 50000
myPane.XAxis.Scale.MajorStep = 1000
Case Else
myPane.XAxis.Scale.MajorStepAuto = True
End Select
The following will draw a you solid line in aqua for the major grid line
myPane.XAxis.MajorGrid.DashOff = 0
myPane.XAxis.MajorGrid.Color = Color.Aqua
Hope that helps
Related
Here is what is happening.
First issue is:
I need to press a directional button twice to start incrementing and/or decrementing the x and y variables.
If I change directions for an ex.
From Right to Left, the x variable will increment once more before it'll start decrementing.
The Second Issue:
I have time based on current x and y of player.
However when I go above 2000 the time does not change until 2001.
If I go back down to 1999 the time doesn't change until 1998...
This was the same thing even when my code said
if(y>=0 && y< 2000)
It was the same issue, I thought taking 2000 and making it 1999 would fix that and it did not.
I do not know what is causing either of these issues and I have tried to figure it out... If anyone knows why it is happening like that, I would love to know.
int x = 1995;
int y = 0;
int time = 0;
Console.WriteLine("X: 0Y: 0Time: 0");
while(true){
ConsoleKey key = Console.ReadKey().Key;
Console.SetCursorPosition(Console.CursorLeft, Console.CursorTop -1);
Console.WriteLine($"X: {x,6} Y:{y,6} Time: {time,3}");
Console.SetCursorPosition(Console.CursorLeft, Console.CursorTop +1);
//Change Timezones
if (x >=0 && x< 1999){
time=0;
}
else if (x>=2000 && x< 3999){
time=1;
}
....
//Movement
if (key == ConsoleKey.LeftArrow){
x=x-1;
}
else if (key == ConsoleKey.RightArrow){
x=x+1;
}
....
}
Problem 1 "From Right to Left, the x variable will increment once more before it'll start decrementing."
That's because you print out the value of the previous iteration rather than the new value. Move your Console.WriteLine to the end of the script and it'll show you the updated value
Problem 2 "However when I go above 2000 the time does not change until 2001."
This is caused by the same thing as problem 1 most likely. It could also be caused by the fact you might be changing the value of x after running the change timezone codeblock. Be sure the ordering of your logic is correct.
Problem 3 "If I go back down to 1999 the time doesn't change until 1998"
There's a gap between the values in your logic. You have x < 1999 in your first timezone codeblock, and x >= 2000 in your second timezone codeblock. That means if you start at 2003 for example and go down in value, the time will only change when you reach 1998 because of the x < 1999 part. There's a value that won't trigger a change when decrementing nor incrementing, 1999.
Problem 1:
Console.SetCursorPosition(Console.CursorLert, Console.CursorTop, -1);
does not compile because it must be Console.CursorLeft.
Problem 2:
No overload of SetCursorPosition() takes 3 arguments. Maybe you want
Console.CursorTop -1
Problem 3:
The variables x, y and time are not initialized, so you can't use it in the line
Console.WriteLine($"X: {x,6} Y:{y,6} Time: {time,3}");
Problem 4:
Comparisons in C# require a variable on both sides in the line
else if (x>=2000 && < 3999){
try
else if (x>=2000 && x<3999){
Problem 5:
There's a gap in your definitions:
x< 1999 // ... 1997, 1998
x>=2000 // 2000, 2001, ...
so you're leaving out 1999
First things first:
I have a git repo over here that holds the code of my current efforts and an example data set
Background
The example data set holds a bunch of records in Int32 format. Each record is composed of several bit fields that basically hold info on events where an event is either:
The detection of a photon
The arrival of a synchronizing signal
Each Int32 record can be treated like following C-style struct:
struct {
unsigned TimeTag :16;
unsigned Channel :12;
unsigned Route :2;
unsigned Valid :1;
unsigned Reserved :1; } TTTRrecord;
Whether we are dealing with a photon record or a sync event, time
tag will always hold the time of the event relative to the start of
the experiment (macro-time).
If a record is a photon, valid == 1.
If a record is a sync signal or something else, valid == 0.
If a record is a sync signal, sync type = channel & 7 will give either a value indicating start of frame or end of scan line in a frame.
The last relevant bit of info is that Timetag is 16 bit and thus obviously limited. If the Timetag counter rolls over, the rollover counter is incremented. This rollover (overflow) count can easily be obtained from channel overflow = Channel & 2048.
My Goal
These records come in from a high speed scanning microscope and I would like to use these records to reconstruct images from the recorded photon data, preferably at 60 FPS.
To do so, I obviously have all the info:
I can look over all available data, find all overflows, which allows me to reconstruct the sequential macro time for each record (photon or sync).
I also know when the frame started and when each line composing the frame ended (and thus also how many lines there are).
Therefore, to reconstruct a bitmap of size noOfLines * noOfLines I can process the bulk array of records line by line where each time I basically make a "histogram" of the photon events with edges at the time boundary of each pixel in the line.
Put another way, if I know Tstart and Tend of a line, and I know the number of pixels I want to spread my photons over, I can walk through all records of the line and check if the macro time of my photons falls within the time boundary of the current pixel. If so, I add one to the value of that pixel.
This approach works, current code in the repo gives me the image I expect but it is too slow (several tens of ms to calculate a frame).
What I tried already:
The magic happens in the function int[] Renderline (see repo).
public static int[] RenderlineV(int[] someRecords, int pixelduration, int pixelCount)
{
// Will hold the pixels obviously
int[] linePixels = new int[pixelCount];
// Calculate everything (sync, overflow, ...) from the raw records
int[] timeTag = someRecords.Select(x => Convert.ToInt32(x & 65535)).ToArray();
int[] channel = someRecords.Select(x => Convert.ToInt32((x >> 16) & 4095)).ToArray();
int[] valid = someRecords.Select(x => Convert.ToInt32((x >> 30) & 1)).ToArray();
int[] overflow = channel.Select(x => (x & 2048) >> 11).ToArray();
int[] absTime = new int[overflow.Length];
absTime[0] = 0;
Buffer.BlockCopy(overflow, 0, absTime, 4, (overflow.Length - 1) * 4);
absTime = absTime.Cumsum(0, (prev, next) => prev * 65536 + next).Zip(timeTag, (o, tt) => o + tt).ToArray();
long lineStartTime = absTime[0];
int tempIdx = 0;
for (int j = 0; j < linePixels.Length; j++)
{
int count = 0;
for (int i = tempIdx; i < someRecords.Length; i++)
{
if (valid[i] == 1 && lineStartTime + (j + 1) * pixelduration >= absTime[i])
{
count++;
}
}
// Avoid checking records in the raw data that were already binned to a pixel.
linePixels[j] = count;
tempIdx += count;
}
return linePixels;
}
Treating photon records in my data set as an array of structs and addressing members of my struct in an iteration was a bad idea. I could increase speed significantly (2X) by dumping all bitfields into an array and addressing these. This version of the render function is already in the repo.
I also realised I could improve the loop speed by making sure I refer to the .Length property of the array I am running through as this supposedly eliminates bounds checking.
The major speed loss is in the inner loop of this nested set of loops:
for (int j = 0; j < linePixels.Length; j++)
{
int count = 0;
lineStartTime += pixelduration;
for (int i = tempIdx; i < absTime.Length; i++)
{
//if (lineStartTime + (j + 1) * pixelduration >= absTime[i] && valid[i] == 1)
// Seems quicker to calculate the boundary before...
//if (valid[i] == 1 && lineStartTime >= absTime[i] )
// Quicker still...
if (lineStartTime > absTime[i] && valid[i] == 1)
{
// Slow... looking into linePixels[] each iteration is a bad idea.
//linePixels[j]++;
count++;
}
}
// Doing it here is faster.
linePixels[j] = count;
tempIdx += count;
}
Rendering 400 lines like this in a for loop takes roughly 150 ms in a VM (I do not have a dedicated Windows machine right now and I run a Mac myself, I know I know...).
I just installed Win10CTP on a 6 core machine and replacing the normal loops by Parallel.For() increases the speed by almost exactly 6X.
Oddly enough, the non-parallel for loop runs almost at the same speed in the VM or the physical 6 core machine...
Regardless, I cannot imagine that this function cannot be made quicker. I would first like to eke out every bit of efficiency from the line render before I start thinking about other things.
I would like to optimise the function that generates the line to the maximum.
Outlook
Until now, my programming dealt with rather trivial things so I lack some experience but things I think I might consider:
Matlab is/seems very efficient with vectored operations. Could I achieve similar things in C#, i.e. by using Microsoft.Bcl.Simd? Is my case suited for something like this? Would I see gains even in my VM or should I definitely move to real HW?
Could I gain from pointer arithmetic/unsafe code to run through my arrays?
...
Any help would be greatly, greatly appreciated.
I apologize beforehand for the quality of the code in the repo, I am still in the quick and dirty testing stage... Nonetheless, criticism is welcomed if it is constructive :)
Update
As some mentioned, absTime is ordered already. Therefore, once a record is hit that is no longer in the current pixel or bin, there is no need to continue the inner loop.
5X speed gain by adding a break...
for (int i = tempIdx; i < absTime.Length; i++)
{
//if (lineStartTime + (j + 1) * pixelduration >= absTime[i] && valid[i] == 1)
// Seems quicker to calculate the boundary before...
//if (valid[i] == 1 && lineStartTime >= absTime[i] )
// Quicker still...
if (lineStartTime > absTime[i] && valid[i] == 1)
{
// Slow... looking into linePixels[] each iteration is a bad idea.
//linePixels[j]++;
count++;
}
else
{
break;
}
}
Okay so I have created this vending machine application form and I am having problems getting rid of the change. The machine has 50 10p's in at the start of the day. A fizzy drink costs 40p, so, if the user puts in 50p, he will get change back of 10p. I have a textbox showing the amount of 10p's in the machine, so at the start, 50, after he puts in 50p it will be 55. However, now that he has to get 10p change (I have a release change button), I want the amount of 10p's in the textbox to go to 54...any ideas? I tried using the mod operator but wasn't sure how to use it:
decimal change = decimal.Parse(txtChange.Text)
if (change % 10 > 1)
{
int tenPenny = int.Parse(txt_BoxTenPenny.Text);
int totalTenPen = tenPenny - 1;
txt_BoxTenPenny.Text = totalTenPen.ToString();
}
I know this isn't right, when I was doing research, they were using the % operator and using the number 10 as the numerator..so..I got a bit lost. Any suggestions would be great!
If you're trying to determine how many 10 pennies the user is owed, this is calculated using:
int tenPennies = change / 10
As opposed to the modulus (%) operator, so:
decimal change = decimal.Parse(txtChange.Text)
int tenPenny = int.Parse(txt_BoxTenPenny.Text);
int totalTenPen = tenPenny - change / 10 ;
txt_BoxTenPenny.Text = totalTenPen.ToString();
Hope that helps!
Something like that:
decimal change = decimal.Parse(txtChange.Text)
if (change % 10 > 0)
{
int tenPenny = int.Parse(txt_BoxTenPenny.Text);
int totalTenPen = tenPenny - (change % 10);
txt_BoxTenPenny.Text = totalTenPen.ToString();
}
But is supposed that before that, you have added the 50p the users puts into machine in the txt_BoxTenPenny.
The modulo operator (%) returns the remainder of a division operation. For example, 23 MOD 10 = 3.
In this case I believe you want integer division, or the Floor. That is, you want to divide and throw away the remainder.
Since you are using decimal, I presume change will contain 0.10 for 10p. In that case, try the following:
//calculate the number of 10p coins you will get for change
var tenPenniesChange = (int)Math.Floor(change / 0.10m);
if(tenPenniesChange > 0)
txt_BoxTenPenny.Text = (int.Parse(txt_BoxTenPenny.Text) - tenPenniesChange).ToString();
change -= tenPenniesChange * 0.10;
Note the use of the Math.Floor function. If you had change = 0.13 you will get tenPenniesChange = 1. After the subtraction, you will then get change = 0.03.
This may be of some use:
Issuing vending machine change: Using C# to recursively build and search a tree
Okay so I have a datetime x-axis on an MSChart. I want to plot months below the first of each month and years below the change of a year. Here's what I have so far:
for (int i = 0; i < rdate.Length -1 ; i++)
{
if (rdate[i].Day == 01 && set == 0)
chart1.ChartAreas[0].AxisX.CustomLabels.Add(
rdate[i].AddDays(-20).ToOADate(), rdate[i].AddDays(20).ToOADate(),
Convert.ToString(rdate[i].ToString("MMMM")), 1, LabelMarkStyle.None);
set = 1;
if (rdate[i].Day > 01)
set = 0;
i++;
if (rdate[i].Year > rdate[i-1].Year)
chart1.ChartAreas[0].AxisX.CustomLabels.Add(
rdate[i].AddDays(-20).ToOADate(), rdate[i].AddDays(20).ToOADate(),
Convert.ToString(rdate[i].ToString("yyyy")), 2, LabelMarkStyle.None);
}
However for some reason this skips some months... The years do not show up at all.
rdate is a datetime array used to populate the x axis.
Here is an example of what my code does:
As you can see, the labels are behaving unexpectedly. I would also like to show a larger tick mark for these dates, and reduce the number of day labels based upon the date range, but I'm at a loss. Anyone done this sort of thing before?
I recently had a similar issue with MSChart when adding too many labels to the x-axis. The solution was reduce the number of ticks without losing data.
This approach worked for me but you will have to adapt it to your specific needs.
dataSeries.XValueType = ChartValueType.Auto;
dataSeries.Points.AddXY(record.DateTime, value);
I then determined the min and max dates for the given data to determine the preferred interval, your implementation will vary:
var totalDays = (maxDate.Value - minDate.Value).TotalDays;
if (totalDays < 60)
chartArea.AxisX.IntervalType = DateTimeIntervalType.Days;
else if (totalDays < 120)
chartArea.AxisX.IntervalType = DateTimeIntervalType.Weeks;
else
chartArea.AxisX.IntervalType = DateTimeIntervalType.Months;
Specify the AxisX label format:
In your case you might have to change the Format together with the interval.
chartArea.AxisX.LabelStyle.Format = Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern;
Hopefully there are some key parts that will provide value for you but you still have to modify it for your particular needs.
I have a particular application that needs to calculate something very specific, and while I excel at logic, math has always been my weak spot.
Given a number, say -20, it needs to apply a calculation of a 100 base (that is, the base is 100, not 0. not to be confused with base 100 which would be something else totally).
In other words, the math works like this ..., 105, 104, 103, 102, 101, 100, -101, -102, -103, -104, -105, ...
Then I need to do the math based on this 100 base figure.
So, for example:
-140 - 20 = 120
-120 - 20 = 100
-115 - 20 = -105
-110 - 20 = -110
-105 - 20 = -115
100 - 20 = -120
120 - 20 = -140
If it helps, the problem is related to sports odds. In theory, this refers to money (risk $1.40 to win $1.00 on one side, risk $1.00 to win $1.20 on the other, the .20 difference is what casinos call "the juice" or their cut of moving money back and forth.) However, the program is not dealing with real money, it's more of a simulator.
My current formula works like this:
decimal CalculateSides(decimal side, decimal vig)
{
decimal newSide = side - vig;
newSide = -(newSide < 0) ? newSide + 100 : newSide - 100;
return (newSide < 0) ? newSide + 100 : newSide - 100;
}
While this formula works, I'm not very happy with the conditional +/-, but this is basically the only formula that works for me.
Can anyone suggest a way to improve this? Preferably without conditions of +/-?
EDIT:
When I asked the question, I knew one possible answer was "It's probably best the way you're doing it", and that seems to be the consensus.
One sensible way to handle this would be to compute internally with ordinary numbers which go from positive to negative at zero, and only add/subtract 100 for presentation.
I strongly suspect that your sample function is broken.
Is it a copy paste or did you retyped it ?
decimal CalculateSides(decimal side, decimal vig)
{
decimal newSide = side - vig;
newSide = -(newSide < 0) ? newSide + 100 : newSide - 100;
return (newSide < 0) ? newSide + 100 : newSide - 100;
}
Just try with CalculatesSides(115, 20) you get -95, unlikely to be what you want. (I I understand well result should be -105).
However what you where trying to write seems clear enough. I believe it should be:
decimal CalculateSides(decimal side, decimal vig)
{
decimal newSide;
side = (side < 0) ? side + 100 : side - 100;
newSide = side - vig;
return (newSide < 0) ? newSide - 100 : newSide + 100;
}
This is quite straightforward and won't be easy to optimize
change mode from 100base to 0base
compute in zero base
convert result base from 0base to 100base
You can do some tricks based on signs to avoid the tests as other suggested, but the result will be quite obfuscated and probably slower.
My advice would be to leave it that way.
Optimization is generally done to make something run faster. Have you actually found that your code is not running fast enough? I suspect not.
If your code generates the right results and does it in such a way that it doesn't take a great deal of time, leave it alone, and concentrate on other code that's an actual rather than a perceived, problem.
If you're just worried about the way it looks, add some comments to explain how it works. You would most likely have to do that anyway with a one-formula solution so you may as well not waste your effort.
The 'sign' solution could be more elegant:
decimal CalculateSides(decimal side, decimal vig)
{
decimal res = side - vig + (100 * Math.Sign(side));
return res + (100 * Math.Sign(res));
}
please note that your algorithm doesn't apply to your given examples.