protected void DrawBar(Graphics gr, WorkingHoursConfiguration config, Bar bar) { if (bar == null) { return; } float height = (float)bar.Height; float start = (float)config.time_end - (float)bar.start.TimeOfDay.TotalHours - height; float x_offset = 0; // center for lone bars if (config.show_unlocked_hours && !config.show_work_hours || !config.show_unlocked_hours && config.show_work_hours) { x_offset = 2; } else if (bar.is_unlocked) // right for the second bar (unlocked bar) { x_offset = 8; } if (config.show_detailed_weeks) { gr.FillRectangle(bar.color, 25 + bar.day_of_week * 20 + x_offset, 10 + start * config.zoom_amount, 7, height * config.zoom_amount); } else { if (!bar.is_unlocked && bar.Height > 0) { gr.DrawString(bar.Height.ToHourMinuteString(), font_small, Brushes.Black, 21 + bar.day_of_week * 20 + x_offset, -5 + (float)(config.GraphHours - bar.Height) * config.zoom_amount); } gr.FillRectangle(bar.color, 25 + bar.day_of_week * 20 + x_offset, 10 + (float)(config.GraphHours - bar.Height) * config.zoom_amount, 7, (float)bar.Height * config.zoom_amount); } }
public BarCreator( WorkingHoursConfiguration config, DateTime week_start, DateTime week_end ) { this.config = config; this.week_start = week_start; this.week_end = week_end; work_color = new SolidBrush( config.work_bar_color ); latest_work_color = new SolidBrush( config.latest_work_bar_color ); unlocked_color = new SolidBrush( config.unlocked_bar_color ); latest_unlocked_color = new SolidBrush( config.latest_unlocked_bar_color ); first_unlock_date = invalid_date; last_unlock_date = invalid_date; last_lock_date = invalid_date; }
public BarCreator(WorkingHoursConfiguration config, DateTime week_start, DateTime week_end) { this.config = config; this.week_start = week_start; this.week_end = week_end; work_color = new SolidBrush(config.work_bar_color); latest_work_color = new SolidBrush(config.latest_work_bar_color); unlocked_color = new SolidBrush(config.unlocked_bar_color); latest_unlocked_color = new SolidBrush(config.latest_unlocked_bar_color); first_unlock_date = invalid_date; last_unlock_date = invalid_date; last_lock_date = invalid_date; }
protected void DrawBackground(Graphics gr, WorkingHoursConfiguration config) { gr.DrawLine(pen_gray, 15, 10, 15, 10 + config.GraphHours * config.zoom_amount); for (int i = 0, hours = config.time_end; i <= config.time_end - config.time_start; i++, hours--) { if (config.full_background_lines) { gr.DrawLine(pen_lightgray, 20, 10 + i * config.zoom_amount, 160, 10 + i * config.zoom_amount); } gr.DrawLine(pen_gray, 15, 10 + i * config.zoom_amount, 20, 10 + i * config.zoom_amount); if (config.show_detailed_weeks) { if (hours < config.work_start.Hours || hours > config.work_end.Hours) { gr.DrawString(hours.ToString(), font_small, Brushes.LightGray, 1, 5 + i * config.zoom_amount); } else { gr.DrawString(hours.ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount); } } else { if (config.GraphHours - i <= config.work_hours) { gr.DrawString((config.GraphHours - i).ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount); } else { gr.DrawString((config.GraphHours - i).ToString(), font_small, Brushes.Red, 1, 5 + i * config.zoom_amount); } } } // bar showing expected working hours if (!config.show_detailed_weeks) { int y = (int)(10 + (config.GraphHours - config.work_hours) * config.zoom_amount); if (config.full_background_lines) { gr.DrawLine(new Pen(Color.LightSkyBlue, 3), 20, y, 160, y); } gr.DrawLine(new Pen(Color.DodgerBlue, 3), 15, y, 20, y); } }
public void ShowDialog( IWin32Window owner, WorkingHoursConfiguration config ) { b_work_bar_color.BackColor = config.work_bar_color; b_unlocked_bar_color.BackColor = config.unlocked_bar_color; b_latest_work_bar_color.BackColor = config.latest_work_bar_color; b_latest_unlocked_bar_color.BackColor = config.latest_unlocked_bar_color; c_zoom_amount.Value = config.zoom_amount; c_time_start.Value = config.time_start; c_time_end.Value = config.time_end; c_unlocked_hours.Value = Convert.ToDecimal( config.unlocked_hours ); c_work_hours.Value = Convert.ToDecimal( config.work_hours ); cb_show_detailed_weeks.Checked = config.show_detailed_weeks; cb_show_work_hours.Checked = config.show_work_hours; cb_show_unlocked_hours.Checked = config.show_unlocked_hours; cb_full_background_lines.Checked = config.full_background_lines; dtp_work_start.Value = DateTime.Today.Add( config.work_start ); dtp_work_end.Value = DateTime.Today.Add( config.work_end ); cb_log_program_start.Checked = config.log_program_start; cb_log_program_shutdown.Checked = config.log_program_shutdown; if ( ShowDialog( owner ) == DialogResult.OK ) { config.work_bar_color = b_work_bar_color.BackColor; config.unlocked_bar_color = b_unlocked_bar_color.BackColor; config.latest_work_bar_color = b_latest_work_bar_color.BackColor; config.latest_unlocked_bar_color = b_latest_unlocked_bar_color.BackColor; config.zoom_amount = Convert.ToInt32( c_zoom_amount.Value ); config.time_start = Convert.ToInt32( c_time_start.Value ); config.time_end = Convert.ToInt32( c_time_end.Value ); config.unlocked_hours = Convert.ToDouble( c_unlocked_hours.Value ); config.work_hours = Convert.ToDouble( c_work_hours.Value ); config.show_detailed_weeks = cb_show_detailed_weeks.Checked; config.show_work_hours = cb_show_work_hours.Checked; config.show_unlocked_hours = cb_show_unlocked_hours.Checked; config.full_background_lines = cb_full_background_lines.Checked; config.work_start = dtp_work_start.Value.Subtract( dtp_work_start.Value.Subtract( dtp_work_start.Value.TimeOfDay ) ); config.work_end = dtp_work_end.Value.Subtract( dtp_work_end.Value.Subtract( dtp_work_end.Value.TimeOfDay ) ); config.log_program_start = cb_log_program_start.Checked; config.log_program_shutdown = cb_log_program_shutdown.Checked; } }
public void ShowDialog(IWin32Window owner, WorkingHoursConfiguration config) { b_work_bar_color.BackColor = config.work_bar_color; b_unlocked_bar_color.BackColor = config.unlocked_bar_color; b_latest_work_bar_color.BackColor = config.latest_work_bar_color; b_latest_unlocked_bar_color.BackColor = config.latest_unlocked_bar_color; c_zoom_amount.Value = config.zoom_amount; c_time_start.Value = config.time_start; c_time_end.Value = config.time_end; c_unlocked_hours.Value = Convert.ToDecimal(config.unlocked_hours); c_work_hours.Value = Convert.ToDecimal(config.work_hours); cb_show_detailed_weeks.Checked = config.show_detailed_weeks; cb_show_work_hours.Checked = config.show_work_hours; cb_show_unlocked_hours.Checked = config.show_unlocked_hours; cb_full_background_lines.Checked = config.full_background_lines; dtp_work_start.Value = DateTime.Today.Add(config.work_start); dtp_work_end.Value = DateTime.Today.Add(config.work_end); cb_log_program_start.Checked = config.log_program_start; cb_log_program_shutdown.Checked = config.log_program_shutdown; if (ShowDialog(owner) == DialogResult.OK) { config.work_bar_color = b_work_bar_color.BackColor; config.unlocked_bar_color = b_unlocked_bar_color.BackColor; config.latest_work_bar_color = b_latest_work_bar_color.BackColor; config.latest_unlocked_bar_color = b_latest_unlocked_bar_color.BackColor; config.zoom_amount = Convert.ToInt32(c_zoom_amount.Value); config.time_start = Convert.ToInt32(c_time_start.Value); config.time_end = Convert.ToInt32(c_time_end.Value); config.unlocked_hours = Convert.ToDouble(c_unlocked_hours.Value); config.work_hours = Convert.ToDouble(c_work_hours.Value); config.show_detailed_weeks = cb_show_detailed_weeks.Checked; config.show_work_hours = cb_show_work_hours.Checked; config.show_unlocked_hours = cb_show_unlocked_hours.Checked; config.full_background_lines = cb_full_background_lines.Checked; config.work_start = dtp_work_start.Value.Subtract(dtp_work_start.Value.Subtract(dtp_work_start.Value.TimeOfDay)); config.work_end = dtp_work_end.Value.Subtract(dtp_work_end.Value.Subtract(dtp_work_end.Value.TimeOfDay)); config.log_program_start = cb_log_program_start.Checked; config.log_program_shutdown = cb_log_program_shutdown.Checked; } }
protected void DrawHours(WorkingHoursConfiguration config, List <EventEntry>[] days, DateTime start_of_week, DateTime end_of_week) { pb_image.Image = new Bitmap(20 + 15 * 10, config.GraphHours * config.zoom_amount + 60); pb_image.Size = pb_image.Image.Size; Graphics gr = Graphics.FromImage(pb_image.Image); gr.Clear(Color.White); DrawBackground(gr, config); double work_avg = 0; double unlocked_avg = 0; DrawBars(gr, config, days, start_of_week, end_of_week, out work_avg, out unlocked_avg); // draw dates for (int i = 0; i < days.Length; i++) { if (i > 4) { gr.DrawString(start_of_week.AddDays(i).Day.ToString(), font_small, Brushes.OrangeRed, 27 + i * 20, config.GraphHours * config.zoom_amount + 20); } else { gr.DrawString(start_of_week.AddDays(i).Day.ToString(), font_small, Brushes.Black, 27 + i * 20, config.GraphHours * config.zoom_amount + 20); } } if (!config.show_detailed_weeks) { gr.DrawString("W: " + work_avg.ToHourMinuteString(), font_normal, Brushes.Black, pb_image.Width / 2 - 70, config.GraphHours * config.zoom_amount + 40); } gr.DrawString(start_of_week.ToString("MMM"), font_normal, Brushes.Black, pb_image.Width / 2 - 10, config.GraphHours * config.zoom_amount + 40); }
public void ShowDialog( IWin32Window owner, WorkingHoursConfiguration configuration, List< EventEntry > events ) { if ( events.Count > 0 ) { DateTime d = events[ 0 ].date; DateTime start_of_week = d.Subtract( new TimeSpan( (int)( d.DayOfWeek )-1, d.Hour, d.Minute, d.Second, d.Millisecond ) ); DateTime end_of_week = start_of_week.AddDays( 7 ); int today = d.MondayFirstDoW(); // partition the events into weeks = array of days // then create 1 WeekGraph control for every week in the event list List< EventEntry >[] days = new List<EventEntry>[ 7 ]; for ( int i=0; i<7; i++ ) days[ i ] = new List<EventEntry>(); foreach ( EventEntry ee in events ) { if ( ee.date.CompareTo( end_of_week ) >= 0 ) { // the next week has begun flp_weeks.Controls.Add( new WeekGraph( configuration, days, start_of_week, end_of_week ) ); days = new List<EventEntry>[ 7 ]; for ( int i=0; i<7; i++ ) days[ i ] = new List< EventEntry >(); start_of_week = ee.date.Subtract( new TimeSpan( (int)( ee.date.DayOfWeek )-1, ee.date.Hour, ee.date.Minute, ee.date.Second, ee.date.Millisecond ) ); end_of_week = start_of_week.AddDays( 7 ); } days[ ee.date.MondayFirstDoW() ].Add( ee ); } Control last_weekgraph = new WeekGraph( configuration, days, start_of_week, end_of_week ); flp_weeks.Controls.Add( last_weekgraph ); // fit the parent form's area to the flowlayoutpanel as closely as possible... Rectangle working_area = Screen.GetWorkingArea( this ); int controls_per_row = Math.Min( configuration.max_weeks_per_row, Math.Min( working_area.Width / flp_weeks.Controls[ 0 ].Width, flp_weeks.Controls.Count ) ); int target_width = controls_per_row * flp_weeks.Controls[ 0 ].Width; int target_height = 0; int control_rows = ( ( flp_weeks.Controls.Count + controls_per_row - 1 ) / controls_per_row ); // rounded up bool scrollbar_appeared = false; if ( working_area.Height > 1.5* control_rows * flp_weeks.Controls[ 0 ].Height ) { target_height = ( (flp_weeks.Controls.Count + controls_per_row - 1 ) / controls_per_row ) * flp_weeks.Controls[ 0 ].Height; } else if ( working_area.Height > flp_weeks.Controls[ 0 ].Height ) { target_height = flp_weeks.Controls[ 0 ].Height; scrollbar_appeared = true; } else { target_height = working_area.Height * 8 / 10; scrollbar_appeared = true; } if ( scrollbar_appeared ) { target_width += SystemInformation.VerticalScrollBarWidth; } this.Width = 10 + target_width; this.Height = 10 + target_height + b_ok.Height + this.Height - this.ClientRectangle.Height; flp_weeks.ScrollControlIntoView( last_weekgraph ); } ShowDialog( owner ); }
protected void DrawHours( WorkingHoursConfiguration config, List< EventEntry >[] days, DateTime start_of_week, DateTime end_of_week ) { pb_image.Image = new Bitmap( 20 + 15*10, config.GraphHours * config.zoom_amount + 60 ); pb_image.Size = pb_image.Image.Size; Graphics gr = Graphics.FromImage( pb_image.Image ); gr.Clear( Color.White ); DrawBackground( gr, config ); double work_avg = 0; double unlocked_avg = 0; DrawBars( gr, config, days, start_of_week, end_of_week, out work_avg, out unlocked_avg); // draw dates for ( int i=0; i<days.Length; i++ ) { if ( i > 4 ) { gr.DrawString( start_of_week.AddDays( i ).Day.ToString(), font_small, Brushes.OrangeRed, 27 + i*20, config.GraphHours * config.zoom_amount + 20 ); } else { gr.DrawString( start_of_week.AddDays( i ).Day.ToString(), font_small, Brushes.Black, 27 + i*20, config.GraphHours * config.zoom_amount + 20 ); } } if ( !config.show_detailed_weeks ) { gr.DrawString( "W: " + work_avg.ToHourMinuteString(), font_normal, Brushes.Black, pb_image.Width / 2 - 70, config.GraphHours * config.zoom_amount + 40 ); } gr.DrawString( start_of_week.ToString( "MMM" ), font_normal, Brushes.Black, pb_image.Width / 2 - 10, config.GraphHours * config.zoom_amount + 40 ); }
protected void DrawBars( Graphics gr, WorkingHoursConfiguration config, List< EventEntry >[] days, DateTime start_of_week, DateTime end_of_week, out double work_hours_week, out double unlocked_hours_week ) { double work_hours_day = 0; double unlocked_hours_day = 0; int work_days = 0; work_hours_week = 0; unlocked_hours_week = 0; BarCreator bar_creator = new BarCreator( config, start_of_week, end_of_week ); for ( int i = 0; i < days.Length; i++ ) { work_hours_day = 0; unlocked_hours_day = 0; foreach ( EventEntry ee in days[ i ] ) { Bar bar = bar_creator.GetBar( ee ); if ( config.show_detailed_weeks || bar == null ) { DrawBar( gr, config, bar ); } else { if ( bar.is_unlocked ) { unlocked_hours_day += bar.Height; } else { work_hours_day += bar.Height; } } } foreach ( Bar b in bar_creator.GetFinalBarsForDay() ) // last unlock - now { if ( config.show_detailed_weeks ) { DrawBar( gr, config, b ); } else { if ( b.is_unlocked ) { unlocked_hours_day += b.Height; } else { work_hours_day += b.Height; } } } if ( !config.show_detailed_weeks ) { Bar b1 = new Bar( new SolidBrush( config.work_bar_color ), i, false, start_of_week.AddDays( i ), start_of_week.AddDays( i + work_hours_day / 24 ) ); Bar b2 = new Bar( new SolidBrush( config.unlocked_bar_color ), i, true, start_of_week.AddDays( i ), start_of_week.AddDays( i + unlocked_hours_day / 24 ) ); DrawBar( gr, config, b1 ); DrawBar( gr, config, b2 ); } if ( work_hours_day > 0 || unlocked_hours_day > 0 ) { work_days++; } work_hours_week += work_hours_day; unlocked_hours_week += unlocked_hours_day; } work_hours_week /= work_days; unlocked_hours_week /= work_days; }
protected void DrawBar( Graphics gr, WorkingHoursConfiguration config, Bar bar ) { if ( bar == null ) return; float height = (float)bar.Height; float start = (float)config.time_end - (float)bar.start.TimeOfDay.TotalHours - height; float x_offset = 0; // center for lone bars if ( config.show_unlocked_hours && !config.show_work_hours || !config.show_unlocked_hours && config.show_work_hours ) { x_offset = 2; } else if ( bar.is_unlocked ) // right for the second bar (unlocked bar) { x_offset = 8; } if ( config.show_detailed_weeks ) { gr.FillRectangle( bar.color, 25 + bar.day_of_week*20 + x_offset, 10 + start * config.zoom_amount, 7, height * config.zoom_amount ); } else { if ( !bar.is_unlocked && bar.Height > 0 ) { gr.DrawString( bar.Height.ToHourMinuteString(), font_small, Brushes.Black, 21 + bar.day_of_week*20 + x_offset, -5 + (float)( config.GraphHours - bar.Height ) * config.zoom_amount ); } gr.FillRectangle( bar.color, 25 + bar.day_of_week*20 + x_offset, 10 + (float)(config.GraphHours - bar.Height) * config.zoom_amount, 7, (float)bar.Height * config.zoom_amount ); } }
protected void DrawBackground( Graphics gr, WorkingHoursConfiguration config ) { gr.DrawLine( pen_gray, 15, 10, 15, 10 + config.GraphHours * config.zoom_amount ); for ( int i = 0, hours = config.time_end; i <= config.time_end - config.time_start; i++, hours-- ) { if ( config.full_background_lines ) { gr.DrawLine( pen_lightgray, 20, 10 + i*config.zoom_amount, 160, 10 + i*config.zoom_amount ); } gr.DrawLine( pen_gray, 15, 10 + i*config.zoom_amount, 20, 10 + i*config.zoom_amount ); if ( config.show_detailed_weeks ) { if ( hours < config.work_start.Hours || hours > config.work_end.Hours ) { gr.DrawString( hours.ToString(), font_small, Brushes.LightGray, 1, 5 + i * config.zoom_amount ); } else { gr.DrawString( hours.ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount ); } } else { if ( config.GraphHours - i <= config.work_hours ) { gr.DrawString( ( config.GraphHours - i ).ToString(), font_small, Brushes.Black, 1, 5 + i * config.zoom_amount ); } else { gr.DrawString( ( config.GraphHours - i ).ToString(), font_small, Brushes.Red, 1, 5 + i * config.zoom_amount ); } } } // bar showing expected working hours if ( !config.show_detailed_weeks ) { int y = (int)(10 + ( config.GraphHours - config.work_hours ) * config.zoom_amount); if ( config.full_background_lines ) { gr.DrawLine( new Pen( Color.LightSkyBlue, 3 ), 20, y, 160, y ); } gr.DrawLine( new Pen( Color.DodgerBlue, 3 ), 15, y, 20, y ); } }
public WeekGraph( WorkingHoursConfiguration configuration, List< EventEntry >[] days, DateTime start_of_week, DateTime end_of_week ) { InitializeComponent(); DrawHours( configuration, days, start_of_week, end_of_week ); }
public void ShowDialog(IWin32Window owner, WorkingHoursConfiguration configuration, List <EventEntry> events) { if (events.Count > 0) { DateTime d = events[0].date; DateTime start_of_week = d.Subtract(new TimeSpan((int)(d.DayOfWeek) - 1, d.Hour, d.Minute, d.Second, d.Millisecond)); DateTime end_of_week = start_of_week.AddDays(7); int today = d.MondayFirstDoW(); // partition the events into weeks = array of days // then create 1 WeekGraph control for every week in the event list List <EventEntry>[] days = new List <EventEntry> [7]; for (int i = 0; i < 7; i++) { days[i] = new List <EventEntry>(); } foreach (EventEntry ee in events) { if (ee.date.CompareTo(end_of_week) >= 0) { // the next week has begun flp_weeks.Controls.Add(new WeekGraph(configuration, days, start_of_week, end_of_week)); days = new List <EventEntry> [7]; for (int i = 0; i < 7; i++) { days[i] = new List <EventEntry>(); } start_of_week = ee.date.Subtract(new TimeSpan((int)(ee.date.DayOfWeek) - 1, ee.date.Hour, ee.date.Minute, ee.date.Second, ee.date.Millisecond)); end_of_week = start_of_week.AddDays(7); } days[ee.date.MondayFirstDoW()].Add(ee); } Control last_weekgraph = new WeekGraph(configuration, days, start_of_week, end_of_week); flp_weeks.Controls.Add(last_weekgraph); // fit the parent form's area to the flowlayoutpanel as closely as possible... Rectangle working_area = Screen.GetWorkingArea(this); int controls_per_row = Math.Min(configuration.max_weeks_per_row, Math.Min(working_area.Width / flp_weeks.Controls[0].Width, flp_weeks.Controls.Count) ); int target_width = controls_per_row * flp_weeks.Controls[0].Width; int target_height = 0; int control_rows = ((flp_weeks.Controls.Count + controls_per_row - 1) / controls_per_row); // rounded up bool scrollbar_appeared = false; if (working_area.Height > 1.5 * control_rows * flp_weeks.Controls[0].Height) { target_height = ((flp_weeks.Controls.Count + controls_per_row - 1) / controls_per_row) * flp_weeks.Controls[0].Height; } else if (working_area.Height > flp_weeks.Controls[0].Height) { target_height = flp_weeks.Controls[0].Height; scrollbar_appeared = true; } else { target_height = working_area.Height * 8 / 10; scrollbar_appeared = true; } if (scrollbar_appeared) { target_width += SystemInformation.VerticalScrollBarWidth; } this.Width = 10 + target_width; this.Height = 10 + target_height + b_ok.Height + this.Height - this.ClientRectangle.Height; flp_weeks.ScrollControlIntoView(last_weekgraph); } ShowDialog(owner); }
protected void DrawBars(Graphics gr, WorkingHoursConfiguration config, List <EventEntry>[] days, DateTime start_of_week, DateTime end_of_week, out double work_hours_week, out double unlocked_hours_week) { double work_hours_day = 0; double unlocked_hours_day = 0; int work_days = 0; work_hours_week = 0; unlocked_hours_week = 0; BarCreator bar_creator = new BarCreator(config, start_of_week, end_of_week); for (int i = 0; i < days.Length; i++) { work_hours_day = 0; unlocked_hours_day = 0; foreach (EventEntry ee in days[i]) { Bar bar = bar_creator.GetBar(ee); if (config.show_detailed_weeks || bar == null) { DrawBar(gr, config, bar); } else { if (bar.is_unlocked) { unlocked_hours_day += bar.Height; } else { work_hours_day += bar.Height; } } } foreach (Bar b in bar_creator.GetFinalBarsForDay()) // last unlock - now { if (config.show_detailed_weeks) { DrawBar(gr, config, b); } else { if (b.is_unlocked) { unlocked_hours_day += b.Height; } else { work_hours_day += b.Height; } } } if (!config.show_detailed_weeks) { Bar b1 = new Bar(new SolidBrush(config.work_bar_color), i, false, start_of_week.AddDays(i), start_of_week.AddDays(i + work_hours_day / 24)); Bar b2 = new Bar(new SolidBrush(config.unlocked_bar_color), i, true, start_of_week.AddDays(i), start_of_week.AddDays(i + unlocked_hours_day / 24)); DrawBar(gr, config, b1); DrawBar(gr, config, b2); } if (work_hours_day > 0 || unlocked_hours_day > 0) { work_days++; } work_hours_week += work_hours_day; unlocked_hours_week += unlocked_hours_day; } work_hours_week /= work_days; unlocked_hours_week /= work_days; }
public WeekGraph(WorkingHoursConfiguration configuration, List <EventEntry>[] days, DateTime start_of_week, DateTime end_of_week) { InitializeComponent(); DrawHours(configuration, days, start_of_week, end_of_week); }