DateTimeRangeHelper.h
86 lines
| 2.9 KiB
| text/x-c
|
CLexer
r8 | #ifndef SCIQLOP_DATETIMERANGEHELPER_H | |||
#define SCIQLOP_DATETIMERANGEHELPER_H | ||||
r23 | #include <optional> | |||
r8 | #include <cmath> | |||
r12 | #include <variant> | |||
r8 | #include <QObject> | |||
#include <QDebug> | ||||
#include <opaque/numeric_typedef.hpp> | ||||
#include <Common/DateUtils.h> | ||||
#include <Common/MetaTypes.h> | ||||
#include <Common/Numeric.h> | ||||
#include <Data/DateTimeRange.h> | ||||
r25 | enum class TransformationType { ZoomOut, ZoomIn, PanRight, PanLeft, Unknown }; | |||
r8 | namespace DateTimeRangeHelper { | |||
r14 | inline bool isnan(const DateTimeRange& range) | |||
r10 | { | |||
return std::isnan(range.m_TStart) && std::isnan(range.m_TEnd); | ||||
} | ||||
r14 | inline bool hasnan(const DateTimeRange& range) | |||
r10 | { | |||
return std::isnan(range.m_TStart) || std::isnan(range.m_TEnd); | ||||
} | ||||
r8 | ||||
r14 | inline bool isPureShift(const DateTimeRange& range1, const DateTimeRange& range2) | |||
r8 | { | |||
r9 | return SciQLop::numeric::almost_equal<double>(range1.delta(), range2.delta(), 1) | |||
&& !SciQLop::numeric::almost_equal(range1.m_TStart, range2.m_TStart, 1); | ||||
r8 | } | |||
r14 | inline bool isPureZoom(const DateTimeRange& range1, const DateTimeRange& range2) | |||
r8 | { | |||
r9 | return !SciQLop::numeric::almost_equal<double>(range1.delta(),range2.delta(),1)&& | |||
SciQLop::numeric::almost_equal<double>(range1.center(), range2.center(),1); | ||||
r8 | } | |||
r25 | ||||
r8 | /** | |||
* @brief computeTransformation such as range2 = zoom*range1 + shift | ||||
* @param range1 | ||||
* @param range2 | ||||
r9 | * @return trnaformation applied to range1 to get range2 or an object of type | |||
* InvalidDateTimeRangeTransformation if the transformation has NaN or forbiden values | ||||
r8 | */ | |||
r15 | inline std::optional<DateTimeRangeTransformation> | |||
r9 | computeTransformation(const DateTimeRange& range1, const DateTimeRange& range2) | |||
r8 | { | |||
r15 | std::optional<DateTimeRangeTransformation> transformation; | |||
r9 | double zoom = range2.delta()/range1.delta(); | |||
Seconds<double> shift = range2.center() - (range1*zoom).center(); | ||||
bool zoomValid = zoom!=0. && !std::isnan(zoom) && !std::isinf(zoom); | ||||
bool shiftValid = !std::isnan(shift.value) && !std::isinf(shift.value); | ||||
if(zoomValid && shiftValid) | ||||
r15 | transformation = DateTimeRangeTransformation{zoom, shift}; | |||
return transformation; | ||||
r8 | } | |||
r25 | inline TransformationType getTransformationType(const DateTimeRange& range1, const DateTimeRange& range2) | |||
{ | ||||
auto transformation = computeTransformation (range1,range2); | ||||
if(transformation.has_value ()) | ||||
{ | ||||
if(SciQLop::numeric::almost_equal(transformation->zoom,1.)) | ||||
{ | ||||
if(transformation->shift > 0.) | ||||
return TransformationType::PanRight; | ||||
return TransformationType::PanLeft; | ||||
} | ||||
if(transformation->zoom > 0.) | ||||
return TransformationType::ZoomOut; | ||||
return TransformationType::ZoomIn; | ||||
} | ||||
return TransformationType::Unknown; | ||||
} | ||||
r8 | } | |||
#endif // SCIQLOP_DATETIMERANGEHELPER_H | ||||