Nice Label Algorithm for Charts with minimum ticks

后端 未结 16 2072
清酒与你
清酒与你 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:25

    Dart / Flutter Version:

    import 'dart:math';
    
    void main() {
      double min = 3, max = 28;
    
      var scale = NiceScale(min, max, 5);
    
      print("Range: $min-$max; Max Point: ${scale.niceMax}; Min Point: ${scale.niceMin}; Steps: ${scale.tickSpacing};");
    }
    
    class NiceScale {
      double _niceMin, _niceMax;
      double _tickSpacing;
    
      double get tickSpacing { return _tickSpacing; }
      double get niceMin{ return _niceMin; }
      double get niceMax{ return _niceMax; }
    
      double _minPoint, _maxPoint;
      double _maxTicks;
      double _range;
    
      NiceScale(double minP, double maxP, double maxTicks){
        this._minPoint = minP;
        this._maxPoint = maxP;
        this._maxTicks = maxTicks;
        _calculate();
      }
    
      void _calculate(){
        _range = _niceNum(_maxPoint - _minPoint, false);
        _tickSpacing = _niceNum(_range / (_maxTicks - 1), true);
        _niceMin = _calcMin();
        _niceMax = _calcMax();
      }
    
      double _calcMin() {
        int floored = (_minPoint / _tickSpacing).floor();
        return floored * _tickSpacing;
      }
    
      double _calcMax() {
        int ceiled = (_maxPoint / _tickSpacing).ceil();
        return ceiled * _tickSpacing;
      }
    
      double _niceNum(double range, bool round){
        double exponent; /** exponent of range */
        double fraction; /** fractional part of range */
        double niceFraction; /** nice, rounded fraction */
    
        exponent = (log(range)/ln10).floor().toDouble();
        fraction = range / 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 * pow(10, exponent);
      }
    }
    

提交回复
热议问题