From 6f0fb5430dd7c35418e55cc7092ed002321eb1a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Sat, 29 Oct 2022 21:19:30 +0200 Subject: [PATCH] Sweep indicator on graphs --- .../LibreVNA-GUI/Traces/tracemodel.cpp | 18 +- .../LibreVNA-GUI/Traces/tracemodel.h | 6 +- .../LibreVNA-GUI/Traces/traceplot.cpp | 12 + .../LibreVNA-GUI/Traces/traceplot.h | 1 + .../LibreVNA-GUI/Traces/tracepolarchart.cpp | 10 + .../LibreVNA-GUI/Traces/tracesmithchart.cpp | 10 + .../LibreVNA-GUI/Traces/tracewaterfall.cpp | 19 ++ .../LibreVNA-GUI/Traces/tracexyplot.cpp | 31 ++ .../LibreVNA-GUI/preferences.cpp | 12 + .../PC_Application/LibreVNA-GUI/preferences.h | 13 + .../LibreVNA-GUI/preferencesdialog.ui | 293 ++++++++++++++---- 11 files changed, 370 insertions(+), 55 deletions(-) diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.cpp index 63712f7..f648f40 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.cpp @@ -2,6 +2,7 @@ #include #include +#include using namespace std; @@ -234,6 +235,7 @@ void TraceModel::clearLiveData() void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::DataType datatype) { source = DataSource::VNA; + lastReceivedData = QDateTime::currentDateTimeUtc(); for(auto t : traces) { if (t->getSource() == Trace::Source::Live && !t->isPaused()) { int index = -1; @@ -246,13 +248,14 @@ void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::D td.x = d.dBm; break; case TraceMath::DataType::TimeZeroSpan: - td.x = d.us; + td.x = (double) d.us / 1000000.0; index = d.pointNum; break; default: // invalid type, can not add return; } + lastSweepPosition = td.x; if(d.measurements.count(t->liveParameter())) { td.y = d.measurements.at(t->liveParameter()); } else { @@ -267,6 +270,7 @@ void TraceModel::addVNAData(const VirtualDevice::VNAMeasurement& d, TraceMath::D void TraceModel::addSAData(const VirtualDevice::SAMeasurement& d, const VirtualDevice::SASettings &settings) { source = DataSource::SA; + lastReceivedData = QDateTime::currentDateTimeUtc(); for(auto t : traces) { if (t->getSource() == Trace::Source::Live && !t->isPaused()) { int index = -1; @@ -284,6 +288,7 @@ void TraceModel::addSAData(const VirtualDevice::SAMeasurement& d, const VirtualD // parameter not included in data, skip continue; } + lastSweepPosition = td.x; t->addData(td, settings, index); } } @@ -299,6 +304,17 @@ void TraceModel::setSource(const DataSource &value) source = value; } +double TraceModel::getSweepPosition() const +{ + auto t = QDateTime::currentDateTimeUtc(); + constexpr uint64_t timeout_ms = 1000; + if(lastReceivedData.msecsTo(t) > timeout_ms) { + return std::numeric_limits::quiet_NaN(); + } else { + return lastSweepPosition; + } +} + MarkerModel *TraceModel::getMarkerModel() const { return markerModel; diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.h b/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.h index b68d6d7..b93cc67 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.h +++ b/Software/PC_Application/LibreVNA-GUI/Traces/tracemodel.h @@ -1,4 +1,4 @@ -#ifndef TRACEMODEL_H +#ifndef TRACEMODEL_H #define TRACEMODEL_H #include "Device/device.h" @@ -57,6 +57,8 @@ public: DataSource getSource() const; void setSource(const DataSource &value); + double getSweepPosition() const; + signals: void SpanChanged(double fmin, double fmax); void traceAdded(Trace *t); @@ -71,6 +73,8 @@ public slots: private: DataSource source; + double lastSweepPosition; + QDateTime lastReceivedData; std::vector traces; MarkerModel *markerModel; }; diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp index 856c2d4..50890c5 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.cpp @@ -168,6 +168,18 @@ void TracePlot::paintEvent(QPaintEvent *event) traceRemovalPending = false; } + xSweep = std::numeric_limits::quiet_NaN(); + for(auto t : traces) { + if(!t.second) { + continue; + } + Trace* tr = t.first; + if(tr->getSource() == Trace::Source::Live && tr->isVisible() && !tr->isPaused()) { + xSweep = model.getSweepPosition(); + break; + } + } + Q_UNUSED(event) auto& pref = Preferences::getInstance(); QPainter p(this); diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.h b/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.h index b28606c..6ed5df3 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.h +++ b/Software/PC_Application/LibreVNA-GUI/Traces/traceplot.h @@ -110,6 +110,7 @@ protected: static constexpr unsigned int marginRight = 0; double sweep_fmin, sweep_fmax; + double xSweep; // current position in the sweep (NaN if no live traces are active on the plot) TraceModel &model; Marker *selectedMarker; bool movingGraph; diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/tracepolarchart.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/tracepolarchart.cpp index 18da04c..a0cb9aa 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/tracepolarchart.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/tracepolarchart.cpp @@ -185,6 +185,16 @@ void TracePolarChart::draw(QPainter &p) { break; } + if(pref.Graphs.SweepIndicator.hide && !isnan(xSweep) && trace->getSource() == Trace::Source::Live && trace->isVisible() && !trace->isPaused()) { + // check if this part of the trace is visible + double range = maximumVisibleFrequency - minimumVisibleFrequency; + double afterSweep = now.x - xSweep; + if(afterSweep > 0 && afterSweep * 100 / range <= pref.Graphs.SweepIndicator.hidePercent) { + // do not display this part of the trace + continue; + } + } + last = dataAddDx(last); now = dataAddDx(now); diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/tracesmithchart.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/tracesmithchart.cpp index 4182952..53f6908 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/tracesmithchart.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/tracesmithchart.cpp @@ -279,6 +279,16 @@ void TraceSmithChart::draw(QPainter &p) { break; } + if(pref.Graphs.SweepIndicator.hide && !isnan(xSweep) && trace->getSource() == Trace::Source::Live && trace->isVisible() && !trace->isPaused()) { + // check if this part of the trace is visible + double range = maximumVisibleFrequency - minimumVisibleFrequency; + double afterSweep = now.x - xSweep; + if(afterSweep > 0 && afterSweep * 100 / range <= pref.Graphs.SweepIndicator.hidePercent) { + // do not display this part of the trace + continue; + } + } + last = dataAddDx(last); now = dataAddDx(now); diff --git a/Software/PC_Application/LibreVNA-GUI/Traces/tracewaterfall.cpp b/Software/PC_Application/LibreVNA-GUI/Traces/tracewaterfall.cpp index 22922e8..b8e94c8 100644 --- a/Software/PC_Application/LibreVNA-GUI/Traces/tracewaterfall.cpp +++ b/Software/PC_Application/LibreVNA-GUI/Traces/tracewaterfall.cpp @@ -418,6 +418,25 @@ void TraceWaterfall::draw(QPainter &p) } p.setClipping(false); + // show sweep indicator if activated + if((xAxis.getType() == XAxis::Type::Frequency || xAxis.getType() == XAxis::Type::TimeZeroSpan || xAxis.getType() == XAxis::Type::Power) + && !isnan(xSweep)) { + if(xSweep >= xAxis.getRangeMin() && xSweep <= xAxis.getRangeMax()) { + auto xpos = xAxis.transform(xSweep, plotAreaLeft, plotAreaLeft + plotAreaWidth); + pen = QPen(pref.Graphs.Color.axis); + pen.setCosmetic(true); + p.setPen(pen); + if(pref.Graphs.SweepIndicator.line) { + p.drawLine(xpos, plotAreaTop, xpos, plotAreaBottom); + } + if(pref.Graphs.SweepIndicator.triangle) { + for(unsigned int i=0;igetSource() == Trace::Source::Live && t->isVisible() && !t->isPaused()) { + // check if this part of the trace is visible + double range = xAxis.getRangeMax() - xAxis.getRangeMin(); + double afterSweep = now.x() - xSweep; + if(afterSweep > 0 && afterSweep * 100 / range <= pref.Graphs.SweepIndicator.hidePercent) { + // do not display this part of the trace + continue; + } + } + // scale to plot coordinates auto p1 = plotValueToPixel(last, i); auto p2 = plotValueToPixel(now, i); @@ -750,6 +761,26 @@ void TraceXYPlot::draw(QPainter &p) } } + + // show sweep indicator if activated + if((xAxis.getType() == XAxis::Type::Frequency || xAxis.getType() == XAxis::Type::TimeZeroSpan || xAxis.getType() == XAxis::Type::Power) + && !isnan(xSweep)) { + if(xSweep >= xAxis.getRangeMin() && xSweep <= xAxis.getRangeMax()) { + auto xpos = plotValueToPixel(QPointF(xSweep, 1.0), 0); + pen = QPen(pref.Graphs.Color.axis); + pen.setCosmetic(true); + p.setPen(pen); + if(pref.Graphs.SweepIndicator.line) { + p.drawLine(xpos.x(), plotAreaTop, xpos.x(), plotAreaBottom); + } + if(pref.Graphs.SweepIndicator.triangle) { + for(unsigned int i=0;iGraphsZoomFactor->setPrecision(3); + ui->GraphsSweepHidePercent->setPrecision(3); + ui->GraphsSweepHidePercent->setUnit("%"); // General page if(p->TCPoverride) { @@ -327,6 +329,11 @@ void PreferencesDialog::setInitialGUIState() ui->GraphsFontSizeTraceNames->setValue(p->Graphs.fontSizeTraceNames); ui->GraphsEnablePanZoom->setChecked(p->Graphs.enablePanAndZoom); ui->GraphsZoomFactor->setValue(p->Graphs.zoomFactor); + ui->GraphsSweepTriangle->setChecked(p->Graphs.SweepIndicator.triangle); + ui->GraphsSweepTriangleSize->setValue(p->Graphs.SweepIndicator.triangleSize); + ui->GraphsSweepLine->setChecked(p->Graphs.SweepIndicator.line); + ui->GraphsSweepHide->setChecked(p->Graphs.SweepIndicator.hide); + ui->GraphsSweepHidePercent->setValue(p->Graphs.SweepIndicator.hidePercent); ui->MarkerShowMarkerData->setChecked(p->Marker.defaultBehavior.showDataOnGraphs); ui->MarkerShowAllMarkerData->setChecked(p->Marker.defaultBehavior.showAllData); @@ -404,6 +411,11 @@ void PreferencesDialog::updateFromGUI() p->Graphs.fontSizeTraceNames = ui->GraphsFontSizeTraceNames->value(); p->Graphs.enablePanAndZoom = ui->GraphsEnablePanZoom->isChecked(); p->Graphs.zoomFactor = ui->GraphsZoomFactor->value(); + p->Graphs.SweepIndicator.triangle = ui->GraphsSweepTriangle->isChecked(); + p->Graphs.SweepIndicator.triangleSize = ui->GraphsSweepTriangleSize->value(); + p->Graphs.SweepIndicator.line = ui->GraphsSweepLine->isChecked(); + p->Graphs.SweepIndicator.hide = ui->GraphsSweepHide->isChecked(); + p->Graphs.SweepIndicator.hidePercent = ui->GraphsSweepHidePercent->value(); p->Marker.defaultBehavior.showDataOnGraphs = ui->MarkerShowMarkerData->isChecked(); p->Marker.defaultBehavior.showAllData = ui->MarkerShowAllMarkerData->isChecked(); diff --git a/Software/PC_Application/LibreVNA-GUI/preferences.h b/Software/PC_Application/LibreVNA-GUI/preferences.h index 5739bb0..7f71fd0 100644 --- a/Software/PC_Application/LibreVNA-GUI/preferences.h +++ b/Software/PC_Application/LibreVNA-GUI/preferences.h @@ -137,6 +137,14 @@ public: bool enablePanAndZoom; double zoomFactor; + + struct { + bool triangle; + unsigned int triangleSize; + bool line; + bool hide; + double hidePercent; + } SweepIndicator; } Graphs; struct { struct { @@ -226,6 +234,11 @@ private: {&Graphs.fontSizeTraceNames, "Graphs.fontSizeTraceNames", 12}, {&Graphs.enablePanAndZoom, "Graphs.enablePanAndZoom", true}, {&Graphs.zoomFactor, "Graphs.zoomFactor", 0.9}, + {&Graphs.SweepIndicator.triangle, "Graphs.SweepIndicator.triangle", true}, + {&Graphs.SweepIndicator.triangleSize, "Graphs.SweepIndicator.triangleSize", 5}, + {&Graphs.SweepIndicator.line, "Graphs.SweepIndicator.line", false}, + {&Graphs.SweepIndicator.hide, "Graphs.SweepIndicator.hide", false}, + {&Graphs.SweepIndicator.hidePercent, "Graphs.SweepIndicator.hidePercent", 3.0}, {&Marker.defaultBehavior.showDataOnGraphs, "Marker.defaultBehavior.ShowDataOnGraphs", true}, {&Marker.defaultBehavior.showAllData, "Marker.defaultBehavior.ShowAllData", false}, {&Marker.interpolatePoints, "Marker.interpolatePoints", false}, diff --git a/Software/PC_Application/LibreVNA-GUI/preferencesdialog.ui b/Software/PC_Application/LibreVNA-GUI/preferencesdialog.ui index 1b52c5d..1881808 100644 --- a/Software/PC_Application/LibreVNA-GUI/preferencesdialog.ui +++ b/Software/PC_Application/LibreVNA-GUI/preferencesdialog.ui @@ -6,14 +6,14 @@ 0 0 - 909 - 657 + 989 + 632 Preferences - + @@ -74,39 +74,39 @@ - - - true + + + + 0 + 0 + - - - - 0 - -334 - 687 - 938 - - - + + + 16777215 + 16777215 + + + + 2 + + + - - - - 0 - 0 - + + + true - - - 16777215 - 16777215 - - - - 1 - - - + + + + 0 + 0 + 744 + 920 + + + @@ -138,9 +138,6 @@ Last used - - StartupSweepGroup - @@ -148,9 +145,6 @@ Default values - - StartupSweepGroup - @@ -158,9 +152,6 @@ Setup file - - StartupSweepGroup - @@ -700,8 +691,27 @@ - - + + + + + + + + + + true + + + + + 0 + 0 + 605 + 866 + + + @@ -1002,8 +1012,27 @@ - - + + + + + + + + + + true + + + + + 0 + -216 + 749 + 952 + + + @@ -1178,6 +1207,107 @@ + + + + Sweep Indicator + + + + + + + + Show triangle of size + + + + + + + + + + below X axis + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Show vertical line in graph + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Hide + + + + + + + + + + of displayed data after the sweep point + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + @@ -1301,8 +1431,27 @@ - - + + + + + + + + + + true + + + + + 0 + 0 + 644 + 544 + + + @@ -1425,8 +1574,27 @@ - - + + + + + + + + + + true + + + + + 0 + 0 + 644 + 544 + + + @@ -1488,7 +1656,7 @@ - 471 + 473 20 @@ -1496,8 +1664,27 @@ - - + + + + + + + + + + true + + + + + 0 + 0 + 644 + 544 + + +