13 #include <qdatetime.h> 18 static const double msecs[] =
24 24.0 * 3600.0 * 1000.0,
25 7.0 * 24.0 * 3600.0 * 1000.0,
26 30.0 * 24.0 * 3600.0 * 1000.0,
27 365.0 * 24.0 * 3600.0 * 1000.0,
30 if ( type < 0 || type >= static_cast<int>(
sizeof( msecs ) /
sizeof( msecs[0] ) ) )
37 double value,
double stepSize,
bool up )
39 double d = value / stepSize;
40 d = up ? ::ceil( d ) : ::floor( d );
42 return static_cast<int>( d * stepSize );
48 switch( intervalType )
52 const double secsTo = minDate.secsTo( maxDate );
53 const double msecs = maxDate.time().msec() -
54 minDate.time().msec();
56 return secsTo * 1000 + msecs;
60 return minDate.secsTo( maxDate );
64 const double secsTo = minDate.secsTo( maxDate );
65 return ::floor( secsTo / 60 );
69 const double secsTo = minDate.secsTo( maxDate );
70 return ::floor( secsTo / 3600 );
74 return minDate.daysTo( maxDate );
78 return ::floor( minDate.daysTo( maxDate ) / 7.0 );
83 double( maxDate.date().year() ) - minDate.date().year();
85 int months = maxDate.date().month() - minDate.date().month();
86 if ( maxDate.date().day() < minDate.date().day() )
89 return years * 12 + months;
94 double( maxDate.date().year() ) - minDate.date().year();
96 if ( maxDate.date().month() < minDate.date().month() )
107 const QDateTime &minDate,
const QDateTime &maxDate,
111 const QDateTime maxD =
QwtDate::ceil( maxDate, intervalType );
117 const int limits[],
size_t numLimits )
119 for ( uint
i = 0;
i < numLimits;
i++ )
121 const int numSteps = intervalSize / limits[
i ];
123 if ( numSteps > 1 && numSteps <= maxSteps &&
124 numSteps * limits[
i ] == intervalSize )
133 static int qwtStepSize(
int intervalSize,
int maxSteps, uint base )
140 for (
int numSteps = maxSteps; numSteps > 1; numSteps-- )
142 const double stepSize = double( intervalSize ) / numSteps;
144 const double p = ::floor( ::
log( stepSize ) / ::
log(
double( base ) ) );
145 const double fraction = qPow( base, p );
147 for ( uint
n = base;
n >= 1;
n /= 2 )
149 if ( qFuzzyCompare( stepSize,
n * fraction ) )
150 return qRound( stepSize );
152 if (
n == 3 && ( base % 2 ) == 0 )
154 if ( qFuzzyCompare( stepSize, 2 * fraction ) )
155 return qRound( stepSize );
165 const int limits[],
size_t numLimits )
167 const int v = qCeil( intervalSize /
double( numSteps ) );
169 for ( uint
i = 0;
i < numLimits - 1;
i++ )
171 if ( v <= limits[
i] )
175 return limits[ numLimits - 1 ];
183 if ( ( intervalSize > numSteps ) &&
184 ( intervalSize <= 2 * numSteps ) )
192 switch( intervalType )
197 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
200 limits,
sizeof( limits ) /
sizeof(
int ) );
206 static int limits[] = { 1, 2, 3, 4, 6, 12, 24 };
209 limits,
sizeof( limits ) /
sizeof(
int ) );
215 const double v = intervalSize / double( numSteps );
217 stepSize = qCeil( v );
219 stepSize = qCeil( v / 7 ) * 7;
225 static int limits[] = { 1, 2, 4, 8, 12, 26, 52 };
228 limits,
sizeof( limits ) /
sizeof(
int ) );
234 static int limits[] = { 1, 2, 3, 4, 6, 12 };
237 limits,
sizeof( limits ) /
sizeof(
int ) );
246 intervalSize, numSteps, 10 );
256 double minStepSize = 0.0;
258 switch( intervalType )
262 minStepSize =
qwtStepSize( stepSize, maxMinSteps, 10 );
263 if ( minStepSize == 0.0 )
264 minStepSize = 0.5 * stepSize;
270 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
274 if ( stepSize > maxMinSteps )
277 limits,
sizeof( limits ) /
sizeof(
int ) );
283 limits,
sizeof( limits ) /
sizeof(
int ) );
287 minStepSize = double( stepSize ) / numSteps;
295 if ( stepSize > maxMinSteps )
297 static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 };
300 limits,
sizeof( limits ) /
sizeof(
int ) );
304 static int limits[] = { 1, 2, 5, 10, 15, 20, 30, 60 };
307 limits,
sizeof( limits ) /
sizeof(
int ) );
311 minStepSize = double( stepSize ) / numSteps;
319 if ( stepSize > maxMinSteps )
321 static int limits[] = { 1, 2, 3, 7, 14, 28 };
324 limits,
sizeof( limits ) /
sizeof(
int ) );
328 static int limits[] = { 1, 2, 3, 4, 6, 12, 24, 48, 72 };
331 limits,
sizeof( limits ) /
sizeof(
int ) );
335 minStepSize = double( stepSize ) / numSteps;
341 const int daysInStep = stepSize * 7;
343 if ( maxMinSteps >= daysInStep )
346 minStepSize = 1.0 / 7.0;
353 const int stepSizeInWeeks = stepSize;
355 if ( stepSizeInWeeks <= maxMinSteps )
362 stepSizeInWeeks, maxMinSteps, 10 );
371 if ( stepSize < maxMinSteps )
372 maxMinSteps =
static_cast<int>( stepSize );
374 static int limits[] = { 1, 2, 3, 4, 6, 12 };
377 limits,
sizeof( limits ) /
sizeof(
int ) );
380 minStepSize = double( stepSize ) / numSteps;
386 if ( stepSize >= maxMinSteps )
389 stepSize, maxMinSteps, 10 );
395 static int limits[] = { 1, 2, 3, 4, 6, 12 };
397 int numSteps =
qwtStepCount( 12 * stepSize, maxMinSteps,
398 limits,
sizeof( limits ) /
sizeof(
int ) );
401 minStepSize = double( stepSize ) / numSteps;
411 && minStepSize == 0.0 )
413 minStepSize = 0.5 * stepSize;
420 int secondsMajor,
int secondsMinor )
422 if ( secondsMinor <= 0 )
425 QDateTime minDate = dateTime.addSecs( -secondsMajor );
433 while ( minDate < dateTime &&
436 minDate = minDate.addSecs( 3600 );
437 dstMin += 3600 * 1000.0;
441 #if QT_VERSION >= 0x040700 442 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;
486 QList<double> majorTicks;
487 QList<double> mediumTicks;
488 QList<double> minorTicks;
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 = qFloor( 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 )
590 QList<double> majorTicks;
591 QList<double> mediumTicks;
592 QList<double> minorTicks;
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 )
647 QList<double> majorTicks;
648 QList<double> mediumTicks;
649 QList<double> minorTicks;
651 double minStepSize = 0.0;
653 if ( maxMinSteps > 1 )
659 int numMinorSteps = 0;
660 if ( minStepSize > 0.0 )
661 numMinorSteps = qFloor( 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 );
685 if ( years >= INT_MAX / 12 )
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 )
1002 const double min = qMin( x1, x2 );
1003 const double max = qMax( x1, x2 );
1011 stepSize = qAbs( stepSize );
1012 if ( stepSize > 0.0 )
1018 maxMajorSteps = qCeil( ( 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 dt.setUtcOffset( 0 );
1125 switch( intervalType )
1130 dt.time().msec(), stepSize, up ) ;
1133 dt = dt.addMSecs( ms );
1139 int second = dt.time().second();
1142 if ( dt.time().msec() > 0 )
1149 dt = dt.addSecs( s );
1155 int minute = dt.time().minute();
1158 if ( dt.time().msec() > 0 || dt.time().second() > 0 )
1165 dt = dt.addSecs( m * 60 );
1171 int hour = dt.time().hour();
1174 if ( dt.time().msec() > 0 || dt.time().second() > 0
1175 || dt.time().minute() > 0 )
1183 dt = dt.addSecs( h * 3600 );
1193 int day = dt.date().dayOfYear();
1196 if ( dt.time() > QTime( 0, 0 ) )
1203 dt = dt.addDays( d - 1 );
1212 int numWeeks = date.daysTo( dt.date() ) / 7;
1215 if ( dt.time() > QTime( 0, 0 ) ||
1216 date.daysTo( dt.date() ) % 7 )
1226 dt = dt.addDays( d );
1232 int month = dt.date().month();
1235 if ( dt.date().day() > 1 ||
1236 dt.time() > QTime( 0, 0 ) )
1245 dt = dt.addMonths( m );
1251 int year = dateTime.date().year();
1254 if ( dateTime.date().dayOfYear() > 1 ||
1255 dt.time() > QTime( 0, 0 ) )
1267 dt.setDate( QDate( stepSize, 1, 1 ).addYears( -stepSize ) );
1271 dt.setDate( QDate( y, 1, 1 ) );
1278 if ( dateTime.timeSpec() == Qt::OffsetFromUTC )
1280 dt.setUtcOffset( dateTime.utcOffset() );
1297 if ( !dt.isValid() )
1299 const QDate date = ( value <= 0.0 )
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const
The interval is related to weeks.
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)
void setTicks(int tickType, const QList< double > &)
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const
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)
A class representing a scale division.
static double toDouble(const QDateTime &)
static double divideInterval(double interval, int numSteps, uint base)
double upperMargin() const
TFSIMD_FORCE_INLINE const tfScalar & y() const
double lowerMargin() const
QwtDate::Week0Type week0Type
void setInterval(double lowerBound, double upperBound)
std::chrono::duration< std::int_fast64_t > seconds
The interval is related to minutes.
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
static double qwtMsecsForType(QwtDate::IntervalType type)
void setUtcOffset(int seconds)
static QwtScaleDiv qwtDivideToYears(const QDateTime &minDate, const QDateTime &maxDate, double stepSize, int maxMinSteps)
virtual QwtScaleDiv divideScale(double x1, double x2, int numMajorSteps, int numMinorSteps, double stepSize=0.0) const
Calculate a scale division for an interval.
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)
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.
QwtInterval buildInterval(double v) const
Build an interval around a value.
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)
The interval is related to days.