Label x-axis by days of the week - c#

I am trying to visualise data with a chart. I have done for hours, need to do for days and weeks to compare. Here is a sample code for the how I visualise hourly, having problems doing the same thing for day like monday, tuesday down to sunday in the intervals. How can I do this for day intervals?
chart1.ChartAreas.Add("area");
chart1.ChartAreas["area"].AxisX.Minimum = 0;
chart1.ChartAreas["area"].AxisX.Maximum = 24;
chart1.ChartAreas["area"].AxisX.Interval = 1;
chart1.ChartAreas["area"].AxisY.Minimum = 0;
chart1.ChartAreas["area"].AxisY.Maximum = intYAxisMax;
chart1.ChartAreas["area"].AxisY.Interval= 10;
chart1.Series.Add("Electric");
chart1.Series.Add("Gas");
chart1.Series["Electric"].Color = Color.Red;
chart1.Series["Gas"].Color = Color.Green;
chart1.ChartAreas["area"].AxisX.Title = "Hours";
chart1.ChartAreas["area"].AxisY.Title = "KW/H";
Title objTest = new Title("Daily Data Usage");
chart1.Titles.Add(objTest);
Legend objLegend = new Legend("Testing");
chart1.Legends.Add(objLegend);
//chart1.Series["Electric"].Points.AddXY(20 , 203);
//chart1.Series["Gas"].Points.AddXY(11, 70);

Try this:
chart1.Series["Electric"].IsXValueIndexed = true;
//Add data
chart1.Series["Electric"].Points.AddXY(1, 203);
chart1.Series["Electric"].Points.AddXY(2, 70);
//X-axis labels
chart1.Series["Electric"].Points[0].AxisLabel = "Sunday";
chart1.Series["Electric"].Points[1].AxisLabel = "Monday";
etc...

Related

setting fixed values to X axis of a chart

The problem is that I want to set some fixed values for 3 types of charts:
First is a week chart so it need to have Sunday to Saturday values on X axis.
Second is month so it have to set the days of the current month
The last one its a year chart that need to show months from 1 to 12 or jan to dec.
I did watch a lot of tutorials but any of those set points like I want and most of them teach how to set X and Y points, but I want a fixed X point and get the Y point from the DB.
To get these fixed ranges :
I have set up the chart like so:
private void rb_range_CheckedChanged(object sender, EventArgs e)
{
Chart chart = chart8;
Series s = chart.Series[0];
s.ChartType = SeriesChartType.Line;
s.XValueType = ChartValueType.DateTime;
s.YValueType = ChartValueType.Double;
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY;
//ax.IsMarginVisible = true; // max or may be necessary
ax.Interval = 1;
if (rb_week.Checked)
{
setValues('w', 123);
ax.IntervalType = DateTimeIntervalType.Days;
ax.LabelStyle.Format = "dddd";
}
else if (rb_month.Checked)
{
setValues('m', 123);
ax.IntervalType = DateTimeIntervalType.Days;
ax.LabelStyle.Format = "dd";
}
else if (rb_year.Checked)
{
setValues('y', 123);
ax.IntervalType = DateTimeIntervalType.Months;
ax.LabelStyle.Format = "MMMM";
}
s.Points.Clear();
foreach (var dp in points) s.Points.Add(dp);
// after the points are added or bound to you may want to..
// set the minimum&maximum, but if the data fit you don't have to!
ax.Minimum = points.Min(x => x.XValue);
ax.Maximum = points.Max(x => x.XValue);
}
A few Notes :
It is important to select or bind only those dates that should go into the chart! If you make mistakes here the limits will be off!
If your data are dense enough, that is, if they inclused the 1st and last day of the interval they refer to, you can omit setting the Minimum and Maximum on the x-axis; in that case also include ax.IsMarginVisible = false; to avoid points from the neighboring ranges showing up.
If you data are sparse you may need to determine the Minimum and Maximum values differently than simply picking the first and last x-values. Instead you should pick the correct DateTime values. Note that you need to pick real DateTimes and convert them to double with the ToOADate() function, as the axis properties expect value units.
You can study the code I used to create my data for hints on how to get the Date of the 1st and last day of a given week, month or year..
Note how I use DateTime.DaysInMonth to get the correct number of days in a given month
If you chose Column as ChartType the 1st and last columns may get cut. For this case you can expand the range by adding half a unit to the Maximum and subtracting the same from the Minimum. You may also need to add one such amount to the IntervalOffset.
Here is how I set up the points:
List<DataPoint> points = new List<DataPoint>();
void setValues(char time, int rand)
{
Random rnd = new Random(rand); // random data values
points = new List<DataPoint>();
DateTime dn = DateTime.Now;
DateTime dw = new DateTime(dn.Year, dn.Month, dn.Day % 7 + 1); //my weeks start on monday
DateTime dm = new DateTime(dn.Year, dn.Month, 1);
DateTime dy = new DateTime(dn.Year, 1, 1);
if (time == 'w') for (int i = 0; i < 7; i++)
points.Add(new DataPoint(dw.AddDays(i).ToOADate(), rnd.Next(100) + 50));
if (time == 'm') for (int i = 0; i < DateTime.DaysInMonth(dn.Year, dn.Month); i++)
points.Add(new DataPoint(dm.AddDays(i).ToOADate(), rnd.Next(100) + 50));
if (time == 'y') for (int i = 0; i < 12; i++)
points.Add(new DataPoint(dy.AddMonths(i).ToOADate(), rnd.Next(100) + 50));
}

