private static ChartJob loadSavedJob(string filename) { // Build the full path StringBuilder fullFilePath = new StringBuilder(); if (!filename.StartsWith(_configFile.InputDirectory)) { fullFilePath.Append(_configFile.InputDirectory); } fullFilePath.Append(filename); // Deserialize the object and send it back StreamReader file = new StreamReader(fullFilePath.ToString()); ChartJob ds = (ChartJob)_chartJobSerializer.Deserialize(file); if (string.IsNullOrEmpty(ds.JobName)) { ds.JobName = Crypto.GetMD5(filename); } return(ds); }
static void Main(string[] args) { try { if (args.Any()) { foreach (string argument in args) { if (argument.ToLower().StartsWith("/config:")) { _configFileName = argument.Substring(8, argument.Length - 8); } if (argument.ToLower().StartsWith("/?")) { throw new SyntaxException(""); } } } // Attempt to load the config file _configFile = ConfigFile.LoadFromFile(_configFileName); // Validate the config file _configFile.Validate(); // Check the jobs directory to see if it exists // If it doesn't, create it if (!Directory.Exists(_configFile.InputDirectory)) { Directory.CreateDirectory(_configFile.InputDirectory); } // Check the output directory to see if it exists // If it doesn't, create it if (!Directory.Exists(_configFile.OutputDirectory)) { Directory.CreateDirectory(_configFile.OutputDirectory); } // Check to see if the log file folder needs to be created if (!Directory.Exists(_configFile.LogDirectory)) { Directory.CreateDirectory(_configFile.LogDirectory); } Log("Batch chart generator started"); // Attempt to deserialize config files from the jobs folder Log("Loading jobs from: " + _configFile.InputDirectory); List <ChartJob> loadedJobs = new List <ChartJob>(); foreach (string fileName in Directory.GetFiles(_configFile.InputDirectory)) { if (fileName.EndsWith(_configFile.jobFileExtension)) { ChartJob parsedJob = loadSavedJob(fileName); if (parsedJob != null) { Log(fileName + " (Job will be named: " + parsedJob.JobName + ")"); loadedJobs.Add(parsedJob); } else { Log(fileName + " (not a valid job, skipping)"); } } } Log("Loaded " + loadedJobs.Count + " jobs."); // Generate the charts and save them in the output folder foreach (ChartJob job in loadedJobs) { Log("Processing job " + job.JobName); string fullFileName = _configFile.OutputDirectory + "/" + job.JobName.RemoveSpecialCharacters() + ".png"; byte[] fileBytes = job.Generate(_configFile.DatabaseConnectionString); if (fileBytes.Length > 0) { // Delete file if it already exists if (File.Exists(fullFileName)) { File.Delete(fullFileName); } // Make the new file saveChart(fileBytes, fullFileName); } } Log("Batch chart generator complete"); } catch (SyntaxException ex) { if (!string.IsNullOrEmpty(ex.Message)) { Log("Error: " + ex.Message); } SendSyntax(); } catch (Exception ex) { Log(ex.Message); } }
public FNMTargetAttendanceRateChartGenerator(string InternalConnectionString, ChartJob Options) { this.Title = "% Students with at least " + ((decimal)Options.TargetAttendanceRate * 100).ToString("0") + "% Attendance Rate"; this.SubTitle = Options.StartDate.ToShortDateString() + " to " + Options.EndDate.ToShortDateString(); // Load all schools InternalSchoolRepository _schoolRepo = new InternalSchoolRepository(InternalConnectionString); InternalStudentRepository _studentRepo = new InternalStudentRepository(InternalConnectionString); InternalStudentSchoolEnrolmentRepository _schoolStatusRepo = new InternalStudentSchoolEnrolmentRepository(InternalConnectionString); InternalStudentAttendanceRateRepository _attendanceRateRepo = new InternalStudentAttendanceRateRepository(InternalConnectionString, Options.StartDate, Options.EndDate); InternalSchoolRepository schoolRepo = new InternalSchoolRepository(InternalConnectionString); // Determine limiting schools (if any) List <int> limitediSchoolIDs = new List <int>(); if (Options.LimitSchools.Count > 0) { limitediSchoolIDs = Options.LimitSchools; } else { limitediSchoolIDs = schoolRepo.GetAllKnownSchoolIDs(); } ChartData = new List <BarChartDataSeries>(); // Set up the legend Legend = new Dictionary <int, string>() { { 0, "Non First-Nations Students" }, { 1, "First-Nations Students" } }; // Generate some data points foreach (School school in _schoolRepo.GetAll().Where(x => !_schoolGovIDBlacklist.Contains(x.GovernmentID))) { // Load school students List <Student> schoolStudents = _studentRepo.Get(_schoolStatusRepo.GetStudentIDsEnrolledOn(Options.StartDate, Options.EndDate, school.iSchoolID, true)); // Skip schools that have no students if (schoolStudents.Count == 0) { continue; } // Calculate each student's attendance rate for the given time period // Throw out rates that are -1, because they are invalid // Keep a running tally of all attendance rates, and of those from first nations students List <decimal> attendanceRatesNonFNM = new List <decimal>(); List <decimal> attendanceRatesFNM = new List <decimal>(); foreach (Student s in schoolStudents) { StudentAttendanceRate sar = _attendanceRateRepo.GetForStudent(s.iStudentID, Options.StartDate, Options.EndDate); decimal attendanceRate = sar.GetAttendanceRate(Options.StartDate, Options.EndDate); if (attendanceRate != -1) { if (s.IsFirstNations) { attendanceRatesFNM.Add(attendanceRate); } else { attendanceRatesNonFNM.Add(attendanceRate); } } } BarChartDataSeries schoolGraphData = new BarChartDataSeries() { Label = school.ShortName }; try { decimal nonFNMAttendanceRate = (decimal)((decimal)attendanceRatesNonFNM.Count(x => x >= Options.TargetAttendanceRate) / (decimal)attendanceRatesNonFNM.Count()); schoolGraphData.DataPoints.Add(new BarChartPercentBar() { Value = nonFNMAttendanceRate, Label = (nonFNMAttendanceRate * 100).ToString("0.##") + "%", ID = 0 }); } catch {/* * schoolGraphData.DataPoints.Add(new BarChartPercentBar() * { * Value = 0, * Label = "Unknown", * ID = 0 * }); */ } try { decimal fnmAttendanceRate = (decimal)((decimal)attendanceRatesFNM.Count(x => x >= Options.TargetAttendanceRate) / (decimal)attendanceRatesFNM.Count()); schoolGraphData.DataPoints.Add(new BarChartPercentBar() { Value = fnmAttendanceRate, Label = (fnmAttendanceRate * 100).ToString("0.##") + "%", ID = 1 }); } catch {/* * schoolGraphData.DataPoints.Add(new BarChartPercentBar() * { * Value = 0, * Label = "Unknown", * ID = 1 * });*/ } if (schoolGraphData.DataPoints.Count > 0) { this.ChartData.Add(schoolGraphData); } } }
public AverageAttendanceRateChartGenerator(string InternalConnectionString, ChartJob Options) { this.Title = "Average attendance rate"; this.SubTitle = Options.StartDate.ToShortDateString() + " to " + Options.EndDate.ToShortDateString(); // Load all schools InternalSchoolRepository _schoolRepo = new InternalSchoolRepository(InternalConnectionString); InternalStudentRepository _studentRepo = new InternalStudentRepository(InternalConnectionString); InternalStudentSchoolEnrolmentRepository _schoolStatusRepo = new InternalStudentSchoolEnrolmentRepository(InternalConnectionString); InternalStudentAttendanceRateRepository _attendanceRateRepo = new InternalStudentAttendanceRateRepository(InternalConnectionString, Options.StartDate, Options.EndDate); InternalSchoolRepository schoolRepo = new InternalSchoolRepository(InternalConnectionString); // Determine limiting schools (if any) List <int> limitediSchoolIDs = new List <int>(); if (Options.LimitSchools.Count > 0) { limitediSchoolIDs = Options.LimitSchools; } else { limitediSchoolIDs = schoolRepo.GetAllKnownSchoolIDs(); } ChartData = new List <BarChartDataSeries>(); // Generate some data points foreach (School school in _schoolRepo.GetAll().Where(x => !_schoolGovIDBlacklist.Contains(x.GovernmentID) && limitediSchoolIDs.Contains(x.iSchoolID))) { // Load school students List <Student> schoolStudents = _studentRepo.Get(_schoolStatusRepo.GetStudentIDsEnrolledOn(Options.StartDate, Options.EndDate, school.iSchoolID, true)); // Skip schools that have no students if (schoolStudents.Count == 0) { continue; } // Calculate each student's attendance rate for the given time period // Throw out rates that are -1, because they are invalid // Keep a running tally of all attendance rates, and of those from first nations students List <decimal> attendanceRatesAllStudents = new List <decimal>(); foreach (Student s in schoolStudents) { StudentAttendanceRate sar = _attendanceRateRepo.GetForStudent(s.iStudentID, Options.StartDate, Options.EndDate); decimal attendanceRate = sar.GetAttendanceRate(Options.StartDate, Options.EndDate); if (attendanceRate != -1) { attendanceRatesAllStudents.Add(attendanceRate); } } if (attendanceRatesAllStudents.Count == 0) { continue; } BarChartDataSeries schoolGraphData = new BarChartDataSeries() { Label = school.ShortName }; if (attendanceRatesAllStudents.Count > 0) { decimal averageAttendanceRate = attendanceRatesAllStudents.Average(); schoolGraphData.DataPoints.Add(new BarChartPercentBar() { Value = averageAttendanceRate, Label = (averageAttendanceRate * 100).ToString("0.##") + "%", ID = 0 }); } if (schoolGraphData.DataPoints.Count > 0) { this.ChartData.Add(schoolGraphData); } } }
public SchoolYearTargetAttendanceChartGenerator(string InternalConnectionString, ChartJob Options) { this.Title = "% Students with at least " + ((decimal)Options.TargetAttendanceRate * 100).ToString("0") + "% Attendance Rate"; this.SubTitle = Options.StartDate.ToShortDateString() + " to " + Options.EndDate.ToShortDateString(); this.ShowValuesInChart = true; // Labels / Data points will be one for each month this.Lines = new List <LineChartLine>(); // DATA NEEDED FOR THIS REPORT // - Load all enrolled students // - For each month within the specified date range, calculate every student's attendance rate // - Find the final values for each month // This chart is done by the School Year, not arbitrary dates InternalStudentRepository studentRepo = new InternalStudentRepository(InternalConnectionString); InternalStudentSchoolEnrolmentRepository schoolEnrolmentRepo = new InternalStudentSchoolEnrolmentRepository(InternalConnectionString); InternalStudentAttendanceRateRepository attendanceRateRepo = new InternalStudentAttendanceRateRepository(InternalConnectionString, Options.StartDate, Options.EndDate); InternalSchoolRepository schoolRepo = new InternalSchoolRepository(InternalConnectionString); // Determine limiting schools (if any) List <int> limitediSchoolIDs = new List <int>(); if (Options.LimitSchools.Count > 0) { limitediSchoolIDs = Options.LimitSchools; List <string> schoolNames = schoolRepo.Get(limitediSchoolIDs).Select(x => x.Name).ToList <string>(); this.SubSubTitle = this.SubTitle; this.SubTitle = schoolNames.ToCommaSeparatedString(); } else { limitediSchoolIDs = schoolRepo.GetAllKnownSchoolIDs(); } LineChartLine fnmStudentsLine = new LineChartLine() { Label = "FNM Students" }; LineChartLine nonFNMStudentsLine = new LineChartLine() { Label = "Non-FNM Students" }; // Find the school year that the specified dates fit into // If the dates span into two or more school years, use the first one detected // The chart will always start at the beginning of the school year and end at the end of the school year int schoolYear = ReturnLower(Parsers.FindSchoolYear(Options.StartDate), Parsers.FindSchoolYear(Options.EndDate)); List <ChartMonth> schoolYears = new List <ChartMonth>() { new ChartMonth { Label = "AUG", Starts = new DateTime(schoolYear, 8, 1), Ends = new DateTime(schoolYear, 8, DateTime.DaysInMonth(schoolYear, 8)) }, new ChartMonth { Label = "SEP", Starts = new DateTime(schoolYear, 9, 1), Ends = new DateTime(schoolYear, 9, DateTime.DaysInMonth(schoolYear, 9)) }, new ChartMonth { Label = "OCT", Starts = new DateTime(schoolYear, 10, 1), Ends = new DateTime(schoolYear, 10, DateTime.DaysInMonth(schoolYear, 10)) }, new ChartMonth { Label = "NOV", Starts = new DateTime(schoolYear, 11, 1), Ends = new DateTime(schoolYear, 11, DateTime.DaysInMonth(schoolYear, 11)) }, new ChartMonth { Label = "DEC", Starts = new DateTime(schoolYear, 12, 1), Ends = new DateTime(schoolYear, 12, DateTime.DaysInMonth(schoolYear, 12)) }, new ChartMonth { Label = "JAN", Starts = new DateTime(schoolYear + 1, 1, 1), Ends = new DateTime(schoolYear + 1, 1, DateTime.DaysInMonth(schoolYear + 1, 1)) }, new ChartMonth { Label = "FEB", Starts = new DateTime(schoolYear + 1, 2, 1), Ends = new DateTime(schoolYear + 1, 2, DateTime.DaysInMonth(schoolYear + 1, 2)) }, new ChartMonth { Label = "MAR", Starts = new DateTime(schoolYear + 1, 3, 1), Ends = new DateTime(schoolYear + 1, 3, DateTime.DaysInMonth(schoolYear + 1, 3)) }, new ChartMonth { Label = "APR", Starts = new DateTime(schoolYear + 1, 4, 1), Ends = new DateTime(schoolYear + 1, 4, DateTime.DaysInMonth(schoolYear + 1, 4)) }, new ChartMonth { Label = "MAY", Starts = new DateTime(schoolYear + 1, 5, 1), Ends = new DateTime(schoolYear + 1, 5, DateTime.DaysInMonth(schoolYear + 1, 5)) }, new ChartMonth { Label = "JUN", Starts = new DateTime(schoolYear + 1, 6, 1), Ends = new DateTime(schoolYear + 1, 6, DateTime.DaysInMonth(schoolYear + 1, 6)) }, new ChartMonth { Label = "JUL", Starts = new DateTime(schoolYear + 1, 7, 1), Ends = new DateTime(schoolYear + 1, 7, DateTime.DaysInMonth(schoolYear + 1, 7)) }, }; this.Labels = schoolYears.Select(x => x.Label).ToList(); foreach (ChartMonth month in schoolYears) { // Check to see if this month falls within the specified time period // If it doesn't, skip it if (month.Starts > Options.EndDate) { continue; } if (month.Ends < Options.StartDate) { continue; } // Clamp the start and end dates to the start and end dates specified if (month.Starts < Options.StartDate) { month.Starts = Options.StartDate; } if (month.Ends > Options.EndDate) { month.Ends = Options.EndDate; } // If the month is the current month, cap the end date at today, because future data won't exist yet if ((month.Starts.Month == DateTime.Today.Month) && (month.Starts.Year == DateTime.Today.Year)) { if (month.Ends > DateTime.Today) { month.Ends = DateTime.Today; } } decimal dataPointThisMonth_NonFNM = (decimal) - 1.0; decimal dataPointThisMonth_FNM = (decimal) - 1.0; // Now, load all the enrolled students during the start and end of the month // and calculate their average attendances List <Student> enrolledStudentsThisMonth = studentRepo.Get(schoolEnrolmentRepo.GetStudentIDsEnrolledOn(month.Starts, month.Ends, limitediSchoolIDs, true)); if (enrolledStudentsThisMonth.Count == 0) { continue; } List <decimal> attendanceRatesNonFNM = new List <decimal>(); List <decimal> attendanceRatesFNM = new List <decimal>(); foreach (Student s in enrolledStudentsThisMonth) { StudentAttendanceRate sar = attendanceRateRepo.GetForStudent(s.iStudentID, month.Starts, month.Ends); decimal attendanceRate = sar.GetAttendanceRate(month.Starts, month.Ends); if (attendanceRate != -1) { if (s.IsFirstNations) { attendanceRatesFNM.Add(attendanceRate); } else { attendanceRatesNonFNM.Add(attendanceRate); } } } // Now, find the number of the rates that are greater than or equal to the target try { dataPointThisMonth_NonFNM = (decimal)((decimal)attendanceRatesNonFNM.Count(x => x > Options.TargetAttendanceRate) / (decimal)attendanceRatesNonFNM.Count()); } catch { } try { dataPointThisMonth_FNM = (decimal)((decimal)attendanceRatesFNM.Count(x => x > Options.TargetAttendanceRate) / (decimal)attendanceRatesFNM.Count()); } catch { } // Add the data point to the line if (dataPointThisMonth_NonFNM > -1) { nonFNMStudentsLine.LineDataPoints.Add(month.Label, dataPointThisMonth_NonFNM); } if (dataPointThisMonth_FNM > -1) { fnmStudentsLine.LineDataPoints.Add(month.Label, dataPointThisMonth_FNM); } } // Finally, add the lines to the chart this.Lines.Add(nonFNMStudentsLine); this.Lines.Add(fnmStudentsLine); }