Initial Commit

This commit is contained in:
2024-02-23 00:46:06 -05:00
commit 2bbedc0178
470 changed files with 46035 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Research.DynamicDataDisplay;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Axes.Numeric
{
public class CustomBaseNumericLabelProvider : LabelProvider<double>
{
private double customBase = 2;
/// <summary>
/// Gets or sets the custom base.
/// </summary>
/// <value>The custom base.</value>
public double CustomBase
{
get { return customBase; }
set
{
if (Double.IsNaN(value))
throw new ArgumentException(Strings.Exceptions.CustomBaseTicksProviderBaseIsNaN);
if (value <= 0)
throw new ArgumentOutOfRangeException(Strings.Exceptions.CustomBaseTicksProviderBaseIsTooSmall);
customBase = value;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="CustomBaseNumericLabelProvider"/> class.
/// </summary>
public CustomBaseNumericLabelProvider() { }
/// <summary>
/// Initializes a new instance of the <see cref="CustomBaseNumericLabelProvider"/> class.
/// </summary>
public CustomBaseNumericLabelProvider(double customBase)
: this()
{
CustomBase = customBase;
}
/// <summary>
/// Initializes a new instance of the <see cref="CustomBaseNumericLabelProvider"/> class.
/// </summary>
/// <param name="customBase">The custom base.</param>
/// <param name="customBaseString">The custom base string.</param>
public CustomBaseNumericLabelProvider(double customBase, string customBaseString)
: this(customBase)
{
CustomBaseString = customBaseString;
}
private string customBaseString = null;
/// <summary>
/// Gets or sets the custom base string.
/// </summary>
/// <value>The custom base string.</value>
public string CustomBaseString
{
get { return customBaseString; }
set
{
if (customBaseString != value)
{
customBaseString = value;
RaiseChanged();
}
}
}
protected override string GetStringCore(LabelTickInfo<double> tickInfo)
{
double value = tickInfo.Tick / customBase;
string customBaseStr = customBaseString ?? customBase.ToString();
string result;
if (value == 1)
result = customBaseStr;
else if (value == -1)
{
result = "-" + customBaseStr;
}
else
result = value.ToString() + customBaseStr;
return result;
}
}
}

View File

@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
using System.Windows.Markup;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Axes.Numeric
{
[ContentProperty("TicksProvider")]
public class CustomBaseNumericTicksProvider : ITicksProvider<double>
{
private double customBase = 2;
/// <summary>
/// Gets or sets the custom base.
/// </summary>
/// <value>The custom base.</value>
public double CustomBase
{
get { return customBase; }
set
{
if (Double.IsNaN(value))
throw new ArgumentException(Strings.Exceptions.CustomBaseTicksProviderBaseIsNaN);
if (value <= 0)
throw new ArgumentOutOfRangeException(Strings.Exceptions.CustomBaseTicksProviderBaseIsTooSmall);
customBase = value;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="CustomBaseNumericTicksProvider"/> class.
/// </summary>
public CustomBaseNumericTicksProvider() : this(2.0) { }
/// <summary>
/// Initializes a new instance of the <see cref="CustomBaseNumericTicksProvider"/> class.
/// </summary>
/// <param name="customBase">The custom base, e.g. Math.PI</param>
public CustomBaseNumericTicksProvider(double customBase) : this(customBase, new NumericTicksProvider()) { }
private CustomBaseNumericTicksProvider(double customBase, ITicksProvider<double> ticksProvider)
{
if (ticksProvider == null)
throw new ArgumentNullException("ticksProvider");
CustomBase = customBase;
TicksProvider = ticksProvider;
}
private void ticksProvider_Changed(object sender, EventArgs e)
{
Changed.Raise(this);
}
private ITicksProvider<double> ticksProvider = null;
public ITicksProvider<double> TicksProvider
{
get { return ticksProvider; }
set
{
if (value == null)
throw new ArgumentNullException("value");
if (ticksProvider != null)
ticksProvider.Changed -= ticksProvider_Changed;
ticksProvider = value;
ticksProvider.Changed += ticksProvider_Changed;
if (minorTicksProvider != null)
minorTicksProvider.Changed -= minorTicksProvider_Changed;
minorTicksProvider = new MinorProviderWrapper(this);
minorTicksProvider.Changed += minorTicksProvider_Changed;
Changed.Raise(this);
}
}
void minorTicksProvider_Changed(object sender, EventArgs e)
{
Changed.Raise(this);
}
private Range<double> TransformRange(Range<double> range)
{
double min = range.Min / customBase;
double max = range.Max / customBase;
return new Range<double>(min, max);
}
#region ITicksProvider<double> Members
private double[] tickMarks;
public ITicksInfo<double> GetTicks(Range<double> range, int ticksCount)
{
var ticks = ticksProvider.GetTicks(TransformRange(range), ticksCount);
TransformTicks(ticks);
tickMarks = ticks.Ticks;
return ticks;
}
private void TransformTicks(ITicksInfo<double> ticks)
{
for (int i = 0; i < ticks.Ticks.Length; i++)
{
ticks.Ticks[i] *= customBase;
}
}
public int DecreaseTickCount(int ticksCount)
{
return ticksProvider.DecreaseTickCount(ticksCount);
}
public int IncreaseTickCount(int ticksCount)
{
return ticksProvider.IncreaseTickCount(ticksCount);
}
private ITicksProvider<double> minorTicksProvider;
public ITicksProvider<double> MinorProvider
{
get { return minorTicksProvider; }
}
/// <summary>
/// Gets the major provider, used to generate major ticks - for example, years for common ticks as months.
/// </summary>
/// <value>The major provider.</value>
public ITicksProvider<double> MajorProvider
{
get { return null; }
}
public event EventHandler Changed;
#endregion
private sealed class MinorProviderWrapper : ITicksProvider<double>
{
private readonly CustomBaseNumericTicksProvider owner;
public MinorProviderWrapper(CustomBaseNumericTicksProvider owner)
{
this.owner = owner;
MinorTicksProvider.Changed += MinorTicksProvider_Changed;
}
private void MinorTicksProvider_Changed(object sender, EventArgs e)
{
Changed.Raise(this);
}
private ITicksProvider<double> MinorTicksProvider
{
get { return owner.ticksProvider.MinorProvider; }
}
#region ITicksProvider<double> Members
public ITicksInfo<double> GetTicks(Range<double> range, int ticksCount)
{
var minorProvider = MinorTicksProvider;
var ticks = minorProvider.GetTicks(range, ticksCount);
return ticks;
}
public int DecreaseTickCount(int ticksCount)
{
return MinorTicksProvider.DecreaseTickCount(ticksCount);
}
public int IncreaseTickCount(int ticksCount)
{
return MinorTicksProvider.IncreaseTickCount(ticksCount);
}
public ITicksProvider<double> MinorProvider
{
get { return MinorTicksProvider.MinorProvider; }
}
public ITicksProvider<double> MajorProvider
{
get { return owner; }
}
public event EventHandler Changed;
#endregion
}
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Globalization;
using System.Diagnostics;
using Microsoft.Research.DynamicDataDisplay.Charts.Axes;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
/// <summary>
/// Represents an axis label provider for double ticks, generating labels with numbers in exponential form when it is appropriate.
/// </summary>
public sealed class ExponentialLabelProvider : NumericLabelProviderBase
{
/// <summary>
/// Initializes a new instance of the <see cref="ExponentialLabelProvider"/> class.
/// </summary>
public ExponentialLabelProvider() { }
/// <summary>
/// Creates labels by given ticks info.
/// Is not intended to be called from your code.
/// </summary>
/// <param name="ticksInfo">The ticks info.</param>
/// <returns>
/// Array of <see cref="UIElement"/>s, which are axis labels for specified axis ticks.
/// </returns>
public override UIElement[] CreateLabels(ITicksInfo<double> ticksInfo)
{
var ticks = ticksInfo.Ticks;
Init(ticks);
UIElement[] res = new UIElement[ticks.Length];
LabelTickInfo<double> tickInfo = new LabelTickInfo<double> { Info = ticksInfo.Info };
for (int i = 0; i < res.Length; i++)
{
var tick = ticks[i];
tickInfo.Tick = tick;
tickInfo.Index = i;
string labelText = GetString(tickInfo);
TextBlock label;
if (labelText.Contains('E'))
{
string[] substrs = labelText.Split('E');
string mantissa = substrs[0];
string exponenta = substrs[1];
exponenta = exponenta.TrimStart('+');
Span span = new Span();
span.Inlines.Add(String.Format(CultureInfo.CurrentCulture, "{0}·10", mantissa));
Span exponentaSpan = new Span(new Run(exponenta));
exponentaSpan.BaselineAlignment = BaselineAlignment.Superscript;
exponentaSpan.FontSize = 8;
span.Inlines.Add(exponentaSpan);
label = new TextBlock(span);
LabelProviderProperties.SetExponentialIsCommonLabel(label, false);
}
else
{
label = (TextBlock)GetResourceFromPool();
if (label == null)
{
label = new TextBlock();
}
label.Text = labelText;
}
res[i] = label;
label.ToolTip = tick.ToString(CultureInfo.CurrentCulture);
ApplyCustomView(tickInfo, label);
}
return res;
}
protected override bool ReleaseCore(UIElement label)
{
bool isNotExponential = LabelProviderProperties.GetExponentialIsCommonLabel(label);
return isNotExponential && CustomView == null;
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
/// <summary>
/// Represents a horizontal axis with values of <see cref="Double"/> type.
/// Can be placed only from bottom or top side of plotter.
/// By default is placed from the bottom side.
/// </summary>
public class HorizontalAxis : NumericAxis
{
/// <summary>
/// Initializes a new instance of the <see cref="HorizontalAxis"/> class, placed on bottom of <see cref="ChartPlotter"/>.
/// </summary>
public HorizontalAxis()
{
Placement = AxisPlacement.Bottom;
}
/// <summary>
/// Validates the placement - e.g., vertical axis should not be placed from top or bottom, etc.
/// If proposed placement is wrong, throws an ArgumentException.
/// </summary>
/// <param name="newPlacement">The new placement.</param>
protected override void ValidatePlacement(AxisPlacement newPlacement)
{
if (newPlacement == AxisPlacement.Left || newPlacement == AxisPlacement.Right)
throw new ArgumentException(Strings.Exceptions.HorizontalAxisCannotBeVertical);
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Markup;
using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Axes.Numeric
{
/// <summary>
/// Represents a ticks provider for logarithmically transfomed axis - returns ticks which are a power of specified logarithm base.
/// </summary>
public class LogarithmNumericTicksProvider : ITicksProvider<double>
{
/// <summary>
/// Initializes a new instance of the <see cref="LogarithmNumericTicksProvider"/> class.
/// </summary>
public LogarithmNumericTicksProvider()
{
minorProvider = new MinorNumericTicksProvider(this);
minorProvider.Changed += ticksProvider_Changed;
}
/// <summary>
/// Initializes a new instance of the <see cref="LogarithmNumericTicksProvider"/> class.
/// </summary>
/// <param name="logarithmBase">The logarithm base.</param>
public LogarithmNumericTicksProvider(double logarithmBase)
: this()
{
LogarithmBase = logarithmBase;
}
private void ticksProvider_Changed(object sender, EventArgs e)
{
Changed.Raise(this);
}
private double logarithmBase = 10;
public double LogarithmBase
{
get { return logarithmBase; }
set
{
if (value <= 0)
throw new ArgumentOutOfRangeException(Strings.Exceptions.LogarithmBaseShouldBePositive);
logarithmBase = value;
}
}
private double LogByBase(double d)
{
return Math.Log10(d) / Math.Log10(logarithmBase);
}
#region ITicksProvider<double> Members
private double[] ticks;
public ITicksInfo<double> GetTicks(Range<double> range, int ticksCount)
{
double min = LogByBase(range.Min);
double max = LogByBase(range.Max);
double minDown = Math.Floor(min);
double maxUp = Math.Ceiling(max);
double logLength = LogByBase(range.GetLength());
ticks = CreateTicks(range);
int log = RoundingHelper.GetDifferenceLog(range.Min, range.Max);
TicksInfo<double> result = new TicksInfo<double> { Ticks = ticks, TickSizes = ArrayExtensions.CreateArray(ticks.Length, 1.0), Info = log };
return result;
}
private double[] CreateTicks(Range<double> range)
{
double min = LogByBase(range.Min);
double max = LogByBase(range.Max);
double minDown = Math.Floor(min);
double maxUp = Math.Ceiling(max);
int intStart = (int)Math.Floor(minDown);
int count = (int)(maxUp - minDown + 1);
var ticks = new double[count];
for (int i = 0; i < count; i++)
{
ticks[i] = intStart + i;
}
for (int i = 0; i < ticks.Length; i++)
{
ticks[i] = Math.Pow(logarithmBase, ticks[i]);
}
return ticks;
}
public int DecreaseTickCount(int ticksCount)
{
return ticksCount;
}
public int IncreaseTickCount(int ticksCount)
{
return ticksCount;
}
private MinorNumericTicksProvider minorProvider;
public ITicksProvider<double> MinorProvider
{
get
{
minorProvider.SetRanges(ArrayExtensions.GetPairs(ticks));
return minorProvider;
}
}
public ITicksProvider<double> MajorProvider
{
get { return null; }
}
public event EventHandler Changed;
#endregion
}
}

View File

@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
public sealed class MinorNumericTicksProvider : ITicksProvider<double>
{
private readonly ITicksProvider<double> parent;
private Range<double>[] ranges;
internal void SetRanges(IEnumerable<Range<double>> ranges)
{
this.ranges = ranges.ToArray();
}
private double[] coeffs;
public double[] Coeffs
{
get { return coeffs; }
set
{
if (value == null)
throw new ArgumentNullException("value");
coeffs = value;
Changed.Raise(this);
}
}
internal MinorNumericTicksProvider(ITicksProvider<double> parent)
{
this.parent = parent;
Coeffs = new double[] { 0.3, 0.3, 0.3, 0.3, 0.6, 0.3, 0.3, 0.3, 0.3 };
}
#region ITicksProvider<double> Members
public event EventHandler Changed;
public ITicksInfo<double> GetTicks(Range<double> range, int ticksCount)
{
if (Coeffs.Length == 0)
return new TicksInfo<double>();
var minorTicks = ranges.Select(r => CreateTicks(r)).SelectMany(m => m);
var res = new TicksInfo<double>();
res.TickSizes = minorTicks.Select(m => m.Value).ToArray();
res.Ticks = minorTicks.Select(m => m.Tick).ToArray();
return res;
}
public MinorTickInfo<double>[] CreateTicks(Range<double> range)
{
double step = (range.Max - range.Min) / (Coeffs.Length + 1);
MinorTickInfo<double>[] res = new MinorTickInfo<double>[Coeffs.Length];
for (int i = 0; i < Coeffs.Length; i++)
{
res[i] = new MinorTickInfo<double>(Coeffs[i], range.Min + step * (i + 1));
}
return res;
}
public int DecreaseTickCount(int ticksCount)
{
return ticksCount;
}
public int IncreaseTickCount(int ticksCount)
{
return ticksCount;
}
public ITicksProvider<double> MinorProvider
{
get { return null; }
}
public ITicksProvider<double> MajorProvider
{
get { return parent; }
}
#endregion
}
}

View File

@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using Microsoft.Research.DynamicDataDisplay.Charts.Axes.Numeric;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
/// <summary>
/// Represents a numeric axis with values of <see cref="System.Double"/> type.
/// </summary>
public class NumericAxis : AxisBase<double>
{
/// <summary>
/// Initializes a new instance of the <see cref="NumericAxis"/> class.
/// </summary>
public NumericAxis()
: base(new NumericAxisControl(),
d => d,
d => d)
{
}
/// <summary>
/// Sets conversions of axis - functions used to convert values of axis type to and from double values of viewport.
/// Sets both ConvertToDouble and ConvertFromDouble properties.
/// </summary>
/// <param name="min">The minimal viewport value.</param>
/// <param name="minValue">The value of axis type, corresponding to minimal viewport value.</param>
/// <param name="max">The maximal viewport value.</param>
/// <param name="maxValue">The value of axis type, corresponding to maximal viewport value.</param>
public override void SetConversion(double min, double minValue, double max, double maxValue)
{
var conversion = new NumericConversion(min, minValue, max, maxValue);
this.ConvertFromDouble = conversion.FromDouble;
this.ConvertToDouble = conversion.ToDouble;
}
}
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
public class NumericAxisControl : AxisControl<double>
{
public NumericAxisControl()
{
LabelProvider = new ExponentialLabelProvider();
TicksProvider = new NumericTicksProvider();
ConvertToDouble = d => d;
Range = new Range<double>(0, 10);
}
}
}

View File

@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Axes.Numeric
{
internal sealed class NumericConversion
{
private readonly double min;
private readonly double length;
private readonly double minValue;
private readonly double valueLength;
public NumericConversion(double min, double minValue, double max, double maxValue)
{
this.min = min;
this.length = max - min;
this.minValue = minValue;
this.valueLength = maxValue - minValue;
}
public double FromDouble(double value)
{
double ratio = (value - min) / length;
return minValue + ratio * valueLength;
}
public double ToDouble(double value)
{
double ratio = (value - minValue) / valueLength;
return min + length * ratio;
}
}
}

View File

@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Research.DynamicDataDisplay.Charts.Axes;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
public abstract class NumericLabelProviderBase : LabelProviderBase<double>
{
bool shouldRound = true;
private int rounding;
protected void Init(double[] ticks)
{
if (ticks.Length == 0)
return;
double start = ticks[0];
double finish = ticks[ticks.Length - 1];
if (start == finish)
{
shouldRound = false;
return;
}
double delta = finish - start;
rounding = (int)Math.Round(Math.Log10(delta));
double newStart = RoundingHelper.Round(start, rounding);
double newFinish = RoundingHelper.Round(finish, rounding);
if (newStart == newFinish)
rounding--;
}
protected override string GetStringCore(LabelTickInfo<double> tickInfo)
{
string res;
if (!shouldRound)
{
res = tickInfo.Tick.ToString();
}
else
{
int round = Math.Min(15, Math.Max(-15, rounding - 3)); // was rounding - 2
res = RoundingHelper.Round(tickInfo.Tick, round).ToString();
}
return res;
}
}
}

View File

@@ -0,0 +1,167 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
using System.Collections.ObjectModel;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
/// <summary>
/// Represents a ticks provider for <see cref="System.Double"/> values.
/// </summary>
public sealed class NumericTicksProvider : ITicksProvider<double>
{
/// <summary>
/// Initializes a new instance of the <see cref="NumericTicksProvider"/> class.
/// </summary>
public NumericTicksProvider()
{
minorProvider = new MinorNumericTicksProvider(this);
minorProvider.Changed += minorProvider_Changed;
minorProvider.Coeffs = new double[] { 0.3, 0.3, 0.3, 0.3, 0.6, 0.3, 0.3, 0.3, 0.3 };
}
private void minorProvider_Changed(object sender, EventArgs e)
{
Changed.Raise(this);
}
public event EventHandler Changed;
private void RaiseChangedEvent()
{
Changed.Raise(this);
}
private double minStep = 0.0;
/// <summary>
/// Gets or sets the minimal step between ticks.
/// </summary>
/// <value>The min step.</value>
public double MinStep
{
get { return minStep; }
set
{
Verify.IsTrue(value >= 0.0, "value");
if (minStep != value)
{
minStep = value;
RaiseChangedEvent();
}
}
}
private double[] ticks;
public ITicksInfo<double> GetTicks(Range<double> range, int ticksCount)
{
double start = range.Min;
double finish = range.Max;
double delta = finish - start;
int log = (int)Math.Round(Math.Log10(delta));
double newStart = RoundingHelper.Round(start, log);
double newFinish = RoundingHelper.Round(finish, log);
if (newStart == newFinish)
{
log--;
newStart = RoundingHelper.Round(start, log);
newFinish = RoundingHelper.Round(finish, log);
}
// calculating step between ticks
double unroundedStep = (newFinish - newStart) / ticksCount;
int stepLog = log;
// trying to round step
double step = RoundingHelper.Round(unroundedStep, stepLog);
if (step == 0)
{
stepLog--;
step = RoundingHelper.Round(unroundedStep, stepLog);
if (step == 0)
{
// step will not be rounded if attempts to be rounded to zero.
step = unroundedStep;
}
}
if (step < minStep)
step = minStep;
if (step != 0.0)
{
ticks = CreateTicks(start, finish, step);
}
else
{
ticks = new double[] { };
}
TicksInfo<double> res = new TicksInfo<double> { Info = log, Ticks = ticks };
return res;
}
private static double[] CreateTicks(double start, double finish, double step)
{
DebugVerify.Is(step != 0.0);
double x = step * Math.Floor(start / step);
if (x == x + step)
{
return new double[0];
}
List<double> res = new List<double>();
double increasedFinish = finish + step * 1.05;
while (x <= increasedFinish)
{
res.Add(x);
DebugVerify.Is(res.Count < 2000);
x += step;
}
return res.ToArray();
}
private static int[] tickCounts = new int[] { 20, 10, 5, 4, 2, 1 };
public const int DefaultPreferredTicksCount = 10;
public int DecreaseTickCount(int ticksCount)
{
return tickCounts.FirstOrDefault(tick => tick < ticksCount);
}
public int IncreaseTickCount(int ticksCount)
{
int newTickCount = tickCounts.Reverse().FirstOrDefault(tick => tick > ticksCount);
if (newTickCount == 0)
newTickCount = tickCounts[0];
return newTickCount;
}
private readonly MinorNumericTicksProvider minorProvider;
public ITicksProvider<double> MinorProvider
{
get
{
if (ticks != null)
{
minorProvider.SetRanges(ticks.GetPairs());
}
return minorProvider;
}
}
public ITicksProvider<double> MajorProvider
{
get { return null; }
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Research.DynamicDataDisplay.Charts.Axes;
using System.Globalization;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
/// <summary>
/// Represents a simple label provider for double ticks, which simply returns result of .ToString() method, called for rounded ticks.
/// </summary>
public class ToStringLabelProvider : NumericLabelProviderBase
{
/// <summary>
/// Initializes a new instance of the <see cref="ToStringLabelProvider"/> class.
/// </summary>
public ToStringLabelProvider() { }
public override UIElement[] CreateLabels(ITicksInfo<double> ticksInfo)
{
var ticks = ticksInfo.Ticks;
Init(ticks);
UIElement[] res = new UIElement[ticks.Length];
LabelTickInfo<double> tickInfo = new LabelTickInfo<double> { Info = ticksInfo.Info };
for (int i = 0; i < res.Length; i++)
{
tickInfo.Tick = ticks[i];
tickInfo.Index = i;
string labelText = GetString(tickInfo);
TextBlock label = (TextBlock)GetResourceFromPool();
if (label == null)
{
label = new TextBlock();
}
label.Text = labelText;
label.ToolTip = ticks[i].ToString();
res[i] = label;
ApplyCustomView(tickInfo, label);
}
return res;
}
}
}

View File

@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Axes.Numeric
{
public class UnroundingLabelProvider : LabelProvider<double>
{
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
namespace Microsoft.Research.DynamicDataDisplay.Charts
{
/// <summary>
/// Represents a vertical axis with values of System.Double type.
/// Can be placed only from left or right side of plotter.
/// By default is placed from the left side.
/// </summary>
public class VerticalAxis : NumericAxis
{
/// <summary>
/// Initializes a new instance of the <see cref="VerticalAxis"/> class.
/// </summary>
public VerticalAxis()
{
Placement = AxisPlacement.Left;
}
/// <summary>
/// Validates the placement - e.g., vertical axis should not be placed from top or bottom, etc.
/// If proposed placement if wrong, throws an ArgumentException.
/// </summary>
/// <param name="newPlacement">The new placement.</param>
protected override void ValidatePlacement(AxisPlacement newPlacement)
{
if (newPlacement == AxisPlacement.Bottom || newPlacement == AxisPlacement.Top)
throw new ArgumentException(Strings.Exceptions.VerticalAxisCannotBeHorizontal);
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Microsoft.Research.DynamicDataDisplay.Charts.Axes
{
public class VerticalNumericAxis : NumericAxis
{
public VerticalNumericAxis()
{
Placement = AxisPlacement.Left;
}
protected override void ValidatePlacement(AxisPlacement newPlacement)
{
if (newPlacement == AxisPlacement.Bottom || newPlacement == AxisPlacement.Top)
throw new ArgumentException(Strings.Exceptions.VerticalAxisCannotBeHorizontal);
}
}
}