#include <qwt_legend.h>
-class TimeDomainDisplayZoomer: public QwtPlotZoomer
+class TimePrecisionClass
{
public:
- TimeDomainDisplayZoomer(QwtPlotCanvas* canvas):QwtPlotZoomer(canvas)
+ TimePrecisionClass(const int timePrecision)
+ {
+ _timePrecision = timePrecision;
+ }
+
+ virtual ~TimePrecisionClass()
+ {
+ }
+
+ virtual unsigned int GetTimePrecision() const
+ {
+ return _timePrecision;
+ }
+
+ virtual void SetTimePrecision(const unsigned int newPrecision)
+ {
+ _timePrecision = newPrecision;
+ }
+protected:
+ unsigned int _timePrecision;
+};
+
+
+class TimeDomainDisplayZoomer: public QwtPlotZoomer, public TimePrecisionClass
+{
+public:
+ TimeDomainDisplayZoomer(QwtPlotCanvas* canvas, const unsigned int timePrecision)
+ : QwtPlotZoomer(canvas),TimePrecisionClass(timePrecision)
{
setTrackerMode(QwtPicker::AlwaysOn);
}
updateDisplay();
}
+ void SetUnitType(const std::string &type)
+ {
+ _unitType = type;
+ }
+
protected:
virtual QwtText trackerText( const QwtDoublePoint& p ) const
{
- QwtText t(QString("Sample %1, %2 V").arg(p.x(), 0, 'f', 0).arg(p.y(), 0, 'f', 4));
+ QwtText t(QString("%1 %2, %3 V").arg(p.x(), 0, 'f', GetTimePrecision()).
+ arg(_unitType.c_str()).
+ arg(p.y(), 0, 'f', 4));
return t;
}
+
+private:
+ std::string _unitType;
};
-TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent){
+TimeDomainDisplayPlot::TimeDomainDisplayPlot(QWidget* parent):QwtPlot(parent)
+{
timespec_reset(&_lastReplot);
resize(parent->width(), parent->height());
- _displayIntervalTime = (1.0/10.0); // 1/10 of a second between updates
-
_numPoints = 1024;
_realDataPoints = new double[_numPoints];
_imagDataPoints = new double[_numPoints];
_xAxisPoints = new double[_numPoints];
+ _zoomer = new TimeDomainDisplayZoomer(canvas(), 0);
+
// Disable polygon clipping
QwtPainter::setDeviceClipping(false);
canvas()->setPalette(palette);
setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
- setAxisScale(QwtPlot::xBottom, 0, _numPoints);
- setAxisTitle(QwtPlot::xBottom, "Sample Number");
+ set_xaxis(0, _numPoints);
+ setAxisTitle(QwtPlot::xBottom, "Time (sec)");
setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
set_yaxis(-2.0, 2.0);
memset(_imagDataPoints, 0x0, _numPoints*sizeof(double));
memset(_xAxisPoints, 0x0, _numPoints*sizeof(double));
+ _sampleRate = 1;
_resetXAxisPoints();
replot();
- _zoomer = new TimeDomainDisplayZoomer(canvas());
#if QT_VERSION < 0x040000
_zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
Qt::RightButton, Qt::ControlModifier);
legendDisplay->setItemMode(QwtLegend::CheckableItem);
insertLegend(legendDisplay);
- connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ), this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
+ connect(this, SIGNAL( legendChecked(QwtPlotItem *, bool ) ),
+ this, SLOT( LegendEntryChecked(QwtPlotItem *, bool ) ));
}
TimeDomainDisplayPlot::~TimeDomainDisplayPlot(){
TimeDomainDisplayPlot::set_yaxis(double min, double max)
{
setAxisScale(QwtPlot::yLeft, min, max);
+ _zoomer->setZoomBase();
}
-void TimeDomainDisplayPlot::replot(){
-
- const timespec startTime = get_highres_clock();
-
- QwtPlot::replot();
+void
+TimeDomainDisplayPlot::set_xaxis(double min, double max)
+{
+ setAxisScale(QwtPlot::xBottom, min, max);
+ _zoomer->setZoomBase();
+}
- double differenceTime = (diff_timespec(get_highres_clock(), startTime));
- differenceTime *= 99.0;
- // Require at least a 10% duty cycle
- if(differenceTime > (1.0/10.0)){
- _displayIntervalTime = differenceTime;
- }
+void TimeDomainDisplayPlot::replot()
+{
+ QwtPlot::replot();
}
-void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints, const double* imagDataPoints, const int64_t numDataPoints){
- if(numDataPoints > 0){
+void
+TimeDomainDisplayPlot::resizeSlot( QSize *s )
+{
+ resize(s->width(), s->height());
+}
+void TimeDomainDisplayPlot::PlotNewData(const double* realDataPoints,
+ const double* imagDataPoints,
+ const int64_t numDataPoints,
+ const double timeInterval)
+{
+ if((numDataPoints > 0) &&
+ (diff_timespec(get_highres_clock(), _lastReplot) > timeInterval)) {
+
if(numDataPoints != _numPoints){
_numPoints = numDataPoints;
_real_plot_curve->setRawData(_xAxisPoints, _realDataPoints, _numPoints);
_imag_plot_curve->setRawData(_xAxisPoints, _imagDataPoints, _numPoints);
+ set_xaxis(0, numDataPoints);
+
_resetXAxisPoints();
}
+
memcpy(_realDataPoints, realDataPoints, numDataPoints*sizeof(double));
memcpy(_imagDataPoints, imagDataPoints, numDataPoints*sizeof(double));
- }
+ replot();
- // Allow at least a 50% duty cycle
- if(diff_timespec(get_highres_clock(), _lastReplot) > _displayIntervalTime){
- // Only replot the screen if it is visible
- if(isVisible()){
- replot();
- }
_lastReplot = get_highres_clock();
}
}
-void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag){
+void TimeDomainDisplayPlot::SetImaginaryDataVisible(const bool visibleFlag)
+{
_imag_plot_curve->setVisible(visibleFlag);
}
-void TimeDomainDisplayPlot::_resetXAxisPoints(){
+void TimeDomainDisplayPlot::_resetXAxisPoints()
+{
+ double delt = 1.0/_sampleRate;
for(long loc = 0; loc < _numPoints; loc++){
- _xAxisPoints[loc] = loc;
+ _xAxisPoints[loc] = loc*delt;
}
- setAxisScale(QwtPlot::xBottom, 0, _numPoints);
+ setAxisScale(QwtPlot::xBottom, 0, _numPoints*delt);
+
+ // Set up zoomer base for maximum unzoom x-axis
+ // and reset to maximum unzoom level
+ QwtDoubleRect zbase = _zoomer->zoomBase();
+ zbase.setLeft(0);
+ zbase.setRight(_numPoints*delt);
+ _zoomer->zoom(zbase);
+ _zoomer->setZoomBase(zbase);
+ _zoomer->zoom(0);
}
-void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on){
+void TimeDomainDisplayPlot::LegendEntryChecked(QwtPlotItem* plotItem, bool on)
+{
plotItem->setVisible(!on);
}
+void
+TimeDomainDisplayPlot::SetSampleRate(double sr, double units,
+ const std::string &strunits)
+{
+ double newsr = sr/units;
+ if(newsr != _sampleRate) {
+ _sampleRate = sr/units;
+ _resetXAxisPoints();
+
+ // While we could change the displayed sigfigs based on the unit being
+ // displayed, I think it looks better by just setting it to 4 regardless.
+ //double display_units = ceil(log10(units)/2.0);
+ double display_units = 4;
+ setAxisTitle(QwtPlot::xBottom, QString("Time (%1)").arg(strunits.c_str()));
+ ((TimeDomainDisplayZoomer*)_zoomer)->SetTimePrecision(display_units);
+ ((TimeDomainDisplayZoomer*)_zoomer)->SetUnitType(strunits);
+ }
+}
+
#endif /* TIME_DOMAIN_DISPLAY_PLOT_C */