using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary; namespace Microsoft.Research.DynamicDataDisplay.Charts { public abstract class TimeTicksProviderBase : ITicksProvider { public event EventHandler Changed; protected void RaiseChanged() { if (Changed != null) { Changed(this, EventArgs.Empty); } } private static readonly Dictionary> providers = new Dictionary>(); protected static Dictionary> Providers { get { return TimeTicksProviderBase.providers; } } private static readonly Dictionary> minorProviders = new Dictionary>(); protected static Dictionary> MinorProviders { get { return TimeTicksProviderBase.minorProviders; } } protected abstract TimeSpan GetDifference(T start, T end); #region ITicksProvider Members private IDateTimeTicksStrategy strategy = new DefaultDateTimeTicksStrategy(); public IDateTimeTicksStrategy Strategy { get { return strategy; } set { if (strategy != value) { strategy = value; RaiseChanged(); } } } private ITicksInfo result; private DifferenceIn diff; public ITicksInfo GetTicks(Range range, int ticksCount) { Verify.IsTrue(ticksCount > 0); T start = range.Min; T end = range.Max; TimeSpan length = GetDifference(start, end); diff = strategy.GetDifference(length); TicksInfo result = new TicksInfo { Info = diff }; if (providers.ContainsKey(diff)) { ITicksInfo innerResult = providers[diff].GetTicks(range, ticksCount); T[] ticks = ModifyTicksGuard(innerResult.Ticks, diff); result.Ticks = ticks; this.result = result; return result; } throw new InvalidOperationException(Strings.Exceptions.UnsupportedRangeInAxis); } private T[] ModifyTicksGuard(T[] ticks, object info) { var result = ModifyTicks(ticks, info); if (result == null) throw new ArgumentNullException("ticks"); return result; } protected virtual T[] ModifyTicks(T[] ticks, object info) { return ticks; } /// /// Decreases the tick count. /// /// The tick count. /// public int DecreaseTickCount(int ticksCount) { if (providers.ContainsKey(diff)) return providers[diff].DecreaseTickCount(ticksCount); int res = ticksCount / 2; if (res < 2) res = 2; return res; } /// /// Increases the tick count. /// /// The tick count. /// public int IncreaseTickCount(int ticksCount) { DebugVerify.Is(ticksCount < 2000); if (providers.ContainsKey(diff)) return providers[diff].IncreaseTickCount(ticksCount); return ticksCount * 2; } public ITicksProvider MinorProvider { get { DifferenceIn smallerDiff = DifferenceIn.Smallest; if (strategy.TryGetLowerDiff(diff, out smallerDiff) && minorProviders.ContainsKey(smallerDiff)) { var minorProvider = (MinorTimeProviderBase)minorProviders[smallerDiff]; minorProvider.SetTicks(result.Ticks); return minorProvider; } return null; // todo What to do if this already is the smallest provider? } } public ITicksProvider MajorProvider { get { DifferenceIn biggerDiff = DifferenceIn.Smallest; if (strategy.TryGetBiggerDiff(diff, out biggerDiff)) { return providers[biggerDiff]; } return null; // todo What to do if this already is the biggest provider? } } #endregion } }