Go to the documentation of this file.00001 #include "timeseries_qwt.h"
00002 #include <limits>
00003 #include <stdexcept>
00004 #include <QMessageBox>
00005 #include <QPushButton>
00006 #include <QString>
00007
00008 TimeseriesQwt::TimeseriesQwt(const PlotData *source_data, const PlotData *transformed_data):
00009 DataSeriesBase( transformed_data ),
00010 _source_data(source_data),
00011 _cached_data("")
00012 {
00013 }
00014
00015 PlotData::RangeValueOpt TimeseriesQwt::getVisualizationRangeY(PlotData::RangeTime range_X)
00016 {
00017 int first_index = transformedData()->getIndexFromX( range_X.min );
00018 int last_index = transformedData()->getIndexFromX( range_X.max );
00019
00020 if( first_index > last_index || first_index <0 || last_index <0 )
00021 {
00022 return PlotData::RangeValueOpt();
00023 }
00024
00025
00026 if( first_index == 0 && last_index == transformedData()->size()-1)
00027 {
00028 return PlotData::RangeValueOpt( { _bounding_box.bottom(),
00029 _bounding_box.top() } );
00030 }
00031
00032 double min_y =( std::numeric_limits<double>::max() );
00033 double max_y =(-std::numeric_limits<double>::max() );
00034
00035 for (size_t i = first_index; i < last_index; i++)
00036 {
00037 const double Y = sample(i).y();
00038 min_y = std::min( min_y, Y );
00039 max_y = std::max( max_y, Y );
00040 }
00041 return PlotData::RangeValueOpt( { min_y, max_y } );
00042 }
00043
00044
00045 nonstd::optional<QPointF> TimeseriesQwt::sampleFromTime(double t)
00046 {
00047 int index = transformedData()->getIndexFromX(t);
00048 if( index < 0 )
00049 {
00050 return nonstd::optional<QPointF>();
00051 }
00052 const auto& p = transformedData()->at( size_t(index) );
00053 return QPointF(p.x, p.y);
00054 }
00055
00056
00057 bool Timeseries_NoTransform::updateCache()
00058 {
00059 calculateBoundingBox();
00060 return true;
00061 }
00062
00063 bool Timeseries_1stDerivative::updateCache()
00064 {
00065 size_t data_size = _source_data->size();
00066
00067 if( data_size <= 1)
00068 {
00069 _cached_data.clear();
00070 _bounding_box = QRectF();
00071 return true;
00072 }
00073
00074 data_size = data_size - 1;
00075 _cached_data.resize( data_size );
00076
00077 for (size_t i=0; i < data_size; i++ )
00078 {
00079 const auto& p0 = _source_data->at( i );
00080 const auto& p1 = _source_data->at( i+1 );
00081 const auto delta = p1.x - p0.x;
00082 const auto vel = (p1.y - p0.y) /delta;
00083 QPointF p( (p1.x + p0.x)*0.5, vel);
00084 _cached_data[i] = { p.x(), p.y() };
00085 }
00086
00087 calculateBoundingBox();
00088 return true;
00089 }
00090
00091 bool Timeseries_2ndDerivative::updateCache()
00092 {
00093 size_t data_size = _source_data->size();
00094
00095 if( data_size <= 2)
00096 {
00097 _cached_data.clear();
00098 _bounding_box = QRectF();
00099 return true;
00100 }
00101
00102 data_size = data_size - 2;
00103 _cached_data.resize( data_size );
00104
00105 for (size_t i=0; i < data_size; i++ )
00106 {
00107 const auto& p0 = _source_data->at( i );
00108 const auto& p1 = _source_data->at( i+1 );
00109 const auto& p2 = _source_data->at( i+2 );
00110 const auto delta = (p2.x - p0.x) *0.5;
00111 const auto acc = ( p2.y - 2.0* p1.y + p0.y)/(delta*delta);
00112 QPointF p( (p2.x + p0.x)*0.5, acc );
00113 _cached_data[i] = { p.x(), p.y() };
00114 }
00115
00116 calculateBoundingBox();
00117 return true;
00118 }