#ifndef WATERFALL_3D_DISPLAY_PLOT_HPP #define WATERFALL_3D_DISPLAY_PLOT_HPP #include <cstdio> #include <highResTimeFunctions.h> #include <waterfallGlobalData.h> #include <qwt3d_surfaceplot.h> #include <qwt3d_color.h> #include <qwt_color_map.h> class Waterfall3DColorMap: public Qwt3D::Color, public QwtLinearColorMap { public: Waterfall3DColorMap(); virtual ~Waterfall3DColorMap(); virtual Qwt3D::RGBA operator()(double x, double y, double z)const; virtual Qwt3D::ColorVector& createVector(Qwt3D::ColorVector& vec); virtual void SetInterval(const double minValue, const double maxValue); protected: private: QwtDoubleInterval _interval; }; class Waterfall3DDisplayPlot:public Qwt3D::SurfacePlot{ Q_OBJECT protected: class IntensityScale:public Qwt3D::LinearScale{ friend class Qwt3D::Axis; friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>; private: double _floor; public: explicit IntensityScale(const double newFloor):_floor(newFloor){ } virtual ~IntensityScale(){} virtual QString ticLabel(unsigned int idx) const{ if (idx<majors_p.size()) { return QString("%1").arg( majors_p[idx] + GetFloorValue(), 0, 'f', 0 ); } return QString(""); } virtual double GetFloorValue()const{ return _floor; } virtual void SetFloorValue(const double newFloor){ _floor = newFloor; } //! Returns a new heap based object utilized from qwt3d_ptr Scale* clone() const {return new IntensityScale(*this);} }; class TimeScale:public Qwt3D::LinearScale{ friend class Qwt3D::Axis; friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>; friend class Waterfall3DDisplayPlot; private: Waterfall3DDisplayPlot* _plot; public: TimeScale(Waterfall3DDisplayPlot* plot ):_plot(plot){ } virtual ~TimeScale(){ } virtual QString ticLabel(unsigned int idx) const{ if (idx<majors_p.size()) { const timespec markerTime = timespec_add(_plot->_dataTimestamp, -(_plot->_timePerFFT) * majors_p[idx]); struct tm timeTm; gmtime_r(&markerTime.tv_sec, &timeTm); char* timeBuffer = new char[128]; snprintf(timeBuffer, 128, "%02d:%02d:%02d.%03ld", timeTm.tm_hour, timeTm.tm_min, timeTm.tm_sec, (markerTime.tv_nsec / 1000000)); QString returnBuffer(timeBuffer); delete[] timeBuffer; return returnBuffer; } return QString(""); } //! Returns a new heap based object utilized from qwt3d_ptr Scale* clone() const {return new TimeScale(*this);} }; class FrequencyScale: public Qwt3D::LinearScale{ friend class Qwt3D::Axis; friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>; private: double _centerFrequency; bool _useCenterFrequencyFlag; public: FrequencyScale(bool useCenterFrequencyFlag, double centerFrequency) : _centerFrequency(centerFrequency),_useCenterFrequencyFlag(useCenterFrequencyFlag) {} virtual ~FrequencyScale(){} virtual QString ticLabel(unsigned int idx) const { if (idx<majors_p.size()) { if(!_useCenterFrequencyFlag){ return QString("%1").arg( majors_p[idx], 0, 'f', 0 ); } else{ return QString("%1").arg( (majors_p[idx] + _centerFrequency)/1000.0, 0, 'f', 3 ); } } return QString(""); } //! Returns a new heap based object utilized from qwt3d_ptr Scale* clone() const {return new FrequencyScale(*this);} }; public: Waterfall3DDisplayPlot(QWidget*); virtual ~Waterfall3DDisplayPlot(); void Init(); void Reset(); bool loadFromData(double** data, unsigned int columns, unsigned int rows ,double minx, double maxx, double miny, double maxy); void SetFrequencyRange(const double, const double, const double, const bool, const double units, const std::string &strunits); double GetStartFrequency()const; double GetStopFrequency()const; void PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double timePerFFT, const timespec timestamp, const int droppedFrames); void SetIntensityRange(const double minIntensity, const double maxIntensity); virtual void replot(void); int GetIntensityColorMapType()const; void SetIntensityColorMapType( const int, const QColor, const QColor, const bool forceFlag = false, const bool noReplotFlag = false ); const QColor GetUserDefinedLowIntensityColor()const; const QColor GetUserDefinedHighIntensityColor()const; static const int INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR = 0; static const int INTENSITY_COLOR_MAP_TYPE_WHITE_HOT = 1; static const int INTENSITY_COLOR_MAP_TYPE_BLACK_HOT = 2; static const int INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3; static const int INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4; public slots: void resizeSlot( QSize *s ); signals: void UpdatedLowerIntensityLevel(const double); void UpdatedUpperIntensityLevel(const double); protected: double _startFrequency; double _stopFrequency; Waterfall3DData* _waterfallData; timespec _lastReplot; int64_t _numPoints; double _displayIntervalTime; int _intensityColorMapType; QColor _userDefinedLowIntensityColor; QColor _userDefinedHighIntensityColor; bool _useCenterFrequencyFlag; double _centerFrequency; timespec _dataTimestamp; double _timePerFFT; bool _initialized; bool _createCoordinateSystemFlag; private: }; #endif /* WATERFALL_3D_DISPLAY_PLOT_HPP */