diff options
author | Tom Rondeau <tom@trondeau.com> | 2013-10-29 12:04:50 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2013-10-29 12:10:59 -0400 |
commit | f6e454229964420766b3ae751bd632ec20c62bf9 (patch) | |
tree | 8d4b382c0746a2d5b7850549cabcc4c3d422cb70 /gr-qtgui/lib/TimeDomainDisplayPlot.cc | |
parent | dabe6f1187adc3e2953d14a8d0a1b4ad66044c47 (diff) |
qtgui: time sink plots (complex and float) display tags on the sample they were received on. Displayed as "key: value".
Conflicts:
gr-qtgui/examples/CMakeLists.txt
Diffstat (limited to 'gr-qtgui/lib/TimeDomainDisplayPlot.cc')
-rw-r--r-- | gr-qtgui/lib/TimeDomainDisplayPlot.cc | 135 |
1 files changed, 134 insertions, 1 deletions
diff --git a/gr-qtgui/lib/TimeDomainDisplayPlot.cc b/gr-qtgui/lib/TimeDomainDisplayPlot.cc index a7e6a821bc..55e62d2b2d 100644 --- a/gr-qtgui/lib/TimeDomainDisplayPlot.cc +++ b/gr-qtgui/lib/TimeDomainDisplayPlot.cc @@ -174,6 +174,9 @@ TimeDomainDisplayPlot::TimeDomainDisplayPlot(int nplots, QWidget* parent) _sampleRate = 1; _resetXAxisPoints(); + + d_tag_markers.resize(_nplots); + d_tag_markers_en = std::vector<bool>(_nplots, true); } TimeDomainDisplayPlot::~TimeDomainDisplayPlot() @@ -194,7 +197,8 @@ TimeDomainDisplayPlot::replot() void TimeDomainDisplayPlot::plotNewData(const std::vector<double*> dataPoints, const int64_t numDataPoints, - const double timeInterval) + const double timeInterval, + const std::vector< std::vector<gr::tag_t> > &tags) { if(!_stop) { if((numDataPoints > 0)) { @@ -228,6 +232,109 @@ TimeDomainDisplayPlot::plotNewData(const std::vector<double*> dataPoints, } } + // Detach and delete any tags that were plotted last time + for(int n = 0; n < _nplots; n++) { + for(size_t i = 0; i < d_tag_markers[n].size(); i++) { + d_tag_markers[n][i]->detach(); + delete d_tag_markers[n][i]; + } + d_tag_markers[n].clear(); + } + + // Plot and attach any new tags found. + // First test if this was a complex input where real/imag get + // split here into two stream. + bool cmplx = false; + int mult = (int)_nplots / (int)tags.size(); + if(mult == 2) + cmplx = true; + + std::vector< std::vector<gr::tag_t> >::const_iterator tag = tags.begin(); + for(int i = 0; i < _nplots; i+=mult) { + std::vector<gr::tag_t>::const_iterator t; + for(t = tag->begin(); t != tag->end(); t++) { + uint64_t offset = (*t).offset; + double sample_offset = double(offset)/_sampleRate; + + std::stringstream s; + s << (*t).key << ": " << (*t).value; + + // Select the right input stream to put the tag on. If real, + // just use i; if it's a complex stream, find the max of the + // real and imaginary parts and put the tag on that one. + int which = i; + if(cmplx) { + if(fabs(_dataPoints[i][offset]) < fabs(_dataPoints[i+1][offset])) + which = i+1; + } + + double yval = _dataPoints[which][offset]; + + // Find if we already have a marker at this location + std::vector<QwtPlotMarker*>::iterator mitr; + for(mitr = d_tag_markers[which].begin(); mitr != d_tag_markers[which].end(); mitr++) { + if((*mitr)->xValue() == sample_offset) { + break; + } + } + + // If no matching marker, create a new one + if(mitr == d_tag_markers[which].end()) { + bool show = _plot_curve[which]->isVisible(); + + QwtPlotMarker *m = new QwtPlotMarker(); + m->setXValue(sample_offset); + m->setYValue(yval); + + QBrush brush; + brush.setColor(QColor(0xC8, 0x2F, 0x1F)); + brush.setStyle(Qt::SolidPattern); + + QPen pen; + pen.setColor(Qt::black); + pen.setWidth(1); + + QwtSymbol *sym = new QwtSymbol(QwtSymbol::NoSymbol, brush, pen, QSize(12,12)); + + if(yval >= 0) { + sym->setStyle(QwtSymbol::DTriangle); + m->setLabelAlignment(Qt::AlignTop); + } + else { + sym->setStyle(QwtSymbol::UTriangle); + m->setLabelAlignment(Qt::AlignBottom); + } + +#if QWT_VERSION < 0x060000 + m->setSymbol(*sym); +#else + m->setSymbol(sym); +#endif + + m->setLabel(QwtText(s.str().c_str())); + m->attach(this); + + if(!(show && d_tag_markers_en[which])) { + m->hide(); + } + + d_tag_markers[which].push_back(m); + } + else { + // Prepend the new tag to the existing marker + // And set it at the max value + if(fabs(yval) < fabs((*mitr)->yValue())) + (*mitr)->setYValue(yval); + QString orig = (*mitr)->label().text(); + s << std::endl; + orig.prepend(s.str().c_str()); + (*mitr)->setLabel(orig); + } + } + + tag++; + } + if(_autoscale_state) { double bottom=1e20, top=-1e20; for(int n = 0; n < _nplots; n++) { @@ -249,6 +356,23 @@ TimeDomainDisplayPlot::plotNewData(const std::vector<double*> dataPoints, } void +TimeDomainDisplayPlot::legendEntryChecked(QwtPlotItem* plotItem, bool on) +{ + // When line is turned on/off, immediately show/hide tag markers + for(int n = 0; n < _nplots; n++) { + if(plotItem == _plot_curve[n]) { + for(size_t i = 0; i < d_tag_markers[n].size(); i++) { + if(!(!on && d_tag_markers_en[n])) + d_tag_markers[n][i]->hide(); + else + d_tag_markers[n][i]->show(); + } + } + } + DisplayPlot::legendEntryChecked(plotItem, on); +} + +void TimeDomainDisplayPlot::_resetXAxisPoints() { double delt = 1.0/_sampleRate; @@ -367,4 +491,13 @@ TimeDomainDisplayPlot::setSemilogy(bool en) } } +void +TimeDomainDisplayPlot::enableTagMarker(int which, bool en) +{ + if((size_t)which < d_tag_markers_en.size()) + d_tag_markers_en[which] = en; + else + throw std::runtime_error("TimeDomainDisplayPlot: enabled tag marker does not exist.\n"); +} + #endif /* TIME_DOMAIN_DISPLAY_PLOT_C */ |