How to set an axis range bigger than value range in devexpress - c#

I'm trying to set a rangbar chart in devexpress to show the task's range time.
rangeBarChart.Series.Clear();
Series series = new Series("S1", ViewType.RangeBar);
series.ValueScaleType = ScaleType.DateTime;
DateTime stime = Convert.ToDateTime("2019-08-29 8:00");
DateTime etime = Convert.ToDateTime("2019-08-29 12:00");
SeriesPoint point = new SeriesPoint("task1", stime, etime);
series.Points.Add(point);
rangeBarChart.Series.Add(series);
((XYDiagram)rangeBarChart.Diagram).Rotated = true;
DateTime rangestime = Convert.ToDateTime("2019-08-29 8:00");
DateTime rangeetime = Convert.ToDateTime("2019-08-29 18:00");
((XYDiagram)rangeBarChart.Diagram).AxisY.VisualRange.Auto = false;
((XYDiagram)rangeBarChart.Diagram).AxisY.VisualRange.SetMinMaxValues(rangestime, rangeetime);
I want the AxisY ranges from 8:00 - 18:00 although the point range from 8:00 to 12:00.
However, the code runs like this
How can I make an axis range bigger than value's range

To specify the overall range of Series associated with the axis you should use the WholeRange property instead of the VisualRange:
((XYDiagram)rangeBarChart.Diagram).AxisY.WholeRange.Auto = false;
((XYDiagram)rangeBarChart.Diagram).AxisY.WholeRange.AutoSideMargins = false;
((XYDiagram)rangeBarChart.Diagram).AxisY.WholeRange.SetMinMaxValues(rangestime, rangeetime);
Take a look at the Visual Ranges and Whole Ranges article for details.

Related

How to add minor tick marks in MS Chart in C# Windows Form?

How to add minor tick marks in MS Chart in Windows Form.
I am using below code but minor tick marks are not showing up.
chart.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
chart.ChartAreas[0].AxisX.MajorGrid.Interval = 1;
chart.ChartAreas[0].AxisX.MajorGrid.IntervalType = DateTimeIntervalType.Seconds;
chart.ChartAreas[0].AxisX.MinorTickMark.IntervalType = DateTimeIntervalType.Number;
chart.ChartAreas[0].AxisX.MinorTickMark.Interval = 2;
Please help me.
The way you turn on MinorTickMarks as such is fine.
But if you want to use different IntervalTypes you need to understand the numeric values behind the types.
Internally all values, both x- and y-values are defined and stored as doubles.
If you declare some of them to be DateTimes they get converted to double (and when necessary back to DateTime) by the conversion functions: double.ToOADate (and FromOADate).
Let's have a look at the values resulting for one second:
DateTime dt0 = DateTime.Now;
DateTime dt1 = dt0 .AddSeconds(1);
double d0 = dt0.ToOADate();
double d1 = dt1.ToOADate();
double dd = d1 - d0;
Console.WriteLine(d0 + " .. " + d1 + " => " + dd);
Output:
43612,4597045023 .. 43612,4597160764 => 1,15740695036948E-05
So, with such a tiny value an Interval of 1, as in your code, just won't happen within the chart. Best use a different type, like DateTimeIntervalType.Milliseconds with an suitable Interval, like 500..!

c# winforms chart shows values wrong [duplicate]

I try to draw Chart via C# with table as picture.
However, as you can see A4 data in date: 7 and 8/6 should stay with same 7 and 8/6 X-Axis, abnormal here all of them left to 5 & 6/6 X-Axis. Could you help me to fix it.
for (int i = 0; i < 14; i++)
{
string productname = dataGridView1.Rows[i].Cells[0].Value.ToString();
string datetime = dataGridView1.Rows[i].Cells[2].Value.ToString();
int para = Convert.ToInt16(dataGridView1.Rows[i].Cells[1].Value);
if (chart_dashboard.Series.IndexOf(productname) != -1)
{
chart_dashboard.Series[productname].Points.AddXY(datetime, para);
chart_dashboard.ChartAreas[0].AxisX.Interval = 1;
}
else
{
chart_dashboard.Series.Add(productname);
chart_dashboard.Series[productname].Points.AddXY(datetime, para);
chart_dashboard.ChartAreas[0].AxisX.Interval = 1;
}
}
A common mistake.
string datetime = dataGridView1.Rows[i].Cells[2].Value.ToString();
This is wrong! If you add the x-values as strings they all are added as 0 and the Series can't align them to the proper slots on the X-Axis. So they get added from left to right sequentially..
Instead simply add the x-values as the DateTimes they are supposed to be!
So if the Cells contain DateTime values use:
DateTime datetime = (DateTime) dataGridView1.Rows[i].Cells[2].Value;
If they don't, convert them to DateTime
DateTime datetime = Convert.ToDateTime(dataGridView1.Rows[i].Cells[2].Value);
To control the x-values type set the XValueType for each series:
chart_dashboard.Series[yourSeries].XValueType = ChartValueType.DateTime;
To control the way the axis labels are displayed set their formatting:
chart_dashboard[ChartAreas[0].AxisX.LabelStyle.Format = someDateTimeFormatString;
To create a string like "Week 1" you would
set the XValueType to int16
add the x-value as the week numbers
format it like ..axis.LabelStyle.Format = "Week #0";
To extract the number from your data split by space and Convert.ToInt16 !
If one really needs to insert sparse x-values as strings one would have to insert a dummy DataPoint at each gap in a series.
Creating a dummy DataPoint is simple:
DataPoint dp = new DataPoint() { IsEmpty = true};
But knowing where the gaps are in advance is the challenge! The 'best' way is to go over the data and filling in the before adding the points. Or go over it later and instead of adding, inserting the dummys at the gaps. Both is a lot more trouble than getting the data right in the first place!

Datetime type X axis on MS Chart control without showing weekends

I'm using the MS Chart control in .Net 4 to display 4 data series, the X axis is set to datetime type.
with the interval set to days the graph includes weekend even though no weekend dates are included in the data.
All the series except one have the same date points, the exception is a projection line that starts on the last date and continues for a number of working days (excludes weekends).
How can remove the display of weekends (or dates that have no value) from the chart for all series?
this is a winforms .Net 4.0 Application.
foreach (var series in chart2.Series)
{
series.ChartType = SeriesChartType.Line;
series.BorderWidth = 5;
series.XValueType = ChartValueType.Date;
// I Tried this to remove weekends but it results in the graph showing a big red X
series.IsXValueIndexed = true;
}
Edit with Code to reproduce my issue below:
DateTime dt = DateTime.Now;
chart1.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Days;
Series test1 = new Series("Test1");
test1.XValueType = ChartValueType.Date;
for (int i = 1; i < 7; i++)
{
//skip the weekend
if (dt.DayOfWeek.ToString() == "Saturday") dt = dt.AddDays(1);
if (dt.DayOfWeek.ToString() == "Sunday") dt = dt.AddDays(1);
test1.Points.AddXY(dt.Date, i);
dt = dt.AddDays(1);
i++;
}
chart1.Series.Add(test1);
Series test2 = new Series("Test2");
test1.XValueType = ChartValueType.Date;
for (int i = 1; i < 7; i++)
{
//skip the weekend
if (dt.DayOfWeek.ToString() == "Saturday") dt = dt.AddDays(1);
if (dt.DayOfWeek.ToString() == "Sunday") dt = dt.AddDays(1);
test2.Points.AddXY(dt.Date, i);
dt = dt.AddDays(1);
i++;
}
chart1.Series.Add(test2);
foreach (var series in chart1.Series)
{
series.ChartType = SeriesChartType.Line;
series.BorderWidth = 5;
series.IsXValueIndexed=true;
}
chart1.ChartAreas[0].AxisX.LabelStyle.Angle = 45;
chart1.ChartAreas[0].AxisX.LabelStyle.Interval = 1;
You are adding the x-values as DateTime, which is what you should do. But by default this means the all x-values are positionend proportionally, as one usually wants them to be.
But your case is an exception, that is even mentioned in the documentation of the Series.IsXValueIndexed property:
All data points in a series use sequential indices, and if this
property is true then data points will be plotted sequentially,
regardless of their associated X-values. This means that there will be
no "missing" data points.
For example, assume there are three (3) data points in a series having
X-values of 1, 2 and 4. If this property was false, there would be a
data point missing at the X-axis location labeled "3". However, if you
set this property to true, the three data points will be plotted at
points 1, 2, and 4, sequentially, and there will be no missing data
point. The X-axis location labeled "3" will not appear on the chart.
This is useful when you do not want to have missing data points for
intervals that you know you will not have data for, such as weekends.
Note however:
If you are displaying multiple series and at least one series uses
indexed X-values, then all series must be aligned — that is, have the
same number of data points—and the corresponding points must have the
same X-values.
So you were correct in using this property, however, most likely, your series were not fully aligned.
To make sure they are one often can make use of one of the Chart.DataManipulator.InsertEmptyPoints overloads. Unfortunately they all work with a fixed Interval, not with a template Series.
So you will need to makes sure to add one Empty DataPoint wherever your data are missing a value in a Series. If the data are databound you will have to do that in the DataSource!

Time Trackbar or Very Large Values using Trackbar

I am writing a vehicle tracking application using GMAP.NET
I want to display simultaneous movement of multiple vehicle markers based on date/time.
For this, I would like to use a Trackbar such that when the User slides the trackbar, the corresponding movement of multiple markers is shown.
I did the same application on the browser and it worked very well. I converted the datetime attribute of the marker tag to a UNIX Timestamp and then set the trackbar (NOUI Slider) values to the the UNIX Timestamp range.
But, Now I find that I cannot do this at all with the Windows Desktop C# Trackbar.
The problems are:
The trackbar is unable to take very large timestamp values. Eg. 5 years data.
Even after reducing the very large numbers, the trackbar still cannot take such high values and keeps lagging or crashing.
Eg. I need to show data for 5 years. In this case, my trackbar would have minimum value - 1262304000 (i.e. 01-01-2010) to 1425203100 (i.e. 01-03-2015 | 09:45).
But such large values just don't work with my trackbar.
I have even taken reduction eg. setting 1262304000 as 1 and then 162899100 (i.e. 1425203100 - 1262304000) becomes my maximum value.
But even this is very intensive and the trackbar does not work.
Please suggest if there is a time-trackbar which can show very a large datetimerange or how I can use a regular trackbar with very large values.
The code as follows -
A. The function to convert datetime to a UNIX Timestamp
public Int32 UnixTimeStampUTC(DateTime datetime)
{
Int32 unixTimeStamp;
DateTime zuluTime = datetime.ToUniversalTime();
DateTime unixEpoch = new DateTime(1970, 1, 1).ToUniversalTime();
unixTimeStamp = (Int32)(zuluTime.Subtract(unixEpoch)).TotalSeconds;
return unixTimeStamp;
}
B. Taking the DateTime from a DataTable by Concatenating Date & Time Columns and Adding a third Column to hold the Unix TimeStamp of the DateTime Column
for (int z = 0; z < dt.Rows.Count; z++)
{
if (reviseddt.Rows[z]["date"].ToString() != "")
{
dte = DateTime.Parse(reviseddt.Rows[z]["date"].ToString());
dteticks = UnixTimeStampUTC(dte);
}
else
{
dteticks = 0;
}
if (reviseddt.Rows[z]["time"].ToString() != "")
{
tm = DateTime.Parse(reviseddt.Rows[z]["time"].ToString());
tmticks = UnixTimeStampUTC(tm);
}
else
{
tmticks = 0;
}
Int32 fullDt = dteticks + tmticks;
reviseddt.Rows[z]["datetime"] = fullDt.ToString();
reviseddt.Rows[z]["datetimestring"] = reviseddt.Rows[z]["date"].ToString() + reviseddt.Rows[z]["time"].ToString();
C. Initalising the Trackbar by Getting the min and max values from the datetime column in the datatable and then taking the range as the difference between the min and max values. Hence, Trackbar range = 1 to (Max-Min)
string strminlevel = toplotDataTable.Compute("min(datetime)", String.Empty).ToString();
string strmaxLevel = toplotDataTable.Compute("max(datetime)", String.Empty).ToString();
Int32 minLevel = Convert.ToInt32(strminlevel);
Int32 maxLevel = Convert.ToInt32(strmaxLevel);
Int32 rangeint = maxLevel - minLevel;
trackBarMoveTarget.Maximum = rangeint;
trackBarMoveTarget.Minimum = 1;
trackBarMoveTarget.LargeChange = 100;
trackBarMoveTarget.SmallChange = 1;
There are two problems with using TrackBar at this kind of scale.
First you need to be able to move the track bar left and right, but if the SmallChange and LargeChange properties are too small then you may be making a lot of progress, but it simply doesn't show on the track bar. Try this for a start:
trackBarMoveTarget.Maximum = rangeint;
trackBarMoveTarget.Minimum = 1;
trackBarMoveTarget.LargeChange = rangeint / 50;
trackBarMoveTarget.SmallChange = rangeint / 200;
The other problem is that the TrackBar control tries to render helpful little tick marks along its length. By default the TickFrequency is 1 and the Maximum value is 10. When You set Maximum to 162899100 without changing TickFrequency then the poor TrackBar control has to try and render 162899100 tick marks and that takes a long time. Try this:
trackBarMoveTarget.TickFrequency = rangeint / 100;
Be realistic - the trackbar only has a resolution down to 1 pixel - most displays are, at the most 1920 pixels wide. Therefore the resolution only has to be 1920 - let's round it up to 2000.
Now you have a 5 year period = 5 * 365 + 1 (for the odd leap year) = 1826. This is almost equal to our original 2000 odd. So let's make it 1826.
So set the Minimum value to 0 and the Maximum to 1826.
When you get the track event you take the first date 01-01-2010 and add the value of the trackbar to it:
var firstDate = new DateTime(2010, 1, 1).Date;
var trackDate = firstDate + TimeSpan.FromDays(trackBar.Value);
easy and quick.

Calculate time in asp.net

I am using sql server to store employee lunch in and out time and calculating difference using asp.net as below. Now i want to see if they exceed 30 mins then value should be in red color.
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Lunch Total Time
Label lunIn = (Label)e.Row.FindControl("lblLunIn");
Label lunOut = (Label)e.Row.FindControl("lblLunOut");
Label lunTotal = (Label)e.Row.FindControl("lblLunTotal");
lunTotal.Text = Convert.ToString(Convert.ToDateTime(lunOut.Text) - Convert.ToDateTime(lunIn.Text));
}
How should i go about it? Thanks
In general i would prefer to use the real data-source instead of the text in the GridViewRows. You can get it easily in RowDataBound via e.Row.DataItem. On that way you prevent localization issues and your work with the original data.
However, to get the time in minutes from two DateTimes you can subtract them and use the returned TimeSpans TotalMinutes property:
DateTime dtIn = Convert.ToDateTime(lunIn.Text);
DateTime dtOut = Convert.ToDateTime(lunOut.Text);
TimeSpan duration = dtOut - dtin;
lunTotal.Text = duration.ToString();
if(duration.TotalMinutes > 30)
{
e.Row.BackColor = Color.Red;
// or maybe you just want to change the color of the Label
lunTotal.ForeColor = Color.Red;
}

Categories