Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GrammaticalOptimization/DynamicDataDisplay/Charts/Axes/DateTimeTicksProvider.cs @ 14161

Last change on this file since 14161 was 12503, checked in by aballeit, 9 years ago

#2283 added GUI and charts; fixed MCTS

File size: 12.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Diagnostics;
6using System.Globalization;
7using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
8
9namespace Microsoft.Research.DynamicDataDisplay.Charts.NewAxis
10{
11  public class DateTimeTicksProvider : DateTimeTicksProviderBase
12  {
13    private static readonly Dictionary<DifferenceIn, ITicksProvider<DateTime>> providers =
14      new Dictionary<DifferenceIn, ITicksProvider<DateTime>>();
15
16    static DateTimeTicksProvider()
17    {
18      providers.Add(DifferenceIn.Year, new YearProvider());
19      providers.Add(DifferenceIn.Month, new MonthProvider());
20      providers.Add(DifferenceIn.Day, new DayProvider());
21      providers.Add(DifferenceIn.Hour, new HourProvider());
22      providers.Add(DifferenceIn.Minute, new MinuteProvider());
23      providers.Add(DifferenceIn.Second, new SecondProvider());
24    }
25
26    private DifferenceIn diff;
27    /// <summary>
28    /// Gets the ticks.
29    /// </summary>
30    /// <param name="range">The range.</param>
31    /// <param name="ticksCount">The ticks count.</param>
32    /// <returns></returns>
33    public override ITicksInfo<DateTime> GetTicks(Range<DateTime> range, int ticksCount)
34    {
35      Verify.Is(ticksCount > 0);
36
37      DateTime start = range.Min;
38      DateTime end = range.Max;
39      TimeSpan length = end - start;
40
41      diff = GetDifference(length);
42
43      TicksInfo<DateTime> res = new TicksInfo<DateTime> { Info = diff };
44      if (providers.ContainsKey(diff))
45      {
46        ITicksInfo<DateTime> result = providers[diff].GetTicks(range, ticksCount);
47        DateTime[] mayorTicks = result.Ticks;
48
49        res.Ticks = mayorTicks;
50
51        DifferenceIn lowerDiff = DifferenceIn.Year;
52        // todo разобраться с minor ticks
53        bool lowerDiffExists = TryGetLowerDiff(diff, out lowerDiff);
54        if (lowerDiffExists && providers.ContainsKey(lowerDiff))
55        {
56          var minorTicks = result.Ticks.GetPairs().Select(r => ((IMinorTicksProvider<DateTime>)providers[lowerDiff]).CreateTicks(r)).
57            SelectMany(m => m).ToArray();
58
59          res.MinorTicks = minorTicks;
60        }
61        return res;
62      }
63
64
65      DateTime newStart = RoundDown(start, diff);
66      DateTime newEnd = RoundUp(end, diff);
67
68      DebugVerify.Is(newStart <= start);
69
70      List<DateTime> resultTicks = new List<DateTime>();
71      DateTime dt = newStart;
72      do
73      {
74        resultTicks.Add(dt);
75        dt = Shift(dt, diff);
76      } while (dt <= newEnd);
77
78      while (resultTicks.Count > ticksCount)
79      {
80        var res2 = resultTicks;
81        resultTicks = res2.Where((date, i) => i % 2 == 0).ToList();
82      }
83
84      res.Ticks = resultTicks.ToArray();
85
86      return res;
87    }
88
89    /// <summary>
90    /// Tries the get lower diff.
91    /// </summary>
92    /// <param name="diff">The diff.</param>
93    /// <param name="lowerDiff">The lower diff.</param>
94    /// <returns></returns>
95    private static bool TryGetLowerDiff(DifferenceIn diff, out DifferenceIn lowerDiff)
96    {
97      lowerDiff = diff;
98
99      int code = (int)diff;
100      bool res = code > 0;
101      if (res)
102      {
103        lowerDiff = (DifferenceIn)(code - 1);
104      }
105      return res;
106    }
107
108    /// <summary>
109    /// Decreases the tick count.
110    /// </summary>
111    /// <param name="tickCount">The tick count.</param>
112    /// <returns></returns>
113    public override int DecreaseTickCount(int tickCount)
114    {
115      if (providers.ContainsKey(diff))
116        return providers[diff].DecreaseTickCount(tickCount);
117
118      int res = tickCount / 2;
119      if (res < 2) res = 2;
120      return res;
121    }
122
123    /// <summary>
124    /// Increases the tick count.
125    /// </summary>
126    /// <param name="tickCount">The tick count.</param>
127    /// <returns></returns>
128    public override int IncreaseTickCount(int tickCount)
129    {
130      DebugVerify.Is(tickCount < 2000);
131
132      if (providers.ContainsKey(diff))
133        return providers[diff].IncreaseTickCount(tickCount);
134
135      return tickCount * 2;
136    }
137  }
138
139  public enum DifferenceIn
140  {
141    Year = 7,
142    Month = 6,
143    Day = 5,
144    Hour = 4,
145    Minute = 3,
146    Second = 2,
147    Millisecond = 1
148  }
149
150  internal static class DateTimeArrayExt
151  {
152    [Obsolete("Works wrongly", true)]
153    internal static DateTime[] Clip(this DateTime[] array, DateTime start, DateTime end)
154    {
155      if (start > end)
156      {
157        DateTime temp = start;
158        start = end;
159        end = temp;
160      }
161
162      int startIndex = array.GetIndex(start);
163      int endIndex = array.GetIndex(end) + 1;
164      DateTime[] res = new DateTime[endIndex - startIndex];
165      Array.Copy(array, startIndex, res, 0, res.Length);
166
167      return res;
168    }
169
170    internal static int GetIndex(this DateTime[] array, DateTime value)
171    {
172      for (int i = 0; i < array.Length - 1; i++)
173      {
174        if (array[i] <= value && value < array[i + 1])
175          return i;
176      }
177
178      return array.Length - 1;
179    }
180  }
181
182  internal abstract class DatePeriodTicksProvider : DateTimeTicksProviderBase, IMinorTicksProvider<DateTime>
183  {
184    protected DatePeriodTicksProvider()
185    {
186      tickCounts = GetTickCountsCore();
187      difference = GetDifferenceCore();
188    }
189
190    protected DifferenceIn difference;
191    protected abstract DifferenceIn GetDifferenceCore();
192
193    protected abstract int[] GetTickCountsCore();
194    protected int[] tickCounts = { };
195
196    public sealed override int DecreaseTickCount(int ticksCount)
197    {
198      if (ticksCount > tickCounts[0]) return tickCounts[0];
199
200      for (int i = 0; i < tickCounts.Length; i++)
201        if (ticksCount > tickCounts[i])
202          return tickCounts[i];
203
204      return tickCounts.Last();
205    }
206
207    public sealed override int IncreaseTickCount(int ticksCount)
208    {
209      if (ticksCount >= tickCounts[0]) return tickCounts[0];
210
211      for (int i = tickCounts.Length - 1; i >= 0; i--)
212        if (ticksCount < tickCounts[i])
213          return tickCounts[i];
214
215      return tickCounts.Last();
216    }
217
218    protected abstract int GetSpecificValue(DateTime start, DateTime dt);
219    protected abstract DateTime GetStart(DateTime start, int value, int step);
220    protected abstract bool IsMinDate(DateTime dt);
221    protected abstract DateTime AddStep(DateTime dt, int step);
222
223    public sealed override ITicksInfo<DateTime> GetTicks(Range<DateTime> range, int ticksCount)
224    {
225      DateTime start = range.Min;
226      DateTime end = range.Max;
227      TimeSpan length = end - start;
228
229      bool isPositive = length.Ticks > 0;
230      DifferenceIn diff = difference;
231
232      DateTime newStart = isPositive ? RoundDown(start, diff) : SafelyRoundUp(start);
233      DateTime newEnd = isPositive ? SafelyRoundUp(end) : RoundDown(end, diff);
234
235      RoundingInfo bounds = RoundHelper.CreateRoundedRange(GetSpecificValue(newStart, newStart), GetSpecificValue(newStart, newEnd));
236
237      int delta = (int)(bounds.Max - bounds.Min);
238      if (delta == 0)
239        return new TicksInfo<DateTime> { Ticks = new DateTime[] { newStart } };
240
241      int step = delta / ticksCount;
242
243      if (step == 0) step = 1;
244
245      DateTime tick = GetStart(newStart, (int)bounds.Min, step);
246      bool isMinDateTime = IsMinDate(tick) && step != 1;
247      if (isMinDateTime)
248        step--;
249
250      List<DateTime> ticks = new List<DateTime>();
251      DateTime finishTick = AddStep(range.Max, step);
252      while (tick < finishTick)
253      {
254        ticks.Add(tick);
255        tick = AddStep(tick, step);
256        if (isMinDateTime)
257        {
258          isMinDateTime = false;
259          step++;
260        }
261      }
262
263      TicksInfo<DateTime> res = new TicksInfo<DateTime> { Ticks = ticks.ToArray(), Info = diff };
264      return res;
265    }
266
267    private DateTime SafelyRoundUp(DateTime dt)
268    {
269      if (AddStep(dt, 1) == DateTime.MaxValue)
270        return DateTime.MaxValue;
271
272      return RoundUp(dt, difference);
273    }
274
275    #region IMinorTicksProvider<DateTime> Members
276
277    public MinorTickInfo<DateTime>[] CreateTicks(Range<DateTime> range)
278    {
279      int tickCount = tickCounts[1];
280      ITicksInfo<DateTime> ticks = GetTicks(range, tickCount);
281
282      MinorTickInfo<DateTime>[] res = ticks.Ticks.
283        Select(dt => new MinorTickInfo<DateTime>(0.5, dt)).ToArray();
284
285      return res;
286    }
287
288    #endregion
289  }
290
291  internal class YearProvider : DatePeriodTicksProvider
292  {
293    protected override DifferenceIn GetDifferenceCore()
294    {
295      return DifferenceIn.Year;
296    }
297
298    protected override int[] GetTickCountsCore()
299    {
300      return new int[] { 20, 10, 5, 4, 2, 1 };
301    }
302
303    protected override int GetSpecificValue(DateTime start, DateTime dt)
304    {
305      return dt.Year;
306    }
307
308    protected override DateTime GetStart(DateTime start, int value, int step)
309    {
310      int year = start.Year;
311      int newYear = (year / step) * step;
312      if (newYear == 0) newYear = 1;
313
314      return new DateTime(newYear, 1, 1);
315    }
316
317    protected override bool IsMinDate(DateTime dt)
318    {
319      return dt.Year == DateTime.MinValue.Year;
320    }
321
322    protected override DateTime AddStep(DateTime dt, int step)
323    {
324      if (dt.Year + step > DateTime.MaxValue.Year)
325        return DateTime.MaxValue;
326
327      return dt.AddYears(step);
328    }
329  }
330
331  internal class MonthProvider : DatePeriodTicksProvider
332  {
333    protected override DifferenceIn GetDifferenceCore()
334    {
335      return DifferenceIn.Month;
336    }
337
338    protected override int[] GetTickCountsCore()
339    {
340      return new int[] { 12, 6, 4, 3, 2, 1 };
341    }
342
343    protected override int GetSpecificValue(DateTime start, DateTime dt)
344    {
345      return dt.Month + (dt.Year - start.Year) * 12;
346    }
347
348    protected override DateTime GetStart(DateTime start, int value, int step)
349    {
350      return new DateTime(start.Year, 1, 1);
351    }
352
353    protected override bool IsMinDate(DateTime dt)
354    {
355      return dt.Month == DateTime.MinValue.Month;
356    }
357
358    protected override DateTime AddStep(DateTime dt, int step)
359    {
360      return dt.AddMonths(step);
361    }
362  }
363
364  internal class DayProvider : DatePeriodTicksProvider
365  {
366    protected override DifferenceIn GetDifferenceCore()
367    {
368      return DifferenceIn.Day;
369    }
370
371    protected override int[] GetTickCountsCore()
372    {
373      return new int[] { 30, 15, 10, 5, 2, 1 };
374    }
375
376    protected override int GetSpecificValue(DateTime start, DateTime dt)
377    {
378      return (dt - start).Days;
379    }
380
381    protected override DateTime GetStart(DateTime start, int value, int step)
382    {
383      return start.Date;
384    }
385
386    protected override bool IsMinDate(DateTime dt)
387    {
388      return dt.Day == 1;
389    }
390
391    protected override DateTime AddStep(DateTime dt, int step)
392    {
393      return dt.AddDays(step);
394    }
395  }
396
397  internal class HourProvider : DatePeriodTicksProvider
398  {
399    protected override DifferenceIn GetDifferenceCore()
400    {
401      return DifferenceIn.Hour;
402    }
403
404    protected override int[] GetTickCountsCore()
405    {
406      return new int[] { 24, 12, 6, 4, 3, 2, 1 };
407    }
408
409    protected override int GetSpecificValue(DateTime start, DateTime dt)
410    {
411      return (dt - start).Hours;
412    }
413
414    protected override DateTime GetStart(DateTime start, int value, int step)
415    {
416      return start.Date;//.AddHours(start.Hour);
417    }
418
419    protected override bool IsMinDate(DateTime dt)
420    {
421      return false;
422    }
423
424    protected override DateTime AddStep(DateTime dt, int step)
425    {
426      return dt.AddHours(step);
427    }
428  }
429
430  internal class MinuteProvider : DatePeriodTicksProvider
431  {
432    protected override DifferenceIn GetDifferenceCore()
433    {
434      return DifferenceIn.Minute;
435    }
436
437    protected override int[] GetTickCountsCore()
438    {
439      return new int[] { 60, 30, 20, 15, 10, 5, 4, 3, 2 };
440    }
441
442    protected override int GetSpecificValue(DateTime start, DateTime dt)
443    {
444      return (dt - start).Minutes;
445    }
446
447    protected override DateTime GetStart(DateTime start, int value, int step)
448    {
449      return start.Date.AddHours(start.Hour);
450    }
451
452    protected override bool IsMinDate(DateTime dt)
453    {
454      return false;
455    }
456
457    protected override DateTime AddStep(DateTime dt, int step)
458    {
459      return dt.AddMinutes(step);
460    }
461  }
462
463  internal class SecondProvider : DatePeriodTicksProvider
464  {
465    protected override DifferenceIn GetDifferenceCore()
466    {
467      return DifferenceIn.Second;
468    }
469
470    protected override int[] GetTickCountsCore()
471    {
472      return new int[] { 60, 30, 20, 15, 10, 5, 4, 3, 2 };
473    }
474
475    protected override int GetSpecificValue(DateTime start, DateTime dt)
476    {
477      return (dt - start).Seconds;
478    }
479
480    protected override DateTime GetStart(DateTime start, int value, int step)
481    {
482      return start.Date.AddHours(start.Hour).AddMinutes(start.Minute);
483    }
484
485    protected override bool IsMinDate(DateTime dt)
486    {
487      return false;
488    }
489
490    protected override DateTime AddStep(DateTime dt, int step)
491    {
492      return dt.AddSeconds(step);
493    }
494  }
495}
Note: See TracBrowser for help on using the repository browser.