I\'m writing a bit of code to display a bar (or line) graph in our software. Everything\'s going fine. The thing that\'s got me stumped is labeling the Y axis.
The
Based on @Gamecat's algorithm, I produced the following helper class
public struct Interval
{
public readonly double Min, Max, TickRange;
public static Interval Find(double min, double max, int tickCount, double padding = 0.05)
{
double range = max - min;
max += range*padding;
min -= range*padding;
var attempts = new List();
for (int i = tickCount; i > tickCount / 2; --i)
attempts.Add(new Interval(min, max, i));
return attempts.MinBy(a => a.Max - a.Min);
}
private Interval(double min, double max, int tickCount)
{
var candidates = (min <= 0 && max >= 0 && tickCount <= 8) ? new[] {2, 2.5, 3, 4, 5, 7.5, 10} : new[] {2, 2.5, 5, 10};
double unroundedTickSize = (max - min) / (tickCount - 1);
double x = Math.Ceiling(Math.Log10(unroundedTickSize) - 1);
double pow10X = Math.Pow(10, x);
TickRange = RoundUp(unroundedTickSize/pow10X, candidates) * pow10X;
Min = TickRange * Math.Floor(min / TickRange);
Max = TickRange * Math.Ceiling(max / TickRange);
}
// 1 < scaled <= 10
private static double RoundUp(double scaled, IEnumerable candidates)
{
return candidates.First(candidate => scaled <= candidate);
}
}