Nice Label Algorithm for Charts with minimum ticks

后端 未结 16 2070
清酒与你
清酒与你 2020-11-29 17:07

I need to calculate the Ticklabels and the Tickrange for charts manually.

I know the \"standard\" algorithm for nice ticks (see http://books.google.de/books?id=fvA7

16条回答
  •  野性不改
    2020-11-29 17:37

    Here'a better organized C# code.

    public class NiceScale
    {
    
        public double NiceMin { get; set; }
        public double NiceMax { get; set; }
        public double TickSpacing { get; private set; }
    
        private double _minPoint;
        private double _maxPoint;
        private double _maxTicks = 5;
        private double _range;
    
        /**
         * Instantiates a new instance of the NiceScale class.
         *
         * @param min the minimum data point on the axis
         * @param max the maximum data point on the axis
         */
        public NiceScale(double min, double max)
        {
            _minPoint = min;
            _maxPoint = max;
            Calculate();
        }
    
        /**
         * Calculate and update values for tick spacing and nice
         * minimum and maximum data points on the axis.
         */
        private void Calculate()
        {
            _range = NiceNum(_maxPoint - _minPoint, false);
            TickSpacing = NiceNum(_range / (_maxTicks - 1), true);
            NiceMin = Math.Floor(_minPoint / TickSpacing) * TickSpacing;
            NiceMax = Math.Ceiling(_maxPoint / TickSpacing) * TickSpacing;
        }
    
        /**
         * Returns a "nice" number approximately equal to range Rounds
         * the number if round = true Takes the ceiling if round = false.
         *
         * @param range the data range
         * @param round whether to round the result
         * @return a "nice" number to be used for the data range
         */
        private double NiceNum(double range, bool round)
        {
            double exponent; /** exponent of range */
            double fraction; /** fractional part of range */
            double niceFraction; /** nice, rounded fraction */
    
            exponent = Math.Floor(Math.Log10(range));
            fraction = range / Math.Pow(10, exponent);
    
            if (round) {
                if (fraction < 1.5)
                    niceFraction = 1;
                else if (fraction < 3)
                    niceFraction = 2;
                else if (fraction < 7)
                    niceFraction = 5;
                else
                    niceFraction = 10;
            } else {
                if (fraction <= 1)
                    niceFraction = 1;
                else if (fraction <= 2)
                    niceFraction = 2;
                else if (fraction <= 5)
                    niceFraction = 5;
                else
                    niceFraction = 10;
            }
    
            return niceFraction * Math.Pow(10, exponent);
        }
    
        /**
         * Sets the minimum and maximum data points for the axis.
         *
         * @param minPoint the minimum data point on the axis
         * @param maxPoint the maximum data point on the axis
         */
        public void SetMinMaxPoints(double minPoint, double maxPoint)
        {
            _minPoint = minPoint;
            _maxPoint = maxPoint;
            Calculate();
        }
    
        /**
         * Sets maximum number of tick marks we're comfortable with
         *
         * @param maxTicks the maximum number of tick marks for the axis
         */
        public void SetMaxTicks(double maxTicks)
        {
            _maxTicks = maxTicks;
            Calculate();
        }
    }
    

提交回复
热议问题