Why when called from another class the graph doesn't get populated?

I have been trying to populate a graph from another class. I have already made the graph public so its accessible to the subclass. When I try to run the entire program on Visual Studio 2019. It shows no error but still the graph does not get populated at all.
I tried implementing the same code from the base class and it works but somehow it doesn't work when i run it from the subclass.
This is the method from the other class called "ClassStatistics" and the base class is called "home". "linechart" is the graph variable name that i am using and is declared in the base class - home.
Am I doing anything wrong here?
DataTable dt = new DataTable();
dt.Columns.Add("X_Value", typeof(DateTime)); //X axis of the type date.
dt.Columns.Add("Y_Value", typeof(double)); //Y axis of type double.
Console.WriteLine("Hello M");
StreamReader sr = new StreamReader(Path.GetFullPath("UserData/Logs") + "\\" + System.DateTime.Today.ToString("MM-yyyy") + "_Logs.txt"); //Path to the log file.
string line;
DayOfWeek day = DateTime.Now.DayOfWeek; //Current day of the week
int days = day - DayOfWeek.Monday; //Keeps track of the number of days left before the next week.
DateTime Start = DateTime.ParseExact(new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).ToString("dd-MM-yyyy"), "dd-MM-yyyy", CultureInfo.InvariantCulture); //First day of the month
DateTime End = DateTime.ParseExact(new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1).AddMonths(1).AddDays(-1).ToString("dd-MM-yyyy"), "dd-MM-yyyy", CultureInfo.InvariantCulture); //Last day of the month
DateTime temp; //stores the date extracted from the log file.
int max = 0;
while ((line = sr.ReadLine()) != null)
{
string[] strarr = line.Split(':'); //Splits the data using ':' for '0' to store the date and '1' to store the number of errors
temp = DateTime.ParseExact(strarr[0], "dd-MM-yyyy", CultureInfo.InvariantCulture); //Extracts the date present in the array
if (temp >= Start && temp <= End) //checks if the given date lies in the same month
{
if (Convert.ToInt32(strarr[1]) > max)
max = Convert.ToInt32(strarr[1]); //Storing the maximum value of Y in max
Console.WriteLine(strarr[1]);
dt.Rows.Add(temp, strarr[1]); //Add data to the data table to show in the graph.
}
}
linechart.DataSource = dt;
linechart.Series["Error-Date"].XValueMember = "X_Value";
linechart.Series["Error-Date"].YValueMembers = "Y_Value";
linechart.Series["Error-Date"].ChartType = SeriesChartType.Line; //Defining the type of chart
linechart.ChartAreas[0].AxisY.Maximum = max; //setting the maximum value of the Y axis
//Change the line colors and grid colors of the chart of both the axes.
linechart.ChartAreas[0].AxisX.LineColor = Color.Black;
linechart.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Black;
linechart.ChartAreas[0].AxisX.LabelStyle.ForeColor = Color.White;
linechart.ChartAreas[0].AxisX.Interval = 1;
linechart.ChartAreas[0].AxisY.LineColor = Color.Black;
linechart.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Black;
linechart.ChartAreas[0].AxisY.LabelStyle.ForeColor = Color.White;
linechart.Series["Error-Date"].BorderWidth = 5;
if (sr != null) sr.Close();

Automatic Day Assign

I need help about assigning day automatically. I couldn't find correct way.
Now problem is that I have fitness program. And I will add new user. When I add I will add program too. Fitness program has limit.
For example. 8 seans. Then user chooses every Saturday and Sunday.
16.03.2019, 17.03.2019, 23.03.2019, 24.03.2019,
30.03.2019, 31.03.2019, 06.04.2019, 07.04.2019
The dates will be assign automatically due to his chosen. uye.DAYS choosed days of week. For example '0,6' and uye.SURE means limit of seans
if(uy.UYELIK== "PLATES")
{
DateTime date = DateTime.Now.Date;
System.TimeSpan duration = new System.TimeSpan(1, 0, 0, 0);
for (int i = 0; i < uye.SURE; i++)
{
date = date.Add(duration);
var list = uye.DAYS.Split(',');
for(int j = 0; j < list.Length; j++)
{
if ((int)date.DayOfWeek == Convert.ToInt32(list[j]))
{
HR_FITNESS_USER_PLATES_PROGRAM program = new HR_FITNESS_USER_PLATES_PROGRAM();
program.REF_HOCA = uye.HOCA;program.SEANS_LIMIT = uye.SURE;program.SEANS_TIME = date;program.REF_UYELIK = uy.ID;program.SICIL = uye.SICIL.ToString();
db.HR_FITNESS_USER_PLATES_PROGRAM.Add(program);db.SaveChanges();
}
}
}
}
This code is not correct. Here I can't increase day if not one of them. How can I do it?
As I understand, you need to insert a weekend fitness program for a member. Here is a simple psuedocode for that,
var startDate = DateTime.Today; //today
int currentDayOfWeek = (int)startDate.DayOfWeek; //today
//saturday of this week, disregarding if today is
//saturday or sunday, it is up to you to enhance this.
DateTime thisSaturday = startDate.AddDays(6 - currentDayOfWeek);
var sessions = 8;
for (int i = 0; i<sessions; i++)
{
SaveToDb(thisSaturday);
thisSaturday = thisSaturday.AddDays(7); //next week's weekend
}
private void SaveToDb(DateTime saturday)
{
DateTime sunday = saturday.AddDays(1);
//insert data for saturday and sunday
}

Charting hours wont start at zero

I have a chart control on a winform that should log some counting p hour.
On 12H clock repeat in local PC time.
So the chart starts from 0 to 11
The problem is that when its 12:20 or 12:50 or 12:10
I cannot get the numbering to start at 0 on the X axis
My main inits the chart like :
int[] numbers = new int[11] {12,11,10,91,82,7,66,5,44,3,2,1};
chart1.ChartAreas[0].AxisX.Maximum = 11;
chart1.ChartAreas[0].AxisX.Minimum = 0;
chart1.ChartAreas[0].AxisX.Interval = 1;
Then a loop updates and redraws the chart like below
DateTime currentTime = DateTime.UtcNow.ToLocalTime();
int hour12 = (currentTime.Hour % 12);
numbers[hour12]++;
chart1.Series["total"].Points.DataBindY(numbers);
I also tried but it didnt help here.
chart1.ChartAreas[0].AxisX.IsMarginVisible = false;
Replace
chart1.Series["total"].Points.DataBindY(numbers);
with
chart1.Series["total"].Points.DataBindXY(Enumerable.Range(0,12).ToArray(), numbers);
Update:
Set AxisX so that all chart series shows up correctly:
chart1.ChartAreas[0].AxisX.Maximum = 12;
chart1.ChartAreas[0].AxisX.Minimum =-1;
chart1.ChartAreas[0].AxisX.Interval = 1;
In addition to Sakis to remove -1 and 12 to get the 0..11 scale.
chart1.ChartAreas[0].AxisX.Maximum = 12;
chart1.ChartAreas[0].AxisX.Minimum =-1;
chart1.ChartAreas[0].AxisX.Interval = 1;
chart1.ChartAreas[0].AxisX.CustomLabels.Add(-1.5, -0.5, "Hour");
chart1.ChartAreas[0].AxisX.CustomLabels.Add(11.5, 12.5, " ");
for(int i=0;i<12;i++) chart1.ChartAreas[0].AxisX.CustomLabels.Add(i-0.9, i+0.9, i.ToString());

Create multi column series asp:chart with custom objects list in asp.net C#

I would like to create a main overview chart with asp:chart control, like this:
Instead of Andrew, etc. it would be fiscal years (2009, 2010, 2011, etc.) and the products would be the 4 types of costs.
But how do I do this with a list of custom objects that are contstructed like this:
List< Cost_cost > listOfCosts
Cost
Type (can be one of four types)
Amount (float)
Fiscal Year
Anybody got a link or tips on how to handle this?
Found a solution, it's partialy hard coded, i.e., the types of costs but since it needs to be uploaded by the day after tomorrow, it'll do.
The following code of course is after I created Chart1, the mainlegend and area and some styling stuff:
//Set the amount of the four series to zero
float totalAmountHousing = 0, totalAmountPersonnel = 0, totalAmountServices = 0, totalAmountIT = 0;
//Create the four series per year
Series sr = new Series(); Series sr2 = new Series(); Series sr3 = new Series(); Series sr4 = new Series();
//Set the series to the same chart area
sr.ChartArea = "mainArea"; sr2.ChartArea = "mainArea"; sr3.ChartArea = "mainArea"; sr4.ChartArea = "mainArea";
//Set them to the same legend
sr.Legend = "mainLegend"; sr2.Legend = "mainLegend"; sr3.Legend = "mainLegend"; sr4.Legend = "mainLegend";
//Set the names of the 4 series
sr.Name = "Housing"; sr2.Name = "IT"; sr3.Name = "Services"; sr4.Name = "Personnel";
//Add the series to the chart
Chart1.Series.Add(sr); Chart1.Series.Add(sr2); Chart1.Series.Add(sr3); Chart1.Series.Add(sr4);
//Set drawing style to cylinder of the four costs
Chart1.Series["Housing"]["DrawingStyle"] = "Cylinder";
Chart1.Series["IT"]["DrawingStyle"] = "Cylinder";
Chart1.Series["Services"]["DrawingStyle"] = "Cylinder";
Chart1.Series["Personnel"]["DrawingStyle"] = "Cylinder";
for (int i = 0; i < listOfFiscalYears.Count; i++) {
//generate some point for the chart
for (int j = 0; j < listOfCosts.Count; j++) {
if ((listOfCosts[j].Type).ToLower() == "housing" && listOfCosts[j].Cost_fiscalYear.Year == int.Parse(listOfFiscalYears[i].ToString())) totalAmountHousing += (float)listOfCosts[j].Amount;
if ((listOfCosts[j].Type).ToLower() == "it" && listOfCosts[j].Cost_fiscalYear.Year == int.Parse(listOfFiscalYears[i].ToString())) totalAmountIT += (float)listOfCosts[j].Amount;
if ((listOfCosts[j].Type).ToLower() == "services" && listOfCosts[j].Cost_fiscalYear.Year == int.Parse(listOfFiscalYears[i].ToString())) totalAmountServices += (float)listOfCosts[j].Amount;
if ((listOfCosts[j].Type).ToLower() == "personnel" && listOfCosts[j].Cost_fiscalYear.Year == int.Parse(listOfFiscalYears[i].ToString())) totalAmountPersonnel += (float)listOfCosts[j].Amount;
}
Chart1.Series["Housing"].Points.Add(totalAmountHousing);
Chart1.Series["IT"].Points.Add(totalAmountIT);
Chart1.Series["Services"].Points.Add(totalAmountServices);
Chart1.Series["Personnel"].Points.Add(totalAmountPersonnel);
Chart1.ChartAreas["mainArea"].AxisX.Interval = 1;
//Add custom label to the X axis
Chart1.ChartAreas[0].AxisX.CustomLabels.Add(new CustomLabel(i, i + 2, (listOfFiscalYears[i].ToString()), 0, LabelMarkStyle.None));
//Reset the total cost after they have been added for the year
totalAmountHousing = 0; totalAmountPersonnel = 0; totalAmountServices = 0; totalAmountIT = 0;
}

Categories