public PeriodMatrix( StudyDay day )
            {
                _positions = new Dictionary<Period, int>();
                _widthMultipliers = new Dictionary<Period, double>();

                int[] periodsPerInterval = new int[HoursInDay * MinutesInHour / CollisionCheckingInterval];

                foreach ( var period in day.Periods )
                {
                    IterateOverIntervals( period, n => periodsPerInterval[n]++ );
                }

                ColumnCount = periodsPerInterval.Max();
                int[] remainingPeriods = (int[]) periodsPerInterval.Clone();

                // First order the periods by number of periods that collide, otherwise the algorithm fails.
                // e.g.
                //       ---------
                // --------  -----
                // if we don't handle the top one first, both it and the first bottom one will be in column 1.
                var totalCollisionsPerPeriods =
                    day.Periods.ToDictionary( p => p,
                        p => day.Periods.Count( p2 =>
                            ( p2.Start >= p.Start && p2.Start < p.End ) // start is inside the period
                            || ( p2.End >= p.Start && p2.End < p.End ) // end is inside the period
                            || ( p2.Start <= p.Start && p2.End >= p.End ) // start and end surround the period
                            ) );

                foreach ( var pair in totalCollisionsPerPeriods.OrderByDescending( p => p.Value ) )
                {
                    var period = pair.Key;
                    int collisions = 1;
                    int column = 0;

                    IterateOverIntervals( period, n => collisions = Math.Max( collisions, periodsPerInterval[n] ) );
                    IterateOverIntervals( period, n => { remainingPeriods[n]--; column = Math.Max( column, remainingPeriods[n] ); } );

                    _positions.Add( period, column );
                    _widthMultipliers.Add( period, 1.0 / collisions );
                }
            }
        private void AddPeriodsToCanvas( Canvas canvas, Size size, StudyDay day )
        {
            var matrix = new PeriodMatrix( day );

            double heightPerMinute = size.Height / ( ( _maxHour - _minHour ) * MinutesInHour );
            double widthPerColumn = size.Width / matrix.ColumnCount;
            var startDate = day.Day.AddHours( _minHour );

            foreach ( var period in day.Periods )
            {
                var control = new ContentControl
                {
                    ContentTemplate = PeriodTemplate,
                    Content = period,
                    Style = ContainerStyle,
                    Height = ( period.End - period.Start ).TotalMinutes * heightPerMinute,
                    Width = matrix.GetWidthMultiplier( period ) * size.Width
                };

                Canvas.SetTop( control, ( period.Start - startDate ).TotalMinutes * heightPerMinute );
                Canvas.SetLeft( control, widthPerColumn * matrix.GetColumn( period ) );

                canvas.Children.Add( control );
            }
        }
 private static Tuple<int, int> GetHourBoundaries( StudyDay[] days )
 {
     int min = days.Min( d => d.Periods.Any() ? d.Periods.Min( p => p.Start.Hour ) : EmptyScheduleStart );
     int max = days.Max( d => d.Periods.Any() ? d.Periods.Max( p => HourCeiling( p.End.TimeOfDay ) ) : EmptyScheduleEnd );
     if ( min + MinimumHoursInDay > HoursInDay )
     {
         min = max - MinimumHoursInDay;
     }
     else
     {
         max = Math.Max( max, min + MinimumHoursInDay );
     }
     return Tuple.Create( min, max );
 }
Beispiel #4
0
            /// <summary>
            /// Creates a new PeriodMatrix for the specified day's periods.
            /// </summary>
            public PeriodMatrix( StudyDay day )
            {
                _positions = new Dictionary<Period, int>();
                _widthMultipliers = new Dictionary<Period, double>();

                int[] periodsPerInterval = new int[HoursInDay * MinutesInHour / CollisionCheckingInterval];

                foreach ( var period in day.Periods )
                {
                    IterateOverIntervals( period, periodsPerInterval, n => periodsPerInterval[n]++ );
                }

                ColumnCount = periodsPerInterval.Max();
                int[] remainingPeriods = (int[]) periodsPerInterval.Clone();

                foreach ( var period in day.Periods )
                {
                    int collisions = 1;
                    int column = 0;

                    IterateOverIntervals( period, periodsPerInterval, n => collisions = Math.Max( collisions, periodsPerInterval[n] ) );
                    IterateOverIntervals( period, remainingPeriods, n => { remainingPeriods[n]--; column = Math.Max( column, remainingPeriods[n] ); } );

                    _positions.Add( period, column );
                    _widthMultipliers.Add( period, 1.0 / collisions );
                }
            }