Qwt User's Guide  6.2.0
qwt_scale_engine.cpp
1 /******************************************************************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_scale_engine.h"
11 #include "qwt_math.h"
12 #include "qwt_interval.h"
13 #include "qwt_transform.h"
14 
15 #include <qdebug.h>
16 
17 #include <limits>
18 
19 static inline double qwtLog( double base, double value )
20 {
21  return std::log( value ) / std::log( base );
22 }
23 
24 static inline QwtInterval qwtLogInterval( double base, const QwtInterval& interval )
25 {
26  return QwtInterval( qwtLog( base, interval.minValue() ),
27  qwtLog( base, interval.maxValue() ) );
28 }
29 
30 static inline QwtInterval qwtPowInterval( double base, const QwtInterval& interval )
31 {
32  return QwtInterval( std::pow( base, interval.minValue() ),
33  std::pow( base, interval.maxValue() ) );
34 }
35 
36 #if 1
37 
38 // this version often doesn't find the best ticks: f.e for 15: 5, 10
39 static double qwtStepSize( double intervalSize, int maxSteps, uint base )
40 {
41  const double minStep =
42  QwtScaleArithmetic::divideInterval( intervalSize, maxSteps, base );
43 
44  if ( minStep != 0.0 )
45  {
46  // # ticks per interval
47  const int numTicks = qwtCeil( qAbs( intervalSize / minStep ) ) - 1;
48 
49  // Do the minor steps fit into the interval?
50  if ( qwtFuzzyCompare( ( numTicks + 1 ) * qAbs( minStep ),
51  qAbs( intervalSize ), intervalSize ) > 0 )
52  {
53  // The minor steps doesn't fit into the interval
54  return 0.5 * intervalSize;
55  }
56  }
57 
58  return minStep;
59 }
60 
61 #else
62 
63 static double qwtStepSize( double intervalSize, int maxSteps, uint base )
64 {
65  if ( maxSteps <= 0 )
66  return 0.0;
67 
68  if ( maxSteps > 2 )
69  {
70  for ( int numSteps = maxSteps; numSteps > 1; numSteps-- )
71  {
72  const double stepSize = intervalSize / numSteps;
73 
74  const double p = std::floor( std::log( stepSize ) / std::log( base ) );
75  const double fraction = std::pow( base, p );
76 
77  for ( uint n = base; n > 1; n /= 2 )
78  {
79  if ( qFuzzyCompare( stepSize, n * fraction ) )
80  return stepSize;
81 
82  if ( n == 3 && ( base % 2 ) == 0 )
83  {
84  if ( qFuzzyCompare( stepSize, 2 * fraction ) )
85  return stepSize;
86  }
87  }
88  }
89  }
90 
91  return intervalSize * 0.5;
92 }
93 
94 #endif
95 
96 static const double _eps = 1.0e-6;
97 
108 double QwtScaleArithmetic::ceilEps( double value,
109  double intervalSize )
110 {
111  const double eps = _eps * intervalSize;
112 
113  value = ( value - eps ) / intervalSize;
114  return std::ceil( value ) * intervalSize;
115 }
116 
126 double QwtScaleArithmetic::floorEps( double value, double intervalSize )
127 {
128  const double eps = _eps * intervalSize;
129 
130  value = ( value + eps ) / intervalSize;
131  return std::floor( value ) * intervalSize;
132 }
133 
143 double QwtScaleArithmetic::divideEps( double intervalSize, double numSteps )
144 {
145  if ( numSteps == 0.0 || intervalSize == 0.0 )
146  return 0.0;
147 
148  return ( intervalSize - ( _eps * intervalSize ) ) / numSteps;
149 }
150 
161  double intervalSize, int numSteps, uint base )
162 {
163  if ( numSteps <= 0 )
164  return 0.0;
165 
166  const double v = QwtScaleArithmetic::divideEps( intervalSize, numSteps );
167  if ( v == 0.0 )
168  return 0.0;
169 
170  const double lx = qwtLog( base, std::fabs( v ) );
171  const double p = std::floor( lx );
172 
173  const double fraction = std::pow( base, lx - p );
174 
175  uint n = base;
176  while ( ( n > 1 ) && ( fraction <= n / 2 ) )
177  n /= 2;
178 
179  double stepSize = n * std::pow( base, p );
180  if ( v < 0 )
181  stepSize = -stepSize;
182 
183  return stepSize;
184 }
185 
186 class QwtScaleEngine::PrivateData
187 {
188  public:
189  PrivateData():
191  lowerMargin( 0.0 ),
192  upperMargin( 0.0 ),
193  referenceValue( 0.0 ),
194  base( 10 ),
195  transform( NULL )
196  {
197  }
198 
199  ~PrivateData()
200  {
201  delete transform;
202  }
203 
205 
206  double lowerMargin;
207  double upperMargin;
208 
209  double referenceValue;
210 
211  uint base;
212 
213  QwtTransform* transform;
214 };
215 
223 {
224  m_data = new PrivateData;
225  setBase( base );
226 }
227 
228 
231 {
232  delete m_data;
233 }
234 
249 {
250  if ( transform != m_data->transform )
251  {
252  delete m_data->transform;
253  m_data->transform = transform;
254  }
255 }
256 
266 {
267  QwtTransform* transform = NULL;
268  if ( m_data->transform )
269  transform = m_data->transform->copy();
270 
271  return transform;
272 }
273 
281 {
282  return m_data->lowerMargin;
283 }
284 
292 {
293  return m_data->upperMargin;
294 }
295 
312 void QwtScaleEngine::setMargins( double lower, double upper )
313 {
314  m_data->lowerMargin = qwtMaxF( lower, 0.0 );
315  m_data->upperMargin = qwtMaxF( upper, 0.0 );
316 }
317 
327  double intervalSize, int numSteps ) const
328 {
330  intervalSize, numSteps, m_data->base );
331 }
332 
342  const QwtInterval& interval, double value ) const
343 {
344  if ( !interval.isValid() )
345  return false;
346 
347  if ( qwtFuzzyCompare( value, interval.minValue(), interval.width() ) < 0 )
348  return false;
349 
350  if ( qwtFuzzyCompare( value, interval.maxValue(), interval.width() ) > 0 )
351  return false;
352 
353  return true;
354 }
355 
365  const QwtInterval& interval ) const
366 {
367  if ( !interval.isValid() || ticks.count() == 0 )
368  return QList< double >();
369 
370  if ( contains( interval, ticks.first() )
371  && contains( interval, ticks.last() ) )
372  {
373  return ticks;
374  }
375 
376  QList< double > strippedTicks;
377  for ( int i = 0; i < ticks.count(); i++ )
378  {
379  if ( contains( interval, ticks[i] ) )
380  strippedTicks += ticks[i];
381  }
382  return strippedTicks;
383 }
384 
396 {
397  const double delta = ( value == 0.0 ) ? 0.5 : qAbs( 0.5 * value );
398  const double max = std::numeric_limits< double >::max();
399 
400  if ( max - delta < value )
401  return QwtInterval( max - delta, max );
402 
403  if ( -max + delta > value )
404  return QwtInterval( -max, -max + delta );
405 
406  return QwtInterval( value - delta, value + delta );
407 }
408 
417 void QwtScaleEngine::setAttribute( Attribute attribute, bool on )
418 {
419  if ( on )
420  m_data->attributes |= attribute;
421  else
422  m_data->attributes &= ~attribute;
423 }
424 
432 {
433  return ( m_data->attributes & attribute );
434 }
435 
443 {
444  m_data->attributes = attributes;
445 }
446 
452 {
453  return m_data->attributes;
454 }
455 
465 void QwtScaleEngine::setReference( double reference )
466 {
467  m_data->referenceValue = reference;
468 }
469 
475 {
476  return m_data->referenceValue;
477 }
478 
491 void QwtScaleEngine::setBase( uint base )
492 {
493  m_data->base = qMax( base, 2U );
494 }
495 
501 {
502  return m_data->base;
503 }
504 
512  QwtScaleEngine( base )
513 {
514 }
515 
518 {
519 }
520 
531 void QwtLinearScaleEngine::autoScale( int maxNumSteps,
532  double& x1, double& x2, double& stepSize ) const
533 {
534  QwtInterval interval( x1, x2 );
535  interval = interval.normalized();
536 
537  interval.setMinValue( interval.minValue() - lowerMargin() );
538  interval.setMaxValue( interval.maxValue() + upperMargin() );
539 
541  interval = interval.symmetrize( reference() );
542 
544  interval = interval.extend( reference() );
545 
546  if ( interval.width() == 0.0 )
547  interval = buildInterval( interval.minValue() );
548 
550  interval.width(), qMax( maxNumSteps, 1 ), base() );
551 
553  interval = align( interval, stepSize );
554 
555  x1 = interval.minValue();
556  x2 = interval.maxValue();
557 
559  {
560  qSwap( x1, x2 );
561  stepSize = -stepSize;
562  }
563 }
564 
578  int maxMajorSteps, int maxMinorSteps, double stepSize ) const
579 {
580  QwtInterval interval = QwtInterval( x1, x2 ).normalized();
581 
582  if ( interval.widthL() > std::numeric_limits< double >::max() )
583  {
584  qWarning() << "QwtLinearScaleEngine::divideScale: overflow";
585  return QwtScaleDiv();
586  }
587 
588  if ( interval.width() <= 0 )
589  return QwtScaleDiv();
590 
591  stepSize = qAbs( stepSize );
592  if ( stepSize == 0.0 )
593  {
594  if ( maxMajorSteps < 1 )
595  maxMajorSteps = 1;
596 
598  interval.width(), maxMajorSteps, base() );
599  }
600 
601  QwtScaleDiv scaleDiv;
602 
603  if ( stepSize != 0.0 )
604  {
606  buildTicks( interval, stepSize, maxMinorSteps, ticks );
607 
608  scaleDiv = QwtScaleDiv( interval, ticks );
609  }
610 
611  if ( x1 > x2 )
612  scaleDiv.invert();
613 
614  return scaleDiv;
615 }
616 
628  const QwtInterval& interval, double stepSize, int maxMinorSteps,
630 {
631  const QwtInterval boundingInterval = align( interval, stepSize );
632 
633  ticks[QwtScaleDiv::MajorTick] =
634  buildMajorTicks( boundingInterval, stepSize );
635 
636  if ( maxMinorSteps > 0 )
637  {
638  buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinorSteps, stepSize,
640  }
641 
642  for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
643  {
644  ticks[i] = strip( ticks[i], interval );
645 
646  // ticks very close to 0.0 are explicitly set to 0.0
647 
648  for ( int j = 0; j < ticks[i].count(); j++ )
649  {
650  if ( qwtFuzzyCompare( ticks[i][j], 0.0, stepSize ) == 0 )
651  ticks[i][j] = 0.0;
652  }
653  }
654 }
655 
665  const QwtInterval& interval, double stepSize ) const
666 {
667  int numTicks = qRound( interval.width() / stepSize ) + 1;
668  if ( numTicks > 10000 )
669  numTicks = 10000;
670 
671  QList< double > ticks;
672  ticks.reserve( numTicks );
673 
674  ticks += interval.minValue();
675  for ( int i = 1; i < numTicks - 1; i++ )
676  ticks += interval.minValue() + i * stepSize;
677  ticks += interval.maxValue();
678 
679  return ticks;
680 }
681 
693  const QList< double >& majorTicks,
694  int maxMinorSteps, double stepSize,
695  QList< double >& minorTicks,
696  QList< double >& mediumTicks ) const
697 {
698  double minStep = qwtStepSize( stepSize, maxMinorSteps, base() );
699  if ( minStep == 0.0 )
700  return;
701 
702  // # ticks per interval
703  const int numTicks = qwtCeil( qAbs( stepSize / minStep ) ) - 1;
704 
705  int medIndex = -1;
706  if ( numTicks % 2 )
707  medIndex = numTicks / 2;
708 
709  // calculate minor ticks
710 
711  for ( int i = 0; i < majorTicks.count(); i++ )
712  {
713  double val = majorTicks[i];
714  for ( int k = 0; k < numTicks; k++ )
715  {
716  val += minStep;
717 
718  double alignedValue = val;
719  if ( qwtFuzzyCompare( val, 0.0, stepSize ) == 0 )
720  alignedValue = 0.0;
721 
722  if ( k == medIndex )
723  mediumTicks += alignedValue;
724  else
725  minorTicks += alignedValue;
726  }
727  }
728 }
729 
742  const QwtInterval& interval, double stepSize ) const
743 {
744  double x1 = interval.minValue();
745  double x2 = interval.maxValue();
746 
747  // when there is no rounding beside some effect, when
748  // calculating with doubles, we keep the original value
749 
750  const double eps = 0.000000000001; // since Qt 4.8: qFuzzyIsNull
751  const double max = std::numeric_limits< double >::max();
752 
753  if ( -max + stepSize <= x1 )
754  {
755  const double x = QwtScaleArithmetic::floorEps( x1, stepSize );
756  if ( qAbs(x) <= eps || !qFuzzyCompare( x1, x ) )
757  x1 = x;
758  }
759 
760  if ( max - stepSize >= x2 )
761  {
762  const double x = QwtScaleArithmetic::ceilEps( x2, stepSize );
763  if ( qAbs(x) <= eps || !qFuzzyCompare( x2, x ) )
764  x2 = x;
765  }
766 
767  return QwtInterval( x1, x2 );
768 }
769 
777  QwtScaleEngine( base )
778 {
780 }
781 
784 {
785 }
786 
797 void QwtLogScaleEngine::autoScale( int maxNumSteps,
798  double& x1, double& x2, double& stepSize ) const
799 {
800  if ( x1 > x2 )
801  qSwap( x1, x2 );
802 
803  const double logBase = base();
804 
805  QwtInterval interval( x1 / std::pow( logBase, lowerMargin() ),
806  x2 * std::pow( logBase, upperMargin() ) );
807 
808  if ( interval.maxValue() / interval.minValue() < logBase )
809  {
810  // scale width is less than one step -> try to build a linear scale
811 
812  QwtLinearScaleEngine linearScaler;
813  linearScaler.setAttributes( attributes() );
814  linearScaler.setReference( reference() );
815  linearScaler.setMargins( lowerMargin(), upperMargin() );
816 
817  linearScaler.autoScale( maxNumSteps, x1, x2, stepSize );
818 
819  QwtInterval linearInterval = QwtInterval( x1, x2 ).normalized();
820  linearInterval = linearInterval.limited(
822 
823  if ( linearInterval.maxValue() / linearInterval.minValue() < logBase )
824  {
825  stepSize = 0.0;
826  return;
827  }
828  }
829 
830  double logRef = 1.0;
831  if ( reference() > QwtLogTransform::LogMin / 2 )
832  logRef = qwtMinF( reference(), QwtLogTransform::LogMax / 2 );
833 
835  {
836  const double delta = qwtMaxF( interval.maxValue() / logRef,
837  logRef / interval.minValue() );
838  interval.setInterval( logRef / delta, logRef * delta );
839  }
840 
842  interval = interval.extend( logRef );
843 
845 
846  if ( interval.width() == 0.0 )
847  interval = buildInterval( interval.minValue() );
848 
849  stepSize = divideInterval( qwtLogInterval( logBase, interval ).width(),
850  qMax( maxNumSteps, 1 ) );
851  if ( stepSize < 1.0 )
852  stepSize = 1.0;
853 
855  interval = align( interval, stepSize );
856 
857  x1 = interval.minValue();
858  x2 = interval.maxValue();
859 
861  {
862  qSwap( x1, x2 );
863  stepSize = -stepSize;
864  }
865 }
866 
880  int maxMajorSteps, int maxMinorSteps, double stepSize ) const
881 {
882  QwtInterval interval = QwtInterval( x1, x2 ).normalized();
884 
885  if ( interval.width() <= 0 )
886  return QwtScaleDiv();
887 
888  const double logBase = base();
889 
890  if ( interval.maxValue() / interval.minValue() < logBase )
891  {
892  // scale width is less than one decade -> build linear scale
893 
894  QwtLinearScaleEngine linearScaler;
895  linearScaler.setAttributes( attributes() );
896  linearScaler.setReference( reference() );
897  linearScaler.setMargins( lowerMargin(), upperMargin() );
898 
899  return linearScaler.divideScale( x1, x2,
900  maxMajorSteps, maxMinorSteps, 0.0 );
901  }
902 
903  stepSize = qAbs( stepSize );
904  if ( stepSize == 0.0 )
905  {
906  if ( maxMajorSteps < 1 )
907  maxMajorSteps = 1;
908 
909  stepSize = divideInterval(
910  qwtLogInterval( logBase, interval ).width(), maxMajorSteps );
911  if ( stepSize < 1.0 )
912  stepSize = 1.0; // major step must be >= 1 decade
913  }
914 
915  QwtScaleDiv scaleDiv;
916  if ( stepSize != 0.0 )
917  {
919  buildTicks( interval, stepSize, maxMinorSteps, ticks );
920 
921  scaleDiv = QwtScaleDiv( interval, ticks );
922  }
923 
924  if ( x1 > x2 )
925  scaleDiv.invert();
926 
927  return scaleDiv;
928 }
929 
941  const QwtInterval& interval, double stepSize, int maxMinorSteps,
943 {
944  const QwtInterval boundingInterval = align( interval, stepSize );
945 
946  ticks[QwtScaleDiv::MajorTick] =
947  buildMajorTicks( boundingInterval, stepSize );
948 
949  if ( maxMinorSteps > 0 )
950  {
951  buildMinorTicks( ticks[QwtScaleDiv::MajorTick], maxMinorSteps, stepSize,
953  }
954 
955  for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ )
956  ticks[i] = strip( ticks[i], interval );
957 }
958 
968  const QwtInterval& interval, double stepSize ) const
969 {
970  double width = qwtLogInterval( base(), interval ).width();
971 
972  int numTicks = qRound( width / stepSize ) + 1;
973  if ( numTicks > 10000 )
974  numTicks = 10000;
975 
976  const double lxmin = std::log( interval.minValue() );
977  const double lxmax = std::log( interval.maxValue() );
978  const double lstep = ( lxmax - lxmin ) / double( numTicks - 1 );
979 
980  QList< double > ticks;
981  ticks.reserve( numTicks );
982 
983  ticks += interval.minValue();
984 
985  for ( int i = 1; i < numTicks - 1; i++ )
986  ticks += std::exp( lxmin + double( i ) * lstep );
987 
988  ticks += interval.maxValue();
989 
990  return ticks;
991 }
992 
1003  const QList< double >& majorTicks,
1004  int maxMinorSteps, double stepSize,
1005  QList< double >& minorTicks,
1006  QList< double >& mediumTicks ) const
1007 {
1008  const double logBase = base();
1009 
1010  if ( stepSize < 1.1 ) // major step width is one base
1011  {
1012  double minStep = divideInterval( stepSize, maxMinorSteps + 1 );
1013  if ( minStep == 0.0 )
1014  return;
1015 
1016  const int numSteps = qRound( stepSize / minStep );
1017 
1018  int mediumTickIndex = -1;
1019  if ( ( numSteps > 2 ) && ( numSteps % 2 == 0 ) )
1020  mediumTickIndex = numSteps / 2;
1021 
1022  for ( int i = 0; i < majorTicks.count() - 1; i++ )
1023  {
1024  const double v = majorTicks[i];
1025  const double s = logBase / numSteps;
1026 
1027  if ( s >= 1.0 )
1028  {
1029  if ( !qFuzzyCompare( s, 1.0 ) )
1030  minorTicks += v * s;
1031 
1032  for ( int j = 2; j < numSteps; j++ )
1033  {
1034  minorTicks += v * j * s;
1035  }
1036  }
1037  else
1038  {
1039  for ( int j = 1; j < numSteps; j++ )
1040  {
1041  const double tick = v + j * v * ( logBase - 1 ) / numSteps;
1042  if ( j == mediumTickIndex )
1043  mediumTicks += tick;
1044  else
1045  minorTicks += tick;
1046  }
1047  }
1048  }
1049  }
1050  else
1051  {
1052  double minStep = divideInterval( stepSize, maxMinorSteps );
1053  if ( minStep == 0.0 )
1054  return;
1055 
1056  if ( minStep < 1.0 )
1057  minStep = 1.0;
1058 
1059  // # subticks per interval
1060  int numTicks = qRound( stepSize / minStep ) - 1;
1061 
1062  // Do the minor steps fit into the interval?
1063  if ( qwtFuzzyCompare( ( numTicks + 1 ) * minStep,
1064  stepSize, stepSize ) > 0 )
1065  {
1066  numTicks = 0;
1067  }
1068 
1069  if ( numTicks < 1 )
1070  return;
1071 
1072  int mediumTickIndex = -1;
1073  if ( ( numTicks > 2 ) && ( numTicks % 2 ) )
1074  mediumTickIndex = numTicks / 2;
1075 
1076  // substep factor = base^substeps
1077  const qreal minFactor = qwtMaxF( std::pow( logBase, minStep ), logBase );
1078 
1079  for ( int i = 0; i < majorTicks.count(); i++ )
1080  {
1081  double tick = majorTicks[i];
1082  for ( int j = 0; j < numTicks; j++ )
1083  {
1084  tick *= minFactor;
1085 
1086  if ( j == mediumTickIndex )
1087  mediumTicks += tick;
1088  else
1089  minorTicks += tick;
1090  }
1091  }
1092  }
1093 }
1094 
1107  const QwtInterval& interval, double stepSize ) const
1108 {
1109  const QwtInterval intv = qwtLogInterval( base(), interval );
1110 
1111  double x1 = QwtScaleArithmetic::floorEps( intv.minValue(), stepSize );
1112  if ( qwtFuzzyCompare( interval.minValue(), x1, stepSize ) == 0 )
1113  x1 = interval.minValue();
1114 
1115  double x2 = QwtScaleArithmetic::ceilEps( intv.maxValue(), stepSize );
1116  if ( qwtFuzzyCompare( interval.maxValue(), x2, stepSize ) == 0 )
1117  x2 = interval.maxValue();
1118 
1119  return qwtPowInterval( base(), QwtInterval( x1, x2 ) );
1120 }
A class representing an interval.
Definition: qwt_interval.h:23
void setInterval(double minValue, double maxValue, BorderFlags=IncludeBorders)
Definition: qwt_interval.h:143
double minValue() const
Definition: qwt_interval.h:192
QwtInterval normalized() const
Normalize the limits of the interval.
double width() const
Return the width of an interval.
Definition: qwt_interval.h:227
long double widthL() const
Return the width of an interval as long double.
Definition: qwt_interval.h:241
void setMaxValue(double)
Definition: qwt_interval.h:186
double maxValue() const
Definition: qwt_interval.h:198
QwtInterval limited(double lowerBound, double upperBound) const
QwtInterval extend(double value) const
Extend the interval.
void setMinValue(double)
Definition: qwt_interval.h:176
bool isValid() const
Definition: qwt_interval.h:210
QwtInterval symmetrize(double value) const
A scale engine for linear scales.
void buildMinorTicks(const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const
Calculate minor/medium ticks for major ticks.
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const override
void buildTicks(const QwtInterval &, double stepSize, int maxMinorSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const
Calculate ticks for an interval.
QList< double > buildMajorTicks(const QwtInterval &interval, double stepSize) const
Calculate major ticks for an interval.
QwtLinearScaleEngine(uint base=10)
virtual ~QwtLinearScaleEngine()
Destructor.
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const override
Calculate a scale division for an interval.
QwtInterval align(const QwtInterval &, double stepSize) const
Align an interval to a step size.
QList< double > buildMajorTicks(const QwtInterval &interval, double stepSize) const
Calculate major ticks for an interval.
void buildMinorTicks(const QList< double > &majorTicks, int maxMinorSteps, double stepSize, QList< double > &minorTicks, QList< double > &mediumTicks) const
Calculate minor/medium ticks for major ticks.
void buildTicks(const QwtInterval &, double stepSize, int maxMinorSteps, QList< double > ticks[QwtScaleDiv::NTickTypes]) const
Calculate ticks for an interval.
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const override
Calculate a scale division for an interval.
QwtLogScaleEngine(uint base=10)
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const override
QwtInterval align(const QwtInterval &, double stepSize) const
Align an interval to a step size.
virtual ~QwtLogScaleEngine()
Destructor.
Logarithmic transformation.
static const double LogMax
Largest allowed value for logarithmic scales: 1.0e150.
static const double LogMin
Smallest allowed value for logarithmic scales: 1.0e-150.
static double divideEps(double intervalSize, double numSteps)
Divide an interval into steps.
static double ceilEps(double value, double intervalSize)
static double floorEps(double value, double intervalSize)
static double divideInterval(double intervalSize, int numSteps, uint base)
A class representing a scale division.
Definition: qwt_scale_div.h:34
@ MediumTick
Medium ticks.
Definition: qwt_scale_div.h:46
@ MinorTick
Minor ticks.
Definition: qwt_scale_div.h:43
@ NTickTypes
Number of valid tick types.
Definition: qwt_scale_div.h:52
@ MajorTick
Major ticks.
Definition: qwt_scale_div.h:49
Base class for scale engines.
QwtTransform * transformation() const
double reference() const
QFlags< Attribute > Attributes
QwtScaleEngine(uint base=10)
QList< double > strip(const QList< double > &, const QwtInterval &) const
@ Inverted
Turn the scale upside down.
@ NoAttribute
No attributes.
@ Symmetric
Build a scale which is symmetric to the reference() value.
@ IncludeReference
Build a scale which includes the reference() value.
double divideInterval(double intervalSize, int numSteps) const
double upperMargin() const
bool contains(const QwtInterval &, double value) const
bool testAttribute(Attribute) const
QwtInterval buildInterval(double value) const
Build an interval around a value.
void setReference(double)
Specify a reference point.
virtual ~QwtScaleEngine()
Destructor.
double lowerMargin() const
void setAttributes(Attributes)
void setAttribute(Attribute, bool on=true)
void setTransformation(QwtTransform *)
Attributes attributes() const
void setMargins(double lower, double upper)
Specify margins at the scale's endpoints.
void setBase(uint base)
A transformation between coordinate systems.
Definition: qwt_transform.h:36