1 #ifndef TIME_DOMAIN_DISPLAY_PLOT_C
2 #define TIME_DOMAIN_DISPLAY_PLOT_C
4 #include <TimeDomainDisplayPlot.h>
6 #include <qwt_scale_draw.h>
7 #include <qwt_legend.h>
10 class TimePrecisionClass
13 TimePrecisionClass(const int timePrecision)
15 _timePrecision = timePrecision;
18 virtual ~TimePrecisionClass()
22 virtual unsigned int GetTimePrecision() const
24 return _timePrecision;
27 virtual void SetTimePrecision(const unsigned int newPrecision)
29 _timePrecision = newPrecision;
32 unsigned int _timePrecision;
36 class TimeDomainDisplayZoomer: public QwtPlotZoomer, public TimePrecisionClass
39 TimeDomainDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int timePrecision)
40 : QwtPlotZoomer(canvas),TimePrecisionClass(timePrecision)
42 setTrackerMode(QwtPicker::AlwaysOn);
45 virtual ~TimeDomainDisplayZoomer(){
49 virtual void updateTrackerText(){
53 void SetUnitType(const std::string &type)
59 using QwtPlotZoomer::trackerText;
60 virtual QwtText trackerText( const QwtDoublePoint& p ) const
62 QwtText t(QString("%1 %2, %3 V").arg(p.x(), 0, 'f', GetTimePrecision()).
63 arg(_unitType.c_str()).
64 arg(p.y(), 0, 'f', 4));
70 std::string _unitType;
73 TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent)
75 timespec_reset(&_lastReplot);
77 resize(parent->width(), parent->height());
80 _realDataPoints = new double[_numPoints];
81 _imagDataPoints = new double[_numPoints];
82 _xAxisPoints = new double[_numPoints];
84 _zoomer = new TimeDomainDisplayZoomer(canvas(), 0);
86 // Disable polygon clipping
87 QwtPainter::setDeviceClipping(false);
89 // We don't need the cache here
90 canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
91 canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
94 palette.setColor(canvas()->backgroundRole(), QColor("white"));
95 canvas()->setPalette(palette);
97 setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
98 set_xaxis(0, _numPoints);
99 setAxisTitle(QwtPlot::xBottom, "Time (sec)");
101 setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
102 set_yaxis(-2.0, 2.0);
103 setAxisTitle(QwtPlot::yLeft, "Normalized Voltage");
105 // Automatically deleted when parent is deleted
106 _real_plot_curve = new QwtPlotCurve("Real Data");
107 _real_plot_curve->attach(this);
108 _real_plot_curve->setPen(QPen(Qt::blue));
109 _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
111 _imag_plot_curve = new QwtPlotCurve("Imaginary Data");
112 _imag_plot_curve->attach(this);
113 _imag_plot_curve->setPen(QPen(Qt::magenta));
114 _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
115 // _imag_plot_curve->setVisible(false);
117 memset(_realDataPoints, 0x0, _numPoints*sizeof(double));
118 memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
119 memset(_xAxisPoints, 0x0, _numPoints*sizeof(double));
126 #if QT_VERSION < 0x040000
127 _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
128 Qt::RightButton, Qt::ControlModifier);
130 _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
131 Qt::RightButton, Qt::ControlModifier);
133 _zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
136 _panner = new QwtPlotPanner(canvas());
137 _panner->setAxisEnabled(QwtPlot::yRight, false);
138 _panner->setMouseButton(Qt::MidButton);
140 // Avoid jumping when labels with more/less digits
141 // appear/disappear when scrolling vertically
143 const QFontMetrics fm(axisWidget(QwtPlot::yLeft)->font());
144 QwtScaleDraw *sd = axisScaleDraw(QwtPlot::yLeft);
145 sd->setMinimumExtent( fm.width("100.00") );
147 const QColor c(Qt::darkRed);
148 _zoomer->setRubberBandPen(c);
149 _zoomer->setTrackerPen(c);
151 QwtLegend* legendDisplay = new QwtLegend(this);
152 legendDisplay->setItemMode(QwtLegend::CheckableItem);
153 insertLegend(legendDisplay);
155 connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ),
156 this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
159 TimeDomainDisplayPlot::~TimeDomainDisplayPlot(){
160 delete[] _realDataPoints;
161 delete[] _imagDataPoints;
162 delete[] _xAxisPoints;
164 // _fft_plot_curves deleted when parent deleted
165 // _zoomer and _panner deleted when parent deleted
169 TimeDomainDisplayPlot::set_yaxis(double min, double max)
171 setAxisScale(QwtPlot::yLeft, min, max);
172 _zoomer->setZoomBase();
176 TimeDomainDisplayPlot::set_xaxis(double min, double max)
178 setAxisScale(QwtPlot::xBottom, min, max);
179 _zoomer->setZoomBase();
183 void TimeDomainDisplayPlot::replot()
189 TimeDomainDisplayPlot::resizeSlot( QSize *s )
191 resize(s->width(), s->height());
194 void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints,
195 const double* imagDataPoints,
196 const int64_t numDataPoints,
197 const double timeInterval)
199 if((numDataPoints > 0) &&
200 (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
202 if(numDataPoints != _numPoints){
203 _numPoints = numDataPoints;
205 delete[] _realDataPoints;
206 delete[] _imagDataPoints;
207 delete[] _xAxisPoints;
208 _realDataPoints = new double[_numPoints];
209 _imagDataPoints = new double[_numPoints];
210 _xAxisPoints = new double[_numPoints];
212 _real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
213 _imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
215 set_xaxis(0, numDataPoints);
220 memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
221 memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
225 _lastReplot = get_highres_clock();
229 void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag)
231 _imag_plot_curve->setVisible(visibleFlag);
234 void TimeDomainDisplayPlot::_resetXAxisPoints()
236 double delt = 1.0/_sampleRate;
237 for(long loc = 0; loc < _numPoints; loc++){
238 _xAxisPoints[loc] = loc*delt;
240 setAxisScale(QwtPlot::xBottom, 0, _numPoints*delt);
242 // Set up zoomer base for maximum unzoom x-axis
243 // and reset to maximum unzoom level
244 QwtDoubleRect zbase = _zoomer->zoomBase();
246 zbase.setRight(_numPoints*delt);
247 _zoomer->zoom(zbase);
248 _zoomer->setZoomBase(zbase);
252 void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on)
254 plotItem->setVisible(!on);
258 TimeDomainDisplayPlot::SetSampleRate(double sr, double units,
259 const std::string &strunits)
261 double newsr = sr/units;
262 if(newsr != _sampleRate) {
263 _sampleRate = sr/units;
266 // While we could change the displayed sigfigs based on the unit being
267 // displayed, I think it looks better by just setting it to 4 regardless.
268 //double display_units = ceil(log10(units)/2.0);
269 double display_units = 4;
270 setAxisTitle(QwtPlot::xBottom, QString("Time (%1)").arg(strunits.c_str()));
271 ((TimeDomainDisplayZoomer*)_zoomer)->SetTimePrecision(display_units);
272 ((TimeDomainDisplayZoomer*)_zoomer)->SetUnitType(strunits);
276 #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */