14 #include <qdatetime.h> 20 static const double msecs[] =
26 24.0 * 3600.0 * 1000.0,
27 7.0 * 24.0 * 3600.0 * 1000.0,
28 30.0 * 24.0 * 3600.0 * 1000.0,
29 365.0 * 24.0 * 3600.0 * 1000.0,
32 if ( type < 0 || type >= static_cast<int>(
sizeof( msecs ) /
sizeof( msecs[0] ) ) )
39 double value,
double stepSize,
bool up )
41 double d = value / stepSize;
42 d = up ? std::ceil( d ) : std::floor( d );
44 return static_cast<int>( d * stepSize );
50 switch( intervalType )
54 const double secsTo = minDate.secsTo( maxDate );
55 const double msecs = maxDate.time().msec() -
56 minDate.time().msec();
58 return secsTo * 1000 + msecs;
62 return minDate.secsTo( maxDate );
66 const double secsTo = minDate.secsTo( maxDate );
67 return std::floor( secsTo / 60 );
71 const double secsTo = minDate.secsTo( maxDate );
72 return std::floor( secsTo / 3600 );
76 return minDate.daysTo( maxDate );
80 return std::floor( minDate.daysTo( maxDate ) / 7.0 );
85 double( maxDate.date().year() ) - minDate.date().year();
87 int months = maxDate.date().month() - minDate.date().month();
88 if ( maxDate.date().day() < minDate.date().day() )
91 return years * 12 + months;
96 double( maxDate.date().year() ) - minDate.date().year();
98 if ( maxDate.date().month() < minDate.date().month() )
109 const QDateTime &minDate,
const QDateTime &maxDate,
113 const QDateTime maxD =
QwtDate::ceil( maxDate, intervalType );
119 const int limits[],
size_t numLimits )
121 for ( uint i = 0; i < numLimits; i++ )
123 const int numSteps = intervalSize / limits[ i ];
125 if ( numSteps > 1 && numSteps <= maxSteps &&
126 numSteps * limits[ i ] == intervalSize )
135 static int qwtStepSize(
int intervalSize,
int maxSteps, uint base )
142 for (
int numSteps = maxSteps; numSteps > 1; numSteps-- )
144 const double stepSize = double( intervalSize ) / numSteps;
146 const double p = std::floor( std::log( stepSize ) / std::log(
double( base ) ) );
147 const double fraction = std::pow( base, p );
149 for ( uint n = base; n >= 1; n /= 2 )
151 if ( qFuzzyCompare( stepSize, n * fraction ) )
152 return qRound( stepSize );
154 if ( n == 3 && ( base % 2 ) == 0 )
156 if ( qFuzzyCompare( stepSize, 2 * fraction ) )
157 return qRound( stepSize );
167 const int limits[],
size_t numLimits )
169 const int v =
qwtCeil( intervalSize /
double( numSteps ) );
171 for ( uint i = 0; i < numLimits - 1; i++ )
173 if ( v <= limits[i] )
177 return limits[ numLimits - 1 ];
185 if ( ( intervalSize > numSteps ) &&
186 ( intervalSize <= 2 * numSteps ) )
194 switch( intervalType )
199 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
202 limits,
sizeof( limits ) /
sizeof(
int ) );
208 static int limits[] = { 1, 2, 3, 4, 6, 12, 24 };
211 limits,
sizeof( limits ) /
sizeof(
int ) );
217 const double v = intervalSize / double( numSteps );
219 stepSize = std::ceil( v );
221 stepSize = std::ceil( v / 7 ) * 7;
227 static int limits[] = { 1, 2, 4, 8, 12, 26, 52 };
230 limits,
sizeof( limits ) /
sizeof(
int ) );
236 static int limits[] = { 1, 2, 3, 4, 6, 12 };
239 limits,
sizeof( limits ) /
sizeof(
int ) );
248 intervalSize, numSteps, 10 );
258 double minStepSize = 0.0;
260 switch( intervalType )
264 minStepSize =
qwtStepSize( stepSize, maxMinSteps, 10 );
265 if ( minStepSize == 0.0 )
266 minStepSize = 0.5 * stepSize;
272 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
276 if ( stepSize > maxMinSteps )
279 limits,
sizeof( limits ) /
sizeof(
int ) );
285 limits,
sizeof( limits ) /
sizeof(
int ) );
289 minStepSize = stepSize / numSteps;
297 if ( stepSize > maxMinSteps )
299 static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 };
302 limits,
sizeof( limits ) /
sizeof(
int ) );
306 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
309 limits,
sizeof( limits ) /
sizeof(
int ) );
313 minStepSize = stepSize / numSteps;
321 if ( stepSize > maxMinSteps )
323 static int limits[] = { 1, 2, 3, 7, 14, 28 };
326 limits,
sizeof( limits ) /
sizeof(
int ) );
330 static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 };
333 limits,
sizeof( limits ) /
sizeof(
int ) );
337 minStepSize = stepSize / numSteps;
343 const int daysInStep = stepSize * 7;
345 if ( maxMinSteps >= daysInStep )
348 minStepSize = 1.0 / 7.0;
355 const int stepSizeInWeeks = stepSize;
357 if ( stepSizeInWeeks <= maxMinSteps )
364 stepSizeInWeeks, maxMinSteps, 10 );
373 if ( stepSize < maxMinSteps )
374 maxMinSteps =
static_cast<int>( stepSize );
376 static int limits[] = { 1, 2, 3, 4, 6, 12 };
379 limits,
sizeof( limits ) /
sizeof(
int ) );
382 minStepSize = stepSize / numSteps;
388 if ( stepSize >= maxMinSteps )
391 stepSize, maxMinSteps, 10 );
397 static int limits[] = { 1, 2, 3, 4, 6, 12 };
399 int numSteps =
qwtStepCount( 12 * stepSize, maxMinSteps,
400 limits,
sizeof( limits ) /
sizeof(
int ) );
403 minStepSize = stepSize / numSteps;
413 && minStepSize == 0.0 )
415 minStepSize = 0.5 * stepSize;
422 int secondsMajor,
int secondsMinor )
424 if ( secondsMinor <= 0 )
427 QDateTime minDate = dateTime.addSecs( -secondsMajor );
435 while ( minDate < dateTime &&
438 minDate = minDate.addSecs( 3600 );
439 dstMin += 3600 * 1000.0;
443 ticks.reserve( 3600 / secondsMinor);
445 for (
int i = 0; i < 3600; i += secondsMinor )
446 ticks += dstMin + i * 1000.0;
452 const QDateTime &minDate,
const QDateTime &maxDate,
453 double stepSize,
int maxMinSteps,
457 double minStepSize = 0;
459 if ( maxMinSteps > 1 )
462 maxMinSteps, intervalType );
465 bool daylightSaving =
false;
466 if ( minDate.timeSpec() == Qt::LocalTime )
469 if ( intervalType == QwtDate::Hour )
471 daylightSaving = stepSize > 1;
476 const int secondsMajor =
static_cast<int>( stepSize * s );
477 const double secondsMinor = minStepSize * s;
490 for ( QDateTime dt = minDate; dt <= maxDate;
491 dt = dt.addSecs( secondsMajor ) )
498 if ( daylightSaving )
501 majorValue += offset * 1000.0;
503 if ( offset > dstOff )
508 dt, secondsMajor, qRound( secondsMinor ) );
514 if ( majorTicks.isEmpty() || majorTicks.last() != majorValue )
515 majorTicks += majorValue;
517 if ( secondsMinor > 0.0 )
519 const int numMinorSteps =
qwtFloor( secondsMajor / secondsMinor );
521 for (
int i = 1; i < numMinorSteps; i++ )
523 const QDateTime mt = dt.addMSecs(
524 qRound64( i * secondsMinor * 1000 ) );
527 if ( daylightSaving )
530 minorValue += offset * 1000.0;
533 if ( minorTicks.isEmpty() || minorTicks.last() != minorValue )
535 const bool isMedium = ( numMinorSteps % 2 == 0 )
536 && ( i != 1 ) && ( i == numMinorSteps / 2 );
539 mediumTicks += minorValue;
541 minorTicks += minorValue;
560 QDateTime &minDate,
const QDateTime &maxDate,
561 double stepSize,
int maxMinSteps )
568 int minStepSize = 0.0;
570 if ( maxMinSteps > 1 )
574 if ( maxMinSteps >= 30 )
576 else if ( maxMinSteps >= 6 )
578 else if ( maxMinSteps >= 3 )
594 for ( QDateTime dt = minDate;
595 dt <= maxDate; dt = dt.addMonths( stepSize ) )
602 if ( minStepDays > 0 )
604 for (
int days = minStepDays;
605 days < 30; days += minStepDays )
609 if ( days == 15 && minStepDays != 15 )
615 else if ( minStepSize > 0.0 )
617 const int numMinorSteps = qRound( stepSize / (
double) minStepSize );
619 for (
int i = 1; i < numMinorSteps; i++ )
621 const double minorValue =
624 if ( ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 ) )
625 mediumTicks += minorValue;
627 minorTicks += minorValue;
644 const QDateTime &minDate,
const QDateTime &maxDate,
645 double stepSize,
int maxMinSteps )
651 double minStepSize = 0.0;
653 if ( maxMinSteps > 1 )
659 int numMinorSteps = 0;
660 if ( minStepSize > 0.0 )
661 numMinorSteps =
qwtFloor( stepSize / minStepSize );
663 bool dateBC = minDate.date().year() < -1;
665 for ( QDateTime dt = minDate; dt <= maxDate;
666 dt = dt.addYears( stepSize ) )
668 if ( dateBC && dt.date().year() > 1 )
671 dt = dt.addYears( -1 );
680 for (
int i = 1; i < numMinorSteps; i++ )
684 const double years = qRound( i * minStepSize );
687 tickDate = dt.addYears( years );
691 tickDate = dt.addMonths( qRound( years * 12 ) );
694 const bool isMedium = ( numMinorSteps > 2 ) &&
695 ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 );
699 mediumTicks += minorValue;
701 minorTicks += minorValue;
870 const QDateTime &minDate,
const QDateTime &maxDate,
873 const double jdMin = minDate.date().toJulianDay();
874 const double jdMax = maxDate.date().toJulianDay();
876 if ( ( jdMax - jdMin ) / 365 > maxSteps )
880 if ( months > maxSteps * 6 )
888 if ( days > 4 * maxSteps * 7 )
892 if ( days > maxSteps * 7 )
896 if ( hours > maxSteps * 24 )
901 if ( seconds >= maxSteps * 3600 )
904 if ( seconds >= maxSteps * 60 )
907 if ( seconds >= maxSteps )
930 double &x1,
double &x2,
double &stepSize )
const 946 if ( interval.
width() == 0.0 )
952 if ( from.isValid() && to.isValid() )
954 if ( maxNumSteps < 1 )
962 const double stepWidth =
qwtDivideScale( width, maxNumSteps, intvType );
965 const QDateTime d1 =
alignDate( from, stepWidth, intvType,
false );
966 const QDateTime d2 =
alignDate( to, stepWidth, intvType,
true );
981 stepSize = -stepSize;
997 int maxMajorSteps,
int maxMinorSteps,
double stepSize )
const 999 if ( maxMajorSteps < 1 )
1011 stepSize = qAbs( stepSize );
1012 if ( stepSize > 0.0 )
1018 maxMajorSteps =
qwtCeil( ( max - min ) / stepSize );
1030 maxMajorSteps, maxMinorSteps, stepSize );
1038 maxMajorSteps, maxMinorSteps, intvType );
1043 scaleDiv = scaleDiv.
bounded( min, max );
1053 const QDateTime &minDate,
const QDateTime &maxDate,
1054 int maxMajorSteps,
int maxMinorSteps,
1060 maxMajorSteps, intervalType );
1063 QDateTime dt0 =
alignDate( minDate, stepSize, intervalType,
false );
1064 if ( !dt0.isValid() )
1068 dt0 =
alignDate( minDate, stepSize, intervalType,
true );
1076 stepSize, maxMinorSteps, intervalType );
1083 stepSize, maxMinorSteps );
1088 stepSize, maxMinorSteps );
1113 const QDateTime &dateTime,
double stepSize,
1118 QDateTime dt = dateTime;
1120 if ( dateTime.timeSpec() == Qt::OffsetFromUTC )
1122 #if QT_VERSION >= 0x050200 1123 dt.setOffsetFromUtc( 0 );
1125 dt.setUtcOffset( 0 );
1129 switch( intervalType )
1134 dt.time().msec(), stepSize, up ) ;
1137 dt = dt.addMSecs( ms );
1143 int second = dt.time().second();
1146 if ( dt.time().msec() > 0 )
1153 dt = dt.addSecs( s );
1159 int minute = dt.time().minute();
1162 if ( dt.time().msec() > 0 || dt.time().second() > 0 )
1169 dt = dt.addSecs( m * 60 );
1175 int hour = dt.time().hour();
1178 if ( dt.time().msec() > 0 || dt.time().second() > 0
1179 || dt.time().minute() > 0 )
1187 dt = dt.addSecs( h * 3600 );
1197 int day = dt.date().dayOfYear();
1200 if ( dt.time() > QTime( 0, 0 ) )
1207 dt = dt.addDays( d - 1 );
1216 int numWeeks = date.daysTo( dt.date() ) / 7;
1219 if ( dt.time() > QTime( 0, 0 ) ||
1220 date.daysTo( dt.date() ) % 7 )
1230 dt = dt.addDays( d );
1236 int month = dt.date().month();
1239 if ( dt.date().day() > 1 ||
1240 dt.time() > QTime( 0, 0 ) )
1249 dt = dt.addMonths( m );
1255 int year = dateTime.date().year();
1258 if ( dateTime.date().dayOfYear() > 1 ||
1259 dt.time() > QTime( 0, 0 ) )
1271 dt.setDate( QDate( stepSize, 1, 1 ).addYears( -stepSize ) );
1275 dt.setDate( QDate( y, 1, 1 ) );
1282 if ( dateTime.timeSpec() == Qt::OffsetFromUTC )
1284 #if QT_VERSION >= 0x050200 1285 dt.setOffsetFromUtc( dateTime.offsetFromUtc() );
1287 dt.setUtcOffset( dateTime.utcOffset() );
1305 if ( !dt.isValid() )
1307 const QDate date = ( value <= 0.0 )
1316 #if QT_VERSION >= 0x050200 The interval is related to weeks.
enum MQTTPropertyCodes value
The interval is related to years.
QwtInterval normalized() const
Normalize the limits of the interval.
void setTimeSpec(Qt::TimeSpec)
The interval is related to months.
static double qwtDivideScale(double intervalSize, int numSteps, QwtDate::IntervalType intervalType)
static double qwtDivideMajorStep(double stepSize, int maxMinSteps, QwtDate::IntervalType intervalType)
bool testAttribute(Attribute) const
QwtScaleDiv bounded(double lowerBound, double upperBound) const
static int qwtStepCount(int intervalSize, int maxSteps, const int limits[], size_t numLimits)
QDateTime toDateTime(double) const
A class representing an interval.
void setWeek0Type(QwtDate::Week0Type)
static QwtScaleDiv qwtDivideToMonths(QDateTime &minDate, const QDateTime &maxDate, double stepSize, int maxMinSteps)
QWT_CONSTEXPR float qwtMaxF(float a, float b)
void setTicks(int tickType, const QList< double > &)
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const QWT_OVERRIDE
Calculate a scale division for a date/time interval.
QwtDate::Week0Type week0Type() const
virtual ~QwtDateScaleEngine()
Destructor.
static double qwtRoundedIntervalWidth(const QDateTime &minDate, const QDateTime &maxDate, QwtDate::IntervalType intervalType)
static QDateTime floor(const QDateTime &, IntervalType)
QwtInterval buildInterval(double value) const
Build an interval around a value.
A class representing a scale division.
static double toDouble(const QDateTime &)
double upperMargin() const
double lowerMargin() const
QWT_CONSTEXPR float qwtMinF(float a, float b)
static double divideInterval(double intervalSize, int numSteps, uint base)
int qwtFloor(qreal value)
QwtDate::Week0Type week0Type
void setInterval(double lowerBound, double upperBound)
The interval is related to minutes.
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const QWT_OVERRIDE
Qt::TimeSpec timeSpec() const
QwtDateScaleEngine(Qt::TimeSpec=Qt::LocalTime)
Constructor.
The interval is related to hours.
static QList< double > qwtDstTicks(const QDateTime &dateTime, int secondsMajor, int secondsMinor)
static int utcOffset(const QDateTime &)
virtual QDateTime alignDate(const QDateTime &, double stepSize, QwtDate::IntervalType, bool up) const
void setUtcOffset(int seconds)
static QwtScaleDiv qwtDivideToYears(const QDateTime &minDate, const QDateTime &maxDate, double stepSize, int maxMinSteps)
static QwtScaleDiv qwtDivideToSeconds(const QDateTime &minDate, const QDateTime &maxDate, double stepSize, int maxMinSteps, QwtDate::IntervalType intervalType)
The interval is related to milliseconds.
static int qwtStepSize(int intervalSize, int maxSteps, uint base)
static double qwtMsecsForType(int type)
Build a scale which is symmetric to the reference() value.
QwtScaleDiv buildScaleDiv(const QDateTime &, const QDateTime &, int maxMajorSteps, int maxMinorSteps, QwtDate::IntervalType) const
static QDateTime ceil(const QDateTime &, IntervalType)
static int qwtAlignValue(double value, double stepSize, bool up)
static QDate dateOfWeek0(int year, Week0Type)
Date of the first day of the first week for a year.
Turn the scale upside down.
static QDateTime toDateTime(double value, Qt::TimeSpec=Qt::UTC)
A collection of methods around date/time values.
A scale engine for linear scales.
QwtInterval extend(double value) const
Extend the interval.
virtual QwtDate::IntervalType intervalType(const QDateTime &, const QDateTime &, int maxSteps) const
QwtInterval symmetrize(double value) const
double width() const
Return the width of an interval.
Build a scale which includes the reference() value.
The interval is related to seconds.
static double qwtIntervalWidth(const QDateTime &minDate, const QDateTime &maxDate, QwtDate::IntervalType intervalType)
static int qwtDivideInterval(double intervalSize, int numSteps, const int limits[], size_t numLimits)
PrivateData(Qt::TimeSpec spec)
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const QWT_OVERRIDE
Calculate a scale division for an interval.
The interval is related to days.