How to add negative timestamps to TeeChart X axis with C#? - c#

I have data with relative timestamp (as TimeSpan). Example:
RelativeTimestamp (hh:mm) | Data1 | Data2
-00:03 2.2 1.3
-00:01 2.5 1.5
00:00 2.4 1.6
00:02 2.7 1.7
00:08 2.1 1.9
I want to make a TeeChart with C# that draws these series of data. However when I try
series.Add(row["RelativeTimestamp"], row["Data1"]);
It complains that I cannot use TimeStamp on horizontal axis. So I also tried converting it to DateTime with
DateTime RelativeTimestamp_DT = row["RelativeTimestamp"] + (new DateTime(1970,1,1));
but, of course, this makes the series of timestamps to become 23:57, -23:59 etc instead of anything negative.
So, how can I make negative timestamp labels on X axis?
We can assume that relative timestamp is no larger than 24 hours positive or negative.

The easiest solution I can think of is using text labels based on a TimeSpan, for example:
var line1 = new Steema.TeeChart.Styles.Line(tChart1.Chart);
var y = new Random();
for (int i = -20; i < 20; i++)
{
var referenceTime = DateTime.Today.AddDays(1);
var currentTime = DateTime.Now.AddHours(i);
var timeSpan = referenceTime - currentTime;
var label = timeSpan.ToString(#"h\h\:m\m");
label = (currentTime < referenceTime) ? "-" + label : label;
line1.Add(y.Next(), label);
}
tChart1.Axes.Bottom.Labels.Angle = 90;
Which produces this chart:

I ended up using Series.Add(DateTime X, double Y, string Label), which existence I didn't notice at first. This is nice because I can put the data to right position on X axis, but give it a custom label, even when timestamps are unequally distributed:
foreach (DataRow in data.Rows) {
DateTime RelativeTimestamp_DT = DateTime.MinValue + row["RelativeTimestamp"];
string label = row["RelativeTimestamp"].ToString(#"hh\:mm");
if (row["RelativeTimestamp"] < new TimeSpan(0)) {
label = "-" + label;
}
series.Add(row["RelativeTimestamp"], row["Data1"], label);
series.Add(row["RelativeTimestamp"], row["Data2"], label);
}

Related

How to get Pixel Position from DateTime Value on X-Axis?

I'm trying to retrieve the pixel position on the chart of a DataPoint using its X Value (DateTime).
I'm using this code after the Chart has been painted but I get a very large number:
DateTime date = ... ; // DateTime of the DataPoint, I verified the date is correct and the chart contains it.
var pixelsPosition = ChartAreas[0].AxisX.ValueToPixelPosition(date.ToOADate());
// Here pixelsPosition is a very large number, above 600 000.
These are the Chart settings:
Series[0].XValueType = ChartValueType.DateTime;
Series[0].IsXValueIndexed = true;
The Chart has around 2000 Points.
I'm using the same code to retrieve a pixel position of a DataPoint using the Y Value and it works. I'm sure it's a stupid problem but I can't figure it out.
Working code for the Y-Axis
double yValue = 100;
double pixPositionY = ChartAreas[0].AxisY.ValueToPixelPosition(yValue); // THIS WORKS
What am I doing wrong?
EDIT:
I read that the method ValueToPixelPosition works only on Paint Events, I've tried to execute it on the Paint and PrePaint events but I get the same error.
I have found the solution to my problem:
DateTime date;
int pixelPositionX = 0;
var point = Series[0].Points.Where(X => X.XValue == date.ToOADate()).FirstOrDefault();
var index = (point != null) ? Series[0].Points.IndexOf(point) : -1;
if (index > -1)
pixelPositionX = (int)ChartAreas[0].AxisX.ValueToPixelPosition(index + 1);
That gives me the correct position of the DataPoint on the screen. ValueToPixelPosition works if I pass the dataPoint index as parameter rather than the datetime value converted to OADate. I'm not sure if this is the right solution but it's working for me.
I have the same problem, but your solution is surely wrong. ValueToPixelPosition() requires a double value and not an index. Apart from that your workaround is very slow because it must search through all DateTime values on X axis.
To find out how Microsoft generates these strange X values I used ILSpy to disassemble System.Windows.Forms.DataVisualization.ni.dll which can be found in C:\Windows\assembly\....
Here is the Microsoft code which converts DateTime into double:
// System.Windows.Forms.DataVisualization.Charting.DataPoint
public void SetValueXY(object xValue, params object[] yValue)
{
.......
else if (type == typeof(DateTime))
{
_xValue = ((DateTime)xValue).ToOADate();
}
........
if (series != null && xValue is DateTime)
{
if (series.XValueType == ChartValueType.Date)
{
DateTime dateTime = new DateTime(((DateTime)xValue).Year, ((DateTime)xValue).Month, ((DateTime)xValue).Day, 0, 0, 0, 0);
_xValue = dateTime.ToOADate();
}
else if (series.XValueType == ChartValueType.Time)
{
DateTime dateTime2 = new DateTime(1899, 12, 30, ((DateTime)xValue).Hour, ((DateTime)xValue).Minute, ((DateTime)xValue).Second, ((DateTime)xValue).Millisecond);
_xValue = dateTime2.ToOADate();
}
}
.....
If you use ChartValueType.Time the double value on X axis is between 0.0 (for 00:00:00.000) and 1.0 (for 23:59:59.999)
I don't like the Microsoft code using a date from 1899.
This can be done easier:
int s32_Millis = (((k_Time.Hour*60) +k_Time.Minute)*60 +k_Time.Second)*1000 +k_Time.Millisecond;
double d_OaTime = (double)s32_Millis / (24*60*60*1000);
double d_PixelPosX = ChartAreas[0].AxisX.ValueToPixelPosition(d_OaTime);

Convert seconds to hhh:mm:ss in a chart

I have a MsSql database which calculates the timespan between two dates in seconds. That works fine. I use this column afterwards in C# and write them in an array.
This array is the input for a chart later on.
So far this works well, but I cannot find a way to display the seconds in a format like hhh:mm:ss as the timespan can be greater than 24h.
I tried ChartArea.AxisY.LabelStyle.Format = "hhmmss"; but it does not work at all.
Does anybody has an idea how I could do that?
EDIT:
I add the data this way:
chart2.Series.Clear();
chart2.ChartAreas.Clear();
Series BoxPlotSeries = new Series();
ChartArea ChartArea2 = new ChartArea();
ChartArea ChartArea3 = new ChartArea();
chart2.ChartAreas.Add(ChartArea2);
chart2.ChartAreas.Add(ChartArea3);
ChartArea2.Name = "Data Chart Area";
ChartArea3.Name = "BoxPlotArea";
BoxPlotSeries.Name = "BoxPlotSeries";
BoxPlotSeries.ChartType = SeriesChartType.BoxPlot;
BoxPlotSeries.ChartArea = "BoxPlotArea";
chart2.Series.Add(BoxPlotSeries);
Series Input1 = new Series();
Input1.Name = "Input1";
Input1.ChartType = SeriesChartType.Point;
Input1.ChartArea = "Data Chart Area";
chart2.Series.Add(Input1);
chart2.Series["Input1"].Points.DataBindY(InputArray);
chart2.ChartAreas["BoxPlotArea"].AxisX.CustomLabels.Add(2, 0.0, "BoxPlot1");
chart2.Series["BoxPlotSeries"]["BoxPlotSeries"] = "Input1";
chart2.Series["BoxPlotSeries"]["BoxPlotShowMedian"] = "true";
chart2.Series["BoxPlotSeries"]["BoxPlotShowUnusualValues"] = "false";
chart2.Series["BoxPlotSeries"]["PointWidth"] = "0.5";
chart2.Series["BoxPlotSeries"].IsValueShownAsLabel = false;
ChartArea2.Visible = false;
ChartArea3.BackColor = Color.FromArgb(224,224,224);
//I tried to format it this way but it didn't work
//ChartArea3.AxisY.LabelStyle.Format = "{0:HHHmmss}";
chart2.ChartAreas["BoxPlotArea"].AxisX.LabelStyle.Angle = -90;
EDIT2:
And here's how I populate the input array
int[] InputArray = new int[1000000];
int c = 0;
con.Open();
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
int n;
if (int.TryParse(dr[0].ToString(),out n) == true)
{
InputArray[c] = Convert.ToInt32(dr[0].ToString());
c++;
}
}
}
if (c == 0) { c = 1; }
Array.Resize(ref InputArray, c - 1);
EDIT 3:
The Boxplot should look like this in the end:
In Excel the format to display hours greater than 24 is called "[h]:mm:ss;#"
EDIT4:
Thanks to #TAW I nearly managed to solve my problem. I made some adjustments to his solution and came up with this:
In the chart code block:
The Value "max" is set before.
ChartArea3.AxisY.MajorTickMark.Interval = addCustomLabels(ChartArea3, BoxPlotSeries, 60 * 60, max);
int addCustomLabels(ChartArea ca, Series series, int interval, int max)
{
int tickNo = 0;
ca.AxisY.CustomLabels.Clear();
if(max / interval > 10)
{
interval = (max / 10) - (max / 10) % (60*30);
tickNo = (max / 10) - (max / 10) % (60*30);
}
if (max / interval <= 2 )
{
interval = (max / 4) - (max / 4) % (60 * 15);
tickNo = (max / 4) - (max / 4) % (60 * 15);
}
for (int i = 0; i < max; i += interval)
{
CustomLabel cl = new CustomLabel();
cl.FromPosition = i - interval / 2;
cl.ToPosition = i + interval / 2;
cl.Text = hhh_mm_ss(i);
ca.AxisY.CustomLabels.Add(cl);
}
return tickNo;
}
My problem is now, that sometimes no axis lable (apart from 0:00) is shown even when the code runs through it without any problems.
Has anybody and idea what could be wrong?
Your task involves two parts:
displaying seconds in the hhh:mm:ss format
putting them as labels on the y-axis
There is no suitable date-time formatting string for this in c#, so we can't make use of the built-in automatic labels and their formatting.
There also no way to use expressions that call a function on the automatic labels, unfortunately.
So we can't use those.
Instead we will have to add CustomLabels. This is not very hard but does take a few steps..
But let's start with a function that converts an int to the hhh:mm:ss string we want; this should do the job:
string hhh_mm_ss(int seconds)
{
int sec = seconds % 60;
int min = ((seconds - sec)/60) % 60;
int hhh = (seconds - sec - 60 * min) / 3600;
return hhh > 0 ? string.Format("{2}:{1:00}:{0:00}", sec, min, hhh)
: min + ":" + sec.ToString("00");
}
Maybe it can be optimized, but for our purpose it'll do.
Next we need to create the CustomLabels. They will replace the normal axis labels and we need to add them in a separate loop over the data after each binding.
One special thing about them is their positioning. Which is smack between two values we need to give them: the FromPosition and ToPosition, both in the unit of the axis-values.
Another difference to normal, automatic Labels is that it is up to us to create as many or few of them as we need..
This function tries to create a number that will go up to the maximum y-value and space the CustomLabels at a given interval:
void addCustomLabels(ChartArea ca, Series series, int interval)
{
// we get the maximum form the 1st y-value
int max = (int)series.Points.Select(x => x.YValues[0]).Max();
// we delete any CLs we have
ca.AxisY.CustomLabels.Clear();
// now we add new custom labels
for (int i = 0; i < max; i += interval)
{
CustomLabel cl = new CustomLabel();
cl.FromPosition = i - interval / 2;
cl.ToPosition = i + interval / 2;
cl.Text = hhh_mm_ss(i);
ca.AxisY.CustomLabels.Add(cl);
}
}
The first parameters to call this are obvious; the last one however is tricky:
You need to decide to interval you want your labels to have. It will depend on various details of your chart:
the range of values
the size of the chart area
the size of the font of the axis
I didn't set any special Font in the function; CustomLabels use the same Font as normal axis labels, i.e. AxisY.LabelStyle.Font.
For my screenshot I prepared the chart like this:
ca.AxisX.Minimum = 0;
ca.AxisY.MajorTickMark.Interval = 60 * 60; // one tick per hour
addCustomLabels(ca, s, 60 * 30); // one label every 30 minutes
I have also added DataPoint Labels for testing to show the values..:
series.Points[p].Label = hhh_mm_ss((int)y) + "\n" + y;
Here is the result:
UPDATE: This answer may be quite useful for other readers, but it pretty much misses the OP's issues. I'll leave it as it stands, but it will not help in creating specially formatted y-axis labels..
Most Chart problems stem from invalid or useless x-values. The following discussion tries to help avoiding or getting around them..
A number is a number and you can't simply display it as a DateTime, or for that matter a TimeSpan.
So you need to add the X-Values as either DateTime or as double that contain values that can be converted to DateTime. The fomer is what I prefer..
So instead of adding the seconds directly add them as offsets from a given DateTime:
Change something like this
series.Points.AddXY(sec, yValues);
To this:
var dt = new DateTime(0).AddSeconds(sec);
series.Points.AddXY(dt, yValues);
Now you can use the date and time formatting strings as needed..:
chartArea.AxisX.LabelStyle.Format = "{mm:ss}";
You could also add them as doubles that actually are calculated from DateTimes via the ToOADate:
series.Points.AddXY(dt.ToOADate(), yValues);
But now you will have to set the ChartValueType.DateTime and probably also AxisX.IntervalType and AxisX.Interval to make sure the chart gets the formatting right..:
s.XValueType = ChartValueType.DateTime;
ca.AxisX.Interval = 5;
ca.AxisX.IntervalType = DateTimeIntervalType.Seconds;
ca.AxisX.LabelStyle.Format = "{mm:ss}";
Pick values that suit your data!
Note that the problem with your original code is that the X-Values internally always are doubles, but the seconds are not integer values in them but fractional parts; so you need some kind of calculation. That's what ToOADate does. Here is a short test that shows what one second actually does amount to as a OADate double :
Best add the X-Values as DateTimes so all further processing can rely on the type..
Update I just saw that you have finally added the real code to your question and that is uses Points.DataBindY. This will not create meaningful X-Values, I'm afraid. Try to switch to Points.DataBindXY! Of course the X-Values you bind to also need to follow the rules I have explained above..!
You can do a loop over your array and convert the numbers like I shown above; here is a simple example:
int[] seconds = new int[5] { 1, 3, 88, 123, 3333 };
double[] oaSeconds = seconds.Select(x => new DateTime(0).AddSeconds(x).ToOADate())
.ToArray();
If you are trying to show more than 2 digits of hour I think this should work for you
//yourTimeSpan is the TimeSpan that you already have
var hoursDouble = Math.Floor(yourTimeSpan.TotalHours);
string hours;
string minutes;
string seconds;
//check hours
if(hoursDouble < 10)
{
hours = string.Format("0{0}", hoursDouble);
}
else
{
hours = hoursDouble.ToString();
}
//check minutes
if (yourTimeSpan.Minutes < 10)
{
minutes = string.Format("0{0}", yourTimeSpan.Minutes);
}
else
{
minutes = yourTimeSpan.Minutes.ToString();
}
//check seconds
if (yourTimeSpan.Seconds < 10)
{
seconds = string.Format("0{0}", yourTimeSpan.Seconds);
}
else
{
seconds = yourTimeSpan.Seconds.ToString();
}
string formattedSpan = String.Format("{0}:{1}:{2}", hours, minutes, seconds);
Update: I think this should solve the problem you were seeing with single digit numbers

Different label types on one axis in chart

I'm using System.Windows.Forms.DataVisualization.Charting in my app and I want to add different label types on my X axis which is representing a timeline. For example, I want to use "HH:mm" format for labels but when it's 00:00 I'd like to show "dd.MM" format instead. I tried to add cutom labels but it has no effect at all.
var area = new ChartArea();
area.AxisX.LabelStyle.Format = "HH:mm";
area.AxisX.Interval = 1 / 24.0;
area.AxisX.CustomLabels.Add(1.0, DateTimeIntervalType.Days, "dd.MM");
Adding CustomLabels will help; however if you want them to show an individual format you will have to add them individually to each DataPoint!
Doing so is not quite as simple as one could wish for; there are several overloads but none is really easy to use. The simplest way, imo, is to use one with a FromPosition and a ToPosition; these should then to be set in a way that they hit right between the DataPoints; this way they will be centered nicely..
Note that as the X-Values are really DateTimes, but as always in a chart, converted to doubles we need to convert them back to DateTime for correct formatting and also use their values to calculate the middle or rather half an interval..
Here is an example:
// prepare the test chart..
chart1.ChartAreas.Clear();
ChartArea CA = chart1.ChartAreas.Add("CA1");
Random R = new Random(123);
chart1.Series.Clear();
CA.AxisX.MajorTickMark.Interval = 1;
Series S = chart1.Series.Add("S1");
S.Points.Clear();
S.ChartType = SeriesChartType.Column;
S.SetCustomProperty("PixelPointWidth", "10");
// some random data:
DateTime dt0 = new DateTime(2015, 05, 01);
for (int i = 0; i< 40; i++)
{
int p = S.Points.AddXY(dt0.AddHours(i), R.Next(100));
}
// each custom label will be placed centered in a range
// so we need an amount of half an interval..
// this assumes equal spacing..
double ih = (S.Points[0].XValue - S.Points[1].XValue) / 2d;
// now we add a custom label to each data point
for (int i = 0; i < S.Points.Count; i++)
{
DataPoint pt = S.Points[i];
string s = (DateTime.FromOADate(pt.XValue)).ToString("HH:mm");
bool midnite = s == "00:00";
if (midnite) s = DateTime.FromOADate(pt.XValue).ToString("dd.MM.yyyy");
CustomLabel CL = CA.AxisX.CustomLabels.Add(pt.XValue - ih, pt.XValue + ih, s);
CL.ForeColor = midnite ? Color.Blue : Color.Black;
}

Line Chart Graphical Alert

I currently have a line graph in my C# program, and I have a min and max variable. If any the graph ever exceeds the max, or goes below the min, is there any built in way of displaying on the graph (such as a dot at the point) that the limit was passed, and display the x/y values for that point?
int max = 2000;
int min = 2000;
for (int i = 0; i < dgvLoadedValues.RowCount - 1; i++)
{
DateTime x = Convert.ToDateTime(dgvLoadedValues.Rows[i].Cells[0].Value.ToString());
try
{
float y = float.Parse(dgvLoadedValues.Rows[i].Cells[e.ColumnIndex].Value.ToString());
chart1.Series["Series1"].Points.AddXY(x, y);
}
catch
{
Console.WriteLine("Unable to plot point");
}
}
Code above simply shows values taken from a datagridview and displaying it into a line graph
Thank you
Unfortunately there seems to be no way to define such an automatic alert.
But as you know just when the DataPoints are added or bound you can set a Marker where necessary.
Here is a loop that does it after the fact in one go, but of course you can just as well set the markers as you add the points..:
foreach (DataPoint dp in chart1.Series[0].Points)
{
if (dp.YValues[0] < max && dp.YValues[0] > min ) continue;
dp.MarkerStyle = MarkerStyle.Circle;
dp.MarkerColor = Color.Red;
}
Or in your case:
try
{
float y = float.Parse(dgvLoadedValues.Rows[i].Cells[e.ColumnIndex].Value.ToString());
int i = chart1.Series["Series1"].Points.AddXY(x, y);
if (y < min || y > max)
{
chart1.Series["Series1"].Points[i].MarkerStyle = MarkerStyle.Circle;
chart1.Series["Series1"].Points[i].MarkerColor = Color.Red;
}
}
To clear a marker you can set its MarkerStyle = MarkerStyle.None.
Of course you could easily give the min and max points different colors..
Here is an example with the simple circle style, but there are others including images..:
To add the values in a label use a format like this:
dp.Label = "(#VALX{0.0} / #VAL{0.0})" ;

ASP.Net Chart - Label With Extra Data Not Used In Chart?

I have an asp:Chart control and it is working great. I simply am passing it times (in millitary format) and then values that are average length in time of requests. The following code does what I need - almost (feel free to mark it up if I am going overboard for I am new to the chart control).
My data is in table for like the following:
Date by Hours 9:00 10:00 11:00 12:00 13:00 14:00 15:00 16:00 17:00 18:00
12/03/2010 8 43 53 55 33 46 51 60 50 9
Friday 1.773 1.337 1.242 1.239 1.340 1.191 1.479 1.223 1.178 1.516
Gives me a nice chart. My question is below this code:
List<double> yValues = new List<double>();
List<string> xValues = new List<string>();
// First and Last columns do not contain chartable data
for (int i = 1; i < dtResults.Columns.Count - 1; i++) {
double d;
if (double.TryParse(dtResults.Rows[1][i].ToString(), out d))
yValues.Add(d == 0 ? double.NaN : d);
else
yValues.Add(double.NaN);
} // foreach of the Average Time Values the chart
// foreach of the column names
for (int i = 1; i < dtResults.Columns.Count - 1; i++)
xValues.Add(dtResults.Columns[i].ColumnName);
this.Chart.Titles["Title1"].Text = string.Format(
"Average Request Time In Seconds On {0:MM/dd/yyyy} Between {1:HH} and {2:HH} In {3}",
this.DateRange.BeginDate.Value,
this.ucsTimePicker.BeginTime,
this.ucsTimePicker.EndTime,
this.SelectedSourceEnvironmentName
);
this.Chart.Series["Series1"].Points.DataBindXY(xValues, yValues);
this.Chart.Series["Series1"].ChartType = SeriesChartType.Line;
this.Chart.Series["Series1"].IsValueShownAsLabel = true;
this.Chart.Series["Series1"]["ShowMarkerLines"] = "true";
this.Chart.Series["Series1"].Label = "#VALY{0.000}"; // Make sure they have only 3 decimal places
this.Chart.ChartAreas["ChartArea1"].AxisX.IsMarginVisible = true;
this.Chart.ChartAreas["ChartArea1"].AxisX.Title = "Hours of the Day";
this.Chart.ChartAreas["ChartArea1"].AxisY.Title = "Time in Seconds";
// Handle styling when there is a Zero or missing value
this.Chart.Series["Series1"].EmptyPointStyle.Color = Color.Red;
this.Chart.Series["Series1"].EmptyPointStyle.BorderWidth = 3;
this.Chart.Series["Series1"].EmptyPointStyle.BorderDashStyle = ChartDashStyle.Dash;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerStyle = MarkerStyle.Diamond;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerColor = Color.Red;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerSize = 8;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerBorderColor = Color.Black;
this.Chart.Series["Series1"]["EmptyPointValue"] = "Zero";
There are labels showing (the decimal numbers in the table above) but what I want to do is have the label Also show the total number of requests which is the 2nd row of data in the table above. I was able to add the values to the chart with the code below:
for (int i = 1; i < dtResults.Columns.Count - 1; i++) {
int n;
if (int.TryParse(dtResults.Rows[0][i].ToString(), out n))
this.Chart.Series["Series1"].Points.AddY(n);
else
this.Chart.Series["Series1"].Points.AddY(0);
} // foreach of the Count of Request within the Hour values
That seemed to not throw any fits, but I couldn't access the values with the following adjustment:
this.Chart.Series["Series1"].Label = "#VALY{0.000}\n#VALY2{0}";
All I get is the original value (1.773) showing up twice.
So is there a way to add data to a Chart that is only for labeling purposes and then access it?
Okay, after no help here (which actually shocks me) I was able to figure it out with some help outside of this site. Essentially, I don't have to Add the "extra" data but I do have to modify each Label as opposed to just having the generic label like the following:
this.Chart.Series["Series1"].Label = "#VALY{0.000}"; // Make sure they have only 3 decimal places
I also had to take out the following line:
this.Chart.Series["Series1"].IsValueShownAsLabel = true;
So just for brevity, here is the entire code giving me the two line label where the first line shows the average (which is the actual chart data) and the second line is the count which is not in the data at all.
List<double> yValues = new List<double>();
List<string> xValues = new List<string>();
List<int> zValues = new List<int>();
// First and Last columns do not contain chartable data
for (int i = 1; i < dtResults.Columns.Count - 1; i++) {
double d;
if (double.TryParse(dtResults.Rows[1][i].ToString(), out d))
yValues.Add(d == 0 ? double.NaN : d);
else
yValues.Add(double.NaN);
} // foreach of the Average Time Values the chart
// foreach of the column names
for (int i = 1; i < dtResults.Columns.Count - 1; i++)
xValues.Add(dtResults.Columns[i].ColumnName);
this.Chart.Titles["Title1"].Text = string.Format(
"Average Request Time In Seconds On {0:MM/dd/yyyy} Between {1:HH} and {2:HH} In {3}",
this.DateRange.BeginDate.Value,
this.ucsTimePicker.BeginTime,
this.ucsTimePicker.EndTime,
this.SelectedSourceEnvironmentName
);
this.Chart.Series["Series1"].Points.DataBindXY(xValues, yValues);
/// This loop will setup the point labels in a two line format where the first line displays
/// the Average that the point is actually showing. The second line is data taken from the
/// results table and is not a part of the chart at all but is useful information and is the
/// Count of records in that time frame.
/// In order for this to work, the Series property IsValueShownAsLabel needs to be NOT True.
for (int i = 0; i < this.Chart.Series["Series1"].Points.Count; i++) {
int n = 0;
int.TryParse(dtResults.Rows[0][i + 1].ToString(), out n);
this.Chart.Series["Series1"].Points[i].Label = string.Format("Avg: #VALY{{0.000}}\nCount: {0}", n);
} // foreach of the Count of Request within the Hour values
this.Chart.Series["Series1"].ChartType = SeriesChartType.Line;
this.Chart.Series["Series1"]["ShowMarkerLines"] = "true";
this.Chart.ChartAreas["ChartArea1"].AxisX.IsMarginVisible = true;
this.Chart.ChartAreas["ChartArea1"].AxisX.Title = "Hours of the Day";
this.Chart.ChartAreas["ChartArea1"].AxisY.Title = "Time in Seconds";
// Handle styling when there is a Zero or missing value
this.Chart.Series["Series1"].EmptyPointStyle.Color = Color.Red;
this.Chart.Series["Series1"].EmptyPointStyle.BorderWidth = 3;
this.Chart.Series["Series1"].EmptyPointStyle.BorderDashStyle = ChartDashStyle.Dash;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerStyle = MarkerStyle.Diamond;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerColor = Color.Red;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerSize = 8;
this.Chart.Series["Series1"].EmptyPointStyle.MarkerBorderColor = Color.Black;
this.Chart.Series["Series1"]["EmptyPointValue"] = "Zero";

Categories

Resources