00001 #ifndef SERIES_DATA_H 00002 #define SERIES_DATA_H 00003 00004 #include "PlotJuggler/plotdata.h" 00005 #include "qwt_series_data.h" 00006 00007 class DataSeriesBase: public QwtSeriesData<QPointF> 00008 { 00009 00010 public: 00011 DataSeriesBase(const PlotData* transformed): 00012 _transformed_data(transformed), 00013 _time_offset(0) 00014 {} 00015 00016 virtual QPointF sample( size_t i ) const override 00017 { 00018 const auto& p = _transformed_data->at(i); 00019 return QPointF(p.x - _time_offset, p.y); 00020 } 00021 00022 virtual size_t size() const override 00023 { 00024 return _transformed_data->size(); 00025 } 00026 00027 QRectF boundingRect() const override 00028 { 00029 QRectF box = _bounding_box; 00030 box.setLeft( _bounding_box.left() - _time_offset ); 00031 box.setRight( _bounding_box.right() - _time_offset ); 00032 return box; 00033 } 00034 00035 void setTimeOffset(double offset) 00036 { 00037 _time_offset = offset; 00038 } 00039 00040 00041 void calculateBoundingBox(); 00042 00043 virtual PlotData::RangeValueOpt getVisualizationRangeY(PlotData::RangeTime range_X) = 0; 00044 00045 virtual nonstd::optional<QPointF> sampleFromTime(double t) = 0; 00046 00047 virtual bool updateCache() = 0; 00048 00049 virtual PlotData::RangeTimeOpt getVisualizationRangeX() 00050 { 00051 if( this->size() < 2 ) 00052 return PlotData::RangeTimeOpt(); 00053 else{ 00054 return PlotData::RangeTimeOpt( { _bounding_box.left() - _time_offset, 00055 _bounding_box.right() - _time_offset } ); 00056 } 00057 } 00058 00059 const PlotData* transformedData() const { return _transformed_data; } 00060 00061 protected: 00062 QRectF _bounding_box; 00063 00064 private: 00065 const PlotData* _transformed_data; 00066 double _time_offset; 00067 }; 00068 00069 //-------------------------------------------- 00070 inline void DataSeriesBase::calculateBoundingBox() 00071 { 00072 if( _transformed_data->size() == 0) 00073 { 00074 _bounding_box = QRectF(); 00075 return; 00076 } 00077 00078 double min_y = _transformed_data->front().y; 00079 double max_y = _transformed_data->front().y; 00080 00081 for (const auto& p: *_transformed_data ) 00082 { 00083 if( p.y < min_y ) 00084 { 00085 min_y = p.y; 00086 } 00087 else if( p.y > max_y ) 00088 { 00089 max_y = p.y; 00090 } 00091 } 00092 00093 _bounding_box.setLeft( _transformed_data->front().x ); 00094 _bounding_box.setRight( _transformed_data->back().x ); 00095 _bounding_box.setBottom( min_y ); 00096 _bounding_box.setTop( max_y ); 00097 } 00098 00099 #endif // SERIES_DATA_H 00100 00101