Пример #1
0
        /// <summary>
        /// Gets label values for a series vector.
        /// </summary>
        /// <param name="Min">Smallest value.</param>
        /// <param name="Max">Largest value.</param>
        /// <param name="ApproxNrLabels">Number of labels.</param>
        /// <param name="LabelType">Type of labels produced.</param>
        /// <returns>Vector of labels.</returns>
        public static DateTime[] GetLabels(DateTime Min, DateTime Max, int ApproxNrLabels, out LabelType LabelType)
        {
            List <DateTime> Labels = new List <DateTime>();
            TimeSpan        Span = Max - Min;
            TimeSpan        StepSize = Span == TimeSpan.Zero ? new TimeSpan(0, 0, 1) : new TimeSpan((Span.Ticks + (ApproxNrLabels >> 1)) / ApproxNrLabels);
            int             i, c;

            for (i = 0, c = timeStepSizes.Length - 2; i < c; i++)
            {
                if (StepSize >= timeStepSizes[i] && StepSize < timeStepSizes[i + 1])
                {
                    break;
                }
            }

            int Nr1 = (int)Math.Round(Span.TotalSeconds / timeStepSizes[i].TotalSeconds);
            int Diff1 = Math.Abs(ApproxNrLabels - Nr1);

            int Nr2 = (int)Math.Round(Span.TotalSeconds / timeStepSizes[i + 1].TotalSeconds);
            int Diff2 = Math.Abs(ApproxNrLabels - Nr1);

            if (Diff1 < Diff2)
            {
                StepSize = timeStepSizes[i];
            }
            else
            {
                StepSize = timeStepSizes[i + 1];
            }

            if (StepSize.TotalDays >= 1)
            {
                DateTime TP;

                TP = Min.Date;
                if (Min.TimeOfDay != TimeSpan.Zero)
                {
                    TP = TP.AddDays(1);
                }

                Nr1   = (int)Math.Floor((Max - TP).TotalDays);
                Diff1 = Math.Abs(ApproxNrLabels - Nr1);

                Nr2   = (int)Math.Floor((Max - TP).TotalDays / 2);
                Diff2 = Math.Abs(ApproxNrLabels - Nr2);

                if (Diff1 <= Diff2)
                {
                    LabelType = LabelType.DateTimeDate;

                    while (TP <= Max)
                    {
                        Labels.Add(TP);
                        TP = TP.AddDays(1);
                    }
                }
                else
                {
                    Nr1   = Nr2;
                    Diff1 = Diff2;

                    Nr2   = (int)Math.Floor((Max - TP).TotalDays / 7);
                    Diff2 = Math.Abs(ApproxNrLabels - Nr2);

                    if (Diff1 <= Diff2)
                    {
                        LabelType = LabelType.DateTimeDate;                         // Step every 2 days.

                        while (TP <= Max)
                        {
                            Labels.Add(TP);
                            TP = TP.AddDays(2);
                        }
                    }
                    else
                    {
                        Nr1   = Nr2;
                        Diff1 = Diff2;

                        Nr2   = (int)Math.Floor((Max - TP).TotalDays / 30);
                        Diff2 = Math.Abs(ApproxNrLabels - Nr2);

                        if (Diff1 <= Diff2)
                        {
                            LabelType = LabelType.DateTimeWeek;

                            i = (int)TP.DayOfWeek;
                            if (i == 0)
                            {
                                TP = TP.AddDays(1);
                            }
                            else if (i != 1)
                            {
                                TP = TP.AddDays(8 - i);
                            }

                            while (TP <= Max)
                            {
                                Labels.Add(TP);
                                TP = TP.AddDays(7);
                            }
                        }
                        else
                        {
                            Nr1   = Nr2;
                            Diff1 = Diff2;

                            Nr2   = (int)Math.Floor((Max - TP).TotalDays / 180);
                            Diff2 = Math.Abs(ApproxNrLabels - Nr2);

                            if (Diff1 <= Diff2)
                            {
                                LabelType = LabelType.DateTimeMonth;

                                if (TP.Day != 1)
                                {
                                    TP = TP.AddDays(-TP.Day + 1).AddMonths(1);
                                }

                                while (TP <= Max)
                                {
                                    Labels.Add(TP);
                                    TP = TP.AddMonths(1);
                                }
                            }
                            else
                            {
                                Nr1   = Nr2;
                                Diff1 = Diff2;

                                Nr2   = (int)Math.Floor((Max - TP).TotalDays / 700);
                                Diff2 = Math.Abs(ApproxNrLabels - Nr2);

                                if (Diff1 <= Diff2)
                                {
                                    LabelType = LabelType.DateTimeQuarter;

                                    if (TP.Day != 1)
                                    {
                                        TP = TP.AddDays(-TP.Day + 1).AddMonths(1);
                                    }

                                    i = (TP.Month - 1) % 3;
                                    if (i != 0)
                                    {
                                        TP = TP.AddMonths(3 - i);
                                    }

                                    while (TP <= Max)
                                    {
                                        Labels.Add(TP);
                                        TP = TP.AddMonths(3);
                                    }
                                }
                                else
                                {
                                    LabelType = LabelType.DateTimeYear;

                                    i = (int)Math.Floor(GetStepSize((Min - referenceTimestamp).TotalDays / 365.25,
                                                                    (Max - referenceTimestamp).TotalDays / 365.25, ApproxNrLabels));
                                    if (i == 0)
                                    {
                                        i++;
                                    }

                                    if (TP.Day > 1)
                                    {
                                        TP = TP.AddDays(-TP.Day + 1).AddMonths(1);
                                    }

                                    if (TP.Month > 1)
                                    {
                                        TP = TP.AddMonths(13 - TP.Month);
                                    }

                                    c = TP.Year % i;
                                    if (c > 0)
                                    {
                                        TP = TP.AddYears(i - c);
                                    }

                                    while (TP <= Max)
                                    {
                                        Labels.Add(TP);
                                        TP = TP.AddYears(i);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                long Ticks    = Min.Ticks;
                long MaxTicks = Max.Ticks;
                long Step     = StepSize.Ticks;
                long Residue  = Ticks % Step;
                if (Residue > 0)
                {
                    Ticks += Step - Residue;
                }

                while (Ticks <= MaxTicks)
                {
                    Labels.Add(new DateTime(Ticks));
                    Ticks += Step;
                }

                if (StepSize.TotalMinutes >= 1)
                {
                    LabelType = LabelType.DateTimeShortTime;
                }
                else
                {
                    LabelType = LabelType.DateTimeLongTime;
                }
            }

            return(Labels.ToArray());
        }