/Main/src/DynamicDataDisplay/Charts/Axes/TimeSpan/TimeTicksProviderBase.cs
C# | 159 lines | 119 code | 28 blank | 12 comment | 13 complexity | 1f624e7ff6fc76c2895be95e94ba22c9 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary; 6 7namespace Microsoft.Research.DynamicDataDisplay.Charts 8{ 9 public abstract class TimeTicksProviderBase<T> : ITicksProvider<T> 10 { 11 public event EventHandler Changed; 12 protected void RaiseChanged() 13 { 14 if (Changed != null) 15 { 16 Changed(this, EventArgs.Empty); 17 } 18 } 19 20 private static readonly Dictionary<DifferenceIn, ITicksProvider<T>> providers = 21 new Dictionary<DifferenceIn, ITicksProvider<T>>(); 22 23 protected static Dictionary<DifferenceIn, ITicksProvider<T>> Providers 24 { 25 get { return TimeTicksProviderBase<T>.providers; } 26 } 27 28 private static readonly Dictionary<DifferenceIn, ITicksProvider<T>> minorProviders = 29 new Dictionary<DifferenceIn, ITicksProvider<T>>(); 30 31 protected static Dictionary<DifferenceIn, ITicksProvider<T>> MinorProviders 32 { 33 get { return TimeTicksProviderBase<T>.minorProviders; } 34 } 35 36 protected abstract TimeSpan GetDifference(T start, T end); 37 38 #region ITicksProvider<T> Members 39 40 private IDateTimeTicksStrategy strategy = new DefaultDateTimeTicksStrategy(); 41 public IDateTimeTicksStrategy Strategy 42 { 43 get { return strategy; } 44 set 45 { 46 if (strategy != value) 47 { 48 strategy = value; 49 RaiseChanged(); 50 } 51 } 52 } 53 54 private ITicksInfo<T> result; 55 private DifferenceIn diff; 56 57 public ITicksInfo<T> GetTicks(Range<T> range, int ticksCount) 58 { 59 Verify.IsTrue(ticksCount > 0); 60 61 T start = range.Min; 62 T end = range.Max; 63 TimeSpan length = GetDifference(start, end); 64 65 diff = strategy.GetDifference(length); 66 67 TicksInfo<T> result = new TicksInfo<T> { Info = diff }; 68 if (providers.ContainsKey(diff)) 69 { 70 ITicksInfo<T> innerResult = providers[diff].GetTicks(range, ticksCount); 71 T[] ticks = ModifyTicksGuard(innerResult.Ticks, diff); 72 73 result.Ticks = ticks; 74 this.result = result; 75 return result; 76 } 77 78 throw new InvalidOperationException(Strings.Exceptions.UnsupportedRangeInAxis); 79 } 80 81 private T[] ModifyTicksGuard(T[] ticks, object info) 82 { 83 var result = ModifyTicks(ticks, info); 84 if (result == null) 85 throw new ArgumentNullException("ticks"); 86 87 return result; 88 } 89 90 protected virtual T[] ModifyTicks(T[] ticks, object info) 91 { 92 return ticks; 93 } 94 95 /// <summary> 96 /// Decreases the tick count. 97 /// </summary> 98 /// <param name="tickCount">The tick count.</param> 99 /// <returns></returns> 100 public int DecreaseTickCount(int ticksCount) 101 { 102 if (providers.ContainsKey(diff)) 103 return providers[diff].DecreaseTickCount(ticksCount); 104 105 int res = ticksCount / 2; 106 if (res < 2) res = 2; 107 return res; 108 } 109 110 /// <summary> 111 /// Increases the tick count. 112 /// </summary> 113 /// <param name="ticksCount">The tick count.</param> 114 /// <returns></returns> 115 public int IncreaseTickCount(int ticksCount) 116 { 117 DebugVerify.Is(ticksCount < 2000); 118 119 if (providers.ContainsKey(diff)) 120 return providers[diff].IncreaseTickCount(ticksCount); 121 122 return ticksCount * 2; 123 } 124 125 public ITicksProvider<T> MinorProvider 126 { 127 get 128 { 129 DifferenceIn smallerDiff = DifferenceIn.Smallest; 130 if (strategy.TryGetLowerDiff(diff, out smallerDiff) && minorProviders.ContainsKey(smallerDiff)) 131 { 132 var minorProvider = (MinorTimeProviderBase<T>)minorProviders[smallerDiff]; 133 minorProvider.SetTicks(result.Ticks); 134 return minorProvider; 135 } 136 137 return null; 138 // todo What to do if this already is the smallest provider? 139 } 140 } 141 142 public ITicksProvider<T> MajorProvider 143 { 144 get 145 { 146 DifferenceIn biggerDiff = DifferenceIn.Smallest; 147 if (strategy.TryGetBiggerDiff(diff, out biggerDiff)) 148 { 149 return providers[biggerDiff]; 150 } 151 152 return null; 153 // todo What to do if this already is the biggest provider? 154 } 155 } 156 157 #endregion 158 } 159}