Choosing an attractive linear scale for a graph's Y Axis

后端 未结 13 1428
予麋鹿
予麋鹿 2020-12-07 08:42

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

13条回答
  •  既然无缘
    2020-12-07 08:47

    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);
        }
    }
    

提交回复
热议问题