public bool AddStream(Stream stream) { // if the stream clashes with another stream if (!Fits(stream)) { return(false); } // add to list of streams Combination_.Add(stream); // run through list of classes foreach (Session session in stream.Classes) { // increase total time spent in classes TimeInClasses_ += session.Length; // if we're adding the class to an empty day if (ClassesByDay_[session.Day].Count == 0) { // increment day count Days_++; // add start and ending times to totals TotalStart_ += new TimeLength(session.StartTime.DayMinutes); TotalEnd_ += new TimeLength(session.EndTime.DayMinutes); // add length to total time at uni TimeAtUni_ += session.Length; } else { // if it's earlier than the earliest class of that day if (session.StartTime < ClassesByDay_[session.Day][0].StartTime) { TimeLength difference = ClassesByDay_[session.Day][0].StartTime - session.StartTime; // remove the difference for total start TotalStart_ -= difference; // add the difference for total time at uni TimeAtUni_ += difference; } // if it's later than the latest class if (session.EndTime > ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].EndTime) { TimeLength difference = session.EndTime - ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].EndTime; // add the difference for total end TotalEnd_ += difference; // add the difference for total time at uni TimeAtUni_ += difference; } } // update average day length AverageDayLength_ = TimeAtUni_ / Days_; // add new classes to day-indexed list ClassesByDay_[session.Day].Add(session); //ClassesByDay_[session.Day].Sort(); // check class start/end times against maxima/minima if (session.StartTime < EarlyStart_) { EarlyStart_ = session.StartTime; } if (session.StartTime > LateStart_) { LateStart_ = session.StartTime; } if (session.EndTime < EarlyEnd_) { EarlyEnd_ = session.EndTime; } if (session.EndTime > LateEnd_) { LateEnd_ = session.EndTime; } // check day length TimeLength dayLength = ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].EndTime - ClassesByDay_[session.Day][0].StartTime; if (dayLength < MinDayLength_) { MinDayLength_ = dayLength; } if (dayLength > MaxDayLength_) { MaxDayLength_ = dayLength; } } // clear break data NumberBreaks_ = 0; AverageBreak_ = new TimeLength(0, 0); ShortBreak_ = new TimeLength(24, 0); LongBreak_ = new TimeLength(0, 0); TimeInBreaks_ = new TimeLength(0, 0); // clear block data NumberBlocks_ = 0; AverageBlock_ = new TimeLength(0, 0); ShortBlock_ = new TimeLength(24, 0); LongBlock_ = new TimeLength(0, 0); // TODO: rewrite to avoid full sweep? // do a fresh sweep of all days to rebuild break/block data foreach (List <Session> daySessions in ClassesByDay_) { // empty day - skip if (daySessions.Count == 0) { continue; } // set up data for the start of the block TimeOfDay blockStart = daySessions[0].StartTime; TimeLength blockLength, breakLength; // compare adjacent classes int i; for (i = 1; i < daySessions.Count; i++) { breakLength = daySessions[i].StartTime - daySessions[i - 1].EndTime; // if there is at least ~15 minutes between the classes, call it a break, otherwise skip if (breakLength.TotalMinutes < MinBreak) { continue; } // find block length blockLength = daySessions[i - 1].EndTime - blockStart; // increment number of blocks NumberBlocks_++; // add block length to cumulative sum AverageBlock_ += blockLength; // set start of next block blockStart = daySessions[i].StartTime; // compare block against maxima/minima if (blockLength < ShortBlock_) { ShortBlock_ = blockLength; } if (blockLength > LongBlock_) { LongBlock_ = blockLength; } // increment number of breaks NumberBreaks_++; // add break to cumulative sum TimeInBreaks_ += breakLength; // compare break length against maxima/minima if (breakLength < ShortBreak_) { ShortBreak_ = breakLength; } // check if it's the longest break so far if (breakLength > LongBreak_) { LongBreak_ = breakLength; } } // also create a block at the end // find block length blockLength = daySessions[i - 1].EndTime - blockStart; // compare block against maxima/minima if (blockLength < ShortBlock_) { ShortBlock_ = blockLength; } if (blockLength > LongBlock_) { LongBlock_ = blockLength; } // increment number of blocks NumberBlocks_++; // add block length to cumulative sum AverageBlock_ += blockLength; } if (NumberBreaks_ > 0) { // divide the sum of breaks to find the mean AverageBreak_ = TimeInBreaks_ / NumberBreaks_; } // divide the sum of blocks to find the mean AverageBlock_ /= NumberBlocks_; AverageStart_ = new TimeOfDay(TotalStart_.TotalMinutes / Days_); AverageEnd_ = new TimeOfDay(TotalEnd_.TotalMinutes / Days_); return(true); }
protected override void OnDragOver(DragEventArgs drgevent) { TimeOfWeek time = FindClickTime(PointToClient(new Point(drgevent.X, drgevent.Y))); // outside of table bounds? if (TimeOfWeek.ReferenceEquals(time, null)) { // clear current preview (at edge of timetable) EndPreviewStream(); // cannot drag outside of the actual table drgevent.Effect = DragDropEffects.None; return; } // dragging a class if (drgevent.Data.GetDataPresent(typeof(Session)) || drgevent.Data.GetDataPresent(typeof(Type))) { drgevent.Effect = DragDropEffects.Move; Type dragType; if (drgevent.Data.GetDataPresent(typeof(Session))) { dragType = ((Session)drgevent.Data.GetData(typeof(Session))).Stream.Type; } else { dragType = (Type)drgevent.Data.GetData(typeof(Type)); } Session session = Timetable.From(dragType).FindClassAt(time, false); if (session == null) { EndPreviewStream(); } else { PreviewEquiv(session.Stream); } } // dragging an unavailability else if (drgevent.Data.GetDataPresent(typeof(Unavailability))) { Unavailability dragUnavail = (Unavailability)drgevent.Data.GetData(typeof(Unavailability)); TimeLength offset = new TimeLength(dragUnavail.StartMinute); TimeOfWeek start = time - dragUnavail.Length / 2; start -= offset; start.RoundToNearestHour(); start += offset; HoverUnavail_ = new Timeslot(start.Day, (TimeOfDay)start, (TimeOfDay)start + dragUnavail.Length); if (HoverUnavail_.StartTime < new TimeOfDay(HourStart_, 0) || HoverUnavail_.EndTime > new TimeOfDay(HourEnd_, 0)) { drgevent.Effect = DragDropEffects.None; HoverUnavail_ = null; } else { drgevent.Effect = DragDropEffects.Move; } Invalidate(); } else { base.OnDragOver(drgevent); } }
public bool ReCompute() { ClearComputation(); // check if each stream fits with the other streams /*for (int i = 0; i < Combination_.Count; i++) * { * for (int j = i + 1; j < Combination_.Count; j++) * { * if (Timetable_.LookupClashTable(Combination_[i], Combination_[j])) * return false; * } * }*/ // for each stream foreach (Stream stream in Combination_) { // for each session in each stream foreach (Session session in stream.Classes) { // build day-indexed list of classes ClassesByDay_[session.Day].Add(session); // calculate total time spent in classes TimeInClasses_ += session.Length; } } // for each day of classes foreach (List <Session> daySessions in ClassesByDay_) { // empty day - skip if (daySessions.Count == 0) { continue; } // otherwise increment day count Days_++; #region Breaks and blocks // set up data for the start of the block TimeOfDay blockStart = daySessions[0].StartTime; TimeLength blockLength, breakLength; // compare adjacent classes int i; for (i = 1; i < daySessions.Count; i++) { breakLength = daySessions[i].StartTime - daySessions[i - 1].EndTime; // if there is at least ~15 minutes between the classes, call it a break, otherwise skip if (breakLength.TotalMinutes < MinBreak) { continue; } // find block length blockLength = daySessions[i - 1].EndTime - blockStart; // increment number of blocks NumberBlocks_++; // add block length to cumulative sum AverageBlock_ += blockLength; // set start of next block blockStart = daySessions[i].StartTime; // compare block against maxima/minima if (blockLength < ShortBlock_) { ShortBlock_ = blockLength; } if (blockLength > LongBlock_) { LongBlock_ = blockLength; } // increment number of breaks NumberBreaks_++; // add break to cumulative sum TimeInBreaks_ += breakLength; // compare break length against maxima/minima if (breakLength < ShortBreak_) { ShortBreak_ = breakLength; } // check if it's the longest break so far if (breakLength > LongBreak_) { LongBreak_ = breakLength; } } // also create a block at the end // find block length blockLength = daySessions[i - 1].EndTime - blockStart; // compare block against maxima/minima if (blockLength < ShortBlock_) { ShortBlock_ = blockLength; } if (blockLength > LongBlock_) { LongBlock_ = blockLength; } // increment number of blocks NumberBlocks_++; // add block length to cumulative sum AverageBlock_ += blockLength; #endregion TimeOfDay dayStart = daySessions[0].StartTime; TimeOfDay dayEnd = daySessions[i - 1].EndTime; TimeLength dayLength = dayEnd - dayStart; // add to total time at uni TimeAtUni_ += dayLength; // check max/min if (dayLength > MaxDayLength_) { MaxDayLength_ = dayLength; } if (dayLength < MinDayLength_) { MinDayLength_ = dayLength; } // add to total time for start and end TotalStart_.TotalMinutes += dayStart.DayMinutes; TotalEnd_.TotalMinutes += dayEnd.DayMinutes; // check start/end min/max if (dayStart < EarlyStart_) { EarlyStart_ = dayStart; } if (dayStart > LateStart_) { LateStart_ = dayStart; } if (dayEnd < EarlyEnd_) { EarlyEnd_ = dayEnd; } if (dayEnd > LateEnd_) { LateEnd_ = dayEnd; } } // calculate averages using totals and counts if (NumberBreaks_ > 0) { AverageBreak_ = TimeInBreaks_ / NumberBreaks_; } AverageBlock_ /= NumberBlocks_; AverageStart_ = new TimeOfDay(TotalStart_.TotalMinutes / Days_); AverageEnd_ = new TimeOfDay(TotalEnd_.TotalMinutes / Days_); AverageDayLength_ = TimeAtUni_ / Days_; /* * // process all the streams * foreach (Stream stream in Combination_) * { * // run through list of classes * foreach (Session session in stream.Classes) * { * // increase total time spent in classes * TimeInClasses_ += session.Length; * * // if we're adding the class to an empty day * if (ClassesByDay_[session.Day].Count == 0) * { * // increment day count * Days_++; * // add start and ending times to totals * TotalStart_ += new TimeLength(session.Start.TotalMinutes); * TotalEnd_ += new TimeLength(session.End.TotalMinutes); * * // add length to total time at uni * TimeAtUni_ += session.Length; * } * else * { * // if it's earlier than the earliest class of that day * if (session.Start < ClassesByDay_[session.Day][0].Start) * { * TimeLength difference = ClassesByDay_[session.Day][0].Start - session.Start; * // remove the difference for total start * TotalStart_ -= difference; * // add the difference for total time at uni * TimeAtUni_ += difference; * } * // if it's later than the latest class * if (session.End > ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].End) * { * TimeLength difference = session.End - ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].End; * // add the difference for total end * TotalStart_ += difference; * // add the difference for total time at uni * TimeAtUni_ += difference; * } * } * // update average day length * AverageDayLength_ = TimeAtUni_ / Days_; * * // add new classes to day-indexed list * ClassesByDay_[session.Day].Add(session); * ClassesByDay_[session.Day].Sort(); * * // check class start/end times against maxima/minima * if (session.Start < EarlyStart_) * EarlyStart_ = session.Start; * if (session.Start > LateStart_) * LateStart_ = session.Start; * if (session.End < EarlyEnd_) * EarlyEnd_ = session.End; * if (session.End > LateEnd_) * LateEnd_ = session.End; * * // check day length * TimeLength dayLength = ClassesByDay_[session.Day][ClassesByDay_[session.Day].Count - 1].End - * ClassesByDay_[session.Day][0].Start; * if (dayLength < MinDayLength_) * MinDayLength_ = dayLength; * if (dayLength > MaxDayLength_) * MaxDayLength_ = dayLength; * } * } * * // clear break data * NumberBreaks_ = 0; * AverageBreak_ = new TimeLength(0, 0); * ShortBreak_ = new TimeLength(24, 0); * LongBreak_ = new TimeLength(0, 0); * TimeInBreaks_ = new TimeLength(0, 0); * // clear block data * NumberBlocks_ = 0; * AverageBlock_ = new TimeLength(0, 0); * ShortBlock_ = new TimeLength(24, 0); * LongBlock_ = new TimeLength(0, 0); * // TODO: rewrite to avoid full sweep? * // do a fresh sweep of all days to rebuild break/block data * foreach (List<Session> daySessions in ClassesByDay_) * { * // set up data for the start of the block * TimeOfDay blockStart; * if (daySessions.Count > 0) * blockStart = daySessions[0].Start; * else * blockStart = new TimeOfDay(); * * // compare adjacent classes * for (int i = 1; i < daySessions.Count; i++) * { * TimeLength breakLength = daySessions[i].Start - daySessions[i - 1].End; * * // if there's a break between classes, make a block * if (breakLength.TotalMinutes >= MinBreak) * { * // find block length * TimeLength blockLength = daySessions[i - 1].End - blockStart; * // compare block against maxima/minima * if (blockLength < ShortBlock_) * ShortBlock_ = blockLength; * if (blockLength > LongBlock_) * LongBlock_ = blockLength; * * // increment number of blocks * NumberBlocks_++; * // add block length to cumulative sum * AverageBlock_ += blockLength; * // set start of next block * blockStart = daySessions[i].Start; * } * // also create a block at the end * if (i == daySessions.Count - 1) * { * // find block length * TimeLength blockLength = daySessions[i].End - blockStart; * // compare block against maxima/minima * if (blockLength < ShortBlock_) * ShortBlock_ = blockLength; * if (blockLength > LongBlock_) * LongBlock_ = blockLength; * * // increment number of blocks * NumberBlocks_++; * // add block length to cumulative sum * AverageBlock_ += blockLength; * } * * // if there is at least ~15 minutes between the classes, call it a break, otherwise skip * if (breakLength.TotalMinutes < MinBreak) * continue; * * // increment number of breaks * NumberBreaks_++; * // add break to cumulative sum * TimeInBreaks_ += breakLength; * * // compare break length against maxima/minima * if (breakLength < ShortBreak_) * ShortBreak_ = breakLength; * // check if it's the longest break so far * if (breakLength > LongBreak_) * LongBreak_ = breakLength; * } * } * // divide the sum of breaks to find the mean * AverageBreak_ = TimeInBreaks_ / NumberBreaks_; * // divide the sum of blocks to find the mean * AverageBlock_ /= NumberBlocks_;*/ return(true); }
public Rectangle TimeLengthRectangle(TimeLength t) { return(new Rectangle(0, 0, Cell_.Width, (int)(t.TotalMinutes / 60.0f * Cell_.Height))); }