From 32270dc747299d47fe98e8059e1cd3aeacf9fe56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20K=C3=A4berich?= Date: Sun, 1 Nov 2020 22:56:31 +0100 Subject: [PATCH] Autoscale improvements --- .../CustomWidgets/tilewidget.cpp | 4 +- .../PC_Application/Traces/markerwidget.cpp | 1 + Software/PC_Application/Traces/trace.cpp | 19 +- Software/PC_Application/Traces/trace.h | 1 + Software/PC_Application/Traces/tracemodel.cpp | 3 + Software/PC_Application/Traces/tracemodel.h | 1 + Software/PC_Application/Traces/traceplot.cpp | 2 +- Software/PC_Application/Traces/traceplot.h | 2 +- .../PC_Application/Traces/tracexyplot.cpp | 129 ++- Software/PC_Application/Traces/tracexyplot.h | 36 +- .../Traces/xyplotaxisdialog.cpp | 53 +- .../PC_Application/Traces/xyplotaxisdialog.ui | 902 +++++++++--------- 12 files changed, 640 insertions(+), 513 deletions(-) diff --git a/Software/PC_Application/CustomWidgets/tilewidget.cpp b/Software/PC_Application/CustomWidgets/tilewidget.cpp index 38ff1fa..0f1dc12 100644 --- a/Software/PC_Application/CustomWidgets/tilewidget.cpp +++ b/Software/PC_Application/CustomWidgets/tilewidget.cpp @@ -130,7 +130,9 @@ void TileWidget::on_bSmithchart_clicked() void TileWidget::on_bXYplot_clicked() { - setContent(new TraceXYPlot(model)); + auto plot = new TraceXYPlot(model); + setContent(plot); + plot->axisSetupDialog(); } void TileWidget::traceDeleted(TracePlot *) diff --git a/Software/PC_Application/Traces/markerwidget.cpp b/Software/PC_Application/Traces/markerwidget.cpp index 5ae7d63..2731b95 100644 --- a/Software/PC_Application/Traces/markerwidget.cpp +++ b/Software/PC_Application/Traces/markerwidget.cpp @@ -18,6 +18,7 @@ MarkerWidget::MarkerWidget(TraceMarkerModel &model, QWidget *parent) : connect(&model.getModel(), &TraceModel::traceAdded, this, &MarkerWidget::updatePersistentEditors); connect(&model.getModel(), &TraceModel::traceRemoved, this, &MarkerWidget::updatePersistentEditors); + connect(&model.getModel(), &TraceModel::traceNameChanged, this, &MarkerWidget::updatePersistentEditors); } MarkerWidget::~MarkerWidget() diff --git a/Software/PC_Application/Traces/trace.cpp b/Software/PC_Application/Traces/trace.cpp index 0eccc99..9e3d4fc 100644 --- a/Software/PC_Application/Traces/trace.cpp +++ b/Software/PC_Application/Traces/trace.cpp @@ -156,16 +156,22 @@ void Trace::updateTimeDomainData() // system_clock::now().time_since_epoch() // ).count(); auto steps = size(); - if(minFreq() * size() != maxFreq()) { + auto firstStep = minFreq(); + if(firstStep == 0) { + // zero as first step would result in infinite number of points, skip and start with second + firstStep = _data[1].frequency; + steps--; + } + if(firstStep * steps != maxFreq()) { // data is not available with correct frequency spacing, calculate required steps - steps = maxFreq() / minFreq(); + steps = maxFreq() / firstStep; } const double PI = 3.141592653589793238463; // reserve vector for negative frequenies and DC as well vector> frequencyDomain(2*steps + 1); // copy frequencies, use the flipped conjugate for negative part for(unsigned int i = 1;i<=steps;i++) { - auto S = getData(minFreq() * i); + auto S = getData(firstStep * i); constexpr double alpha0 = 0.54; auto hamming = alpha0 - (1.0 - alpha0) * -cos(PI * i / steps); S *= hamming; @@ -180,13 +186,18 @@ void Trace::updateTimeDomainData() auto fft_bins = frequencyDomain.size(); timeDomain.clear(); timeDomain.resize(fft_bins); - const double fs = 1.0 / (minFreq() * fft_bins); + const double fs = 1.0 / (firstStep * fft_bins); double last_step = 0.0; Fft::transform(frequencyDomain, true); + constexpr double c = 299792458; for(unsigned int i = 0;i= MinUpdateInterval) { - replot(); lastUpdate = now; + replot(); } } diff --git a/Software/PC_Application/Traces/traceplot.h b/Software/PC_Application/Traces/traceplot.h index 856f82e..e4fd274 100644 --- a/Software/PC_Application/Traces/traceplot.h +++ b/Software/PC_Application/Traces/traceplot.h @@ -16,7 +16,7 @@ public: virtual void enableTrace(Trace *t, bool enabled); void mouseDoubleClickEvent(QMouseEvent *event) override; - virtual void setXAxis(double min, double max){Q_UNUSED(min);Q_UNUSED(max)}; + virtual void updateSpan(double min, double max){Q_UNUSED(min);Q_UNUSED(max)}; static std::set getPlots(); diff --git a/Software/PC_Application/Traces/tracexyplot.cpp b/Software/PC_Application/Traces/tracexyplot.cpp index 9a8122c..f5aa5f2 100644 --- a/Software/PC_Application/Traces/tracexyplot.cpp +++ b/Software/PC_Application/Traces/tracexyplot.cpp @@ -91,8 +91,11 @@ public: case TraceXYPlot::YAxisType::Impedance: { auto sample = t.getTDR()[i]; QPointF p; - // TODO set distance - p.setX(sample.time); + if(Xtype == TraceXYPlot::XAxisType::Time) { + p.setX(sample.time); + } else { + p.setX(sample.distance); + } p.setY(TimeAxisTransformation(Ytype, &t, i)); return p; } @@ -116,23 +119,23 @@ TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent) selectedMarker(nullptr) { YAxis[0].log = false; - YAxis[0].Ytype = YAxisType::Disabled; + YAxis[0].type = YAxisType::Disabled; YAxis[0].rangeDiv = 1; YAxis[0].rangeMax = 10; YAxis[0].rangeMin = 0; YAxis[0].autorange = false; YAxis[1].log = false; - YAxis[1].Ytype = YAxisType::Disabled; + YAxis[1].type = YAxisType::Disabled; YAxis[1].rangeDiv = 1; YAxis[1].rangeMax = 10; YAxis[1].rangeMin = 0; YAxis[1].autorange = false; - XAxis.Xtype = XAxisType::Frequency; + XAxis.type = XAxisType::Frequency; XAxis.log = false; XAxis.rangeDiv = 1; XAxis.rangeMax = 10; XAxis.rangeMin = 0; - XAxis.autorange = true; + XAxis.mode = XAxisMode::UseSpan; plot = new QwtPlot(this); @@ -168,10 +171,10 @@ TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent) setYAxis(0, YAxisType::Magnitude, false, false, -120, 20, 10); setYAxis(1, YAxisType::Phase, false, false, -180, 180, 30); // enable autoscaling and set for full span (no information about actual span available yet) - setXAxis(0, 6000000000); - setXAxis(XAxisType::Frequency, true, 0, 6000000000, 600000000); + updateSpan(0, 6000000000); + setXAxis(XAxisType::Frequency, XAxisMode::UseSpan, 0, 6000000000, 600000000); // get notified when the span changes - connect(&model, &TraceModel::SpanChanged, this, qOverload(&TraceXYPlot::setXAxis)); + connect(&model, &TraceModel::SpanChanged, this, qOverload(&TraceXYPlot::updateSpan)); allPlots.insert(this); } @@ -187,16 +190,15 @@ TraceXYPlot::~TraceXYPlot() allPlots.erase(this); } -void TraceXYPlot::setXAxis(double min, double max) +void TraceXYPlot::updateSpan(double min, double max) { sweep_fmin = min; sweep_fmax = max; - updateXAxis(); } void TraceXYPlot::setYAxis(int axis, TraceXYPlot::YAxisType type, bool log, bool autorange, double min, double max, double div) { - if(YAxis[axis].Ytype != type) { + if(YAxis[axis].type != type) { // remove traces that are active but not supported with the new axis type bool erased = false; do { @@ -210,12 +212,12 @@ void TraceXYPlot::setYAxis(int axis, TraceXYPlot::YAxisType type, bool log, bool } } while(erased); - if(isTDRtype(YAxis[axis].Ytype)) { + if(isTDRtype(YAxis[axis].type)) { for(auto t : tracesAxis[axis]) { t->removeTDRinterest(); } } - YAxis[axis].Ytype = type; + YAxis[axis].type = type; for(auto t : tracesAxis[axis]) { // supported but needs an adjusted QwtSeriesData @@ -252,20 +254,19 @@ void TraceXYPlot::setYAxis(int axis, TraceXYPlot::YAxisType type, bool log, bool replot(); } -void TraceXYPlot::setXAxis(XAxisType type, bool autorange, double min, double max, double div) +void TraceXYPlot::setXAxis(XAxisType type, XAxisMode mode, double min, double max, double div) { - XAxis.Xtype = type; - XAxis.autorange = autorange; + XAxis.type = type; + XAxis.mode = mode; XAxis.rangeMin = min; XAxis.rangeMax = max; XAxis.rangeDiv = div; - updateXAxis(); } void TraceXYPlot::enableTrace(Trace *t, bool enabled) { for(int axis = 0;axis < 2;axis++) { - if(supported(t, YAxis[axis].Ytype)) { + if(supported(t, YAxis[axis].type)) { enableTraceAxis(t, axis, enabled); } } @@ -290,17 +291,20 @@ bool TraceXYPlot::isTDRtype(TraceXYPlot::YAxisType type) } } +void TraceXYPlot::axisSetupDialog() +{ + auto setup = new XYplotAxisDialog(this); + setup->show(); +} + void TraceXYPlot::updateContextMenu() { contextmenu->clear(); auto setup = new QAction("Axis setup...", contextmenu); - connect(setup, &QAction::triggered, [this]() { - auto setup = new XYplotAxisDialog(this); - setup->show(); - }); + connect(setup, &QAction::triggered, this, &TraceXYPlot::axisSetupDialog); contextmenu->addAction(setup); for(int axis = 0;axis < 2;axis++) { - if(YAxis[axis].Ytype == YAxisType::Disabled) { + if(YAxis[axis].type == YAxisType::Disabled) { continue; } if(axis == 0) { @@ -310,7 +314,7 @@ void TraceXYPlot::updateContextMenu() } for(auto t : traces) { // Skip traces that are not applicable for the selected axis type - if(!supported(t.first, YAxis[axis].Ytype)) { + if(!supported(t.first, YAxis[axis].type)) { continue; } @@ -341,6 +345,7 @@ bool TraceXYPlot::supported(Trace *) void TraceXYPlot::replot() { + updateXAxis(); plot->replot(); } @@ -381,12 +386,12 @@ void TraceXYPlot::enableTraceAxis(Trace *t, int axis, bool enabled) markerAdded(m); } } - if(isTDRtype(YAxis[axis].Ytype)) { + if(isTDRtype(YAxis[axis].type)) { t->addTDRinterest(); } traceColorChanged(t); } else { - if(isTDRtype(YAxis[axis].Ytype)) { + if(isTDRtype(YAxis[axis].type)) { t->removeTDRinterest(); } tracesAxis[axis].erase(t); @@ -436,22 +441,78 @@ bool TraceXYPlot::supported(Trace *t, TraceXYPlot::YAxisType type) void TraceXYPlot::updateXAxis() { - if(XAxis.autorange && sweep_fmax-sweep_fmin > 0) { + if(XAxis.mode == XAxisMode::Manual) { + plot->setAxisScale(QwtPlot::xBottom, XAxis.rangeMin, XAxis.rangeMax, XAxis.rangeDiv); + } else { + // automatic mode, figure out limits + double max = std::numeric_limits::lowest(); + double min = std::numeric_limits::max(); + if(XAxis.mode == XAxisMode::UseSpan) { + min = sweep_fmin; + max = sweep_fmax; + } else if(XAxis.mode == XAxisMode::FitTraces) { + for(auto t : traces) { + bool enabled = (tracesAxis[0].find(t.first) != tracesAxis[0].end() + || tracesAxis[1].find(t.first) != tracesAxis[1].end()); + auto trace = t.first; + if(enabled && trace->isVisible()) { + // this trace is currently displayed + double trace_min, trace_max; + switch(XAxis.type) { + case XAxisType::Frequency: + trace_min = trace->minFreq(); + trace_max = trace->maxFreq(); + break; + case XAxisType::Time: + trace_min = trace->getTDR().front().time; + trace_max = trace->getTDR().back().time; + break; + case XAxisType::Distance: + trace_min = trace->getTDR().front().distance; + trace_max = trace->getTDR().back().distance; + break; + } + if(trace_min < min) { + min = trace_min; + } + if(trace_max > max) { + max = trace_max; + } + } + } + } + if(min >= max) { + // still at initial values, no traces are active, leave axis unchanged + return; + } + constexpr int minDivisions = 8; + double max_div_step = (max - min) / minDivisions; + int zeros = floor(log10(max_div_step)); + double decimals_shift = pow(10, zeros); + max_div_step /= decimals_shift; + if(max_div_step >= 5) { + max_div_step = 5; + } else if(max_div_step >= 2) { + max_div_step = 2; + } else { + max_div_step = 1; + } + auto div_step = max_div_step * decimals_shift; + // round min up to next multiple of div_step + min = ceil(min / div_step) * div_step; QList tickList; - for(double tick = sweep_fmin;tick <= sweep_fmax;tick+= (sweep_fmax-sweep_fmin)/10) { + for(double tick = min;tick <= max;tick += div_step) { tickList.append(tick); } - QwtScaleDiv scalediv(sweep_fmin, sweep_fmax, QList(), QList(), tickList); + QwtScaleDiv scalediv(min, max, QList(), QList(), tickList); plot->setAxisScaleDiv(QwtPlot::xBottom, scalediv); - } else { - plot->setAxisScale(QwtPlot::xBottom, XAxis.rangeMin, XAxis.rangeMax, XAxis.rangeDiv); } triggerReplot(); } QwtSeriesData *TraceXYPlot::createQwtSeriesData(Trace &t, int axis) { - return new QwtTraceSeries(t, YAxis[axis].Ytype, XAxis.Xtype); + return new QwtTraceSeries(t, YAxis[axis].type, XAxis.type); } void TraceXYPlot::traceColorChanged(Trace *t) @@ -513,7 +574,7 @@ void TraceXYPlot::markerDataChanged(TraceMarker *m) { auto qwtMarker = markers[m]; qwtMarker->setXValue(m->getFrequency()); - qwtMarker->setYValue(FrequencyAxisTransformation(YAxis[0].Ytype, m->getData())); + qwtMarker->setYValue(FrequencyAxisTransformation(YAxis[0].type, m->getData())); triggerReplot(); } diff --git a/Software/PC_Application/Traces/tracexyplot.h b/Software/PC_Application/Traces/tracexyplot.h index afb0ba4..1846fd0 100644 --- a/Software/PC_Application/Traces/tracexyplot.h +++ b/Software/PC_Application/Traces/tracexyplot.h @@ -50,17 +50,24 @@ public: Time, Distance, }; + enum class XAxisMode { + UseSpan, + FitTraces, + Manual, + }; - virtual void setXAxis(double min, double max) override; + virtual void updateSpan(double min, double max) override; void setYAxis(int axis, YAxisType type, bool log, bool autorange, double min, double max, double div); - void setXAxis(XAxisType type, bool autorange, double min, double max, double div); + void setXAxis(XAxisType type, XAxisMode mode, double min, double max, double div); void enableTrace(Trace *t, bool enabled) override; // Applies potentially changed colors to all XY-plots static void updateGraphColors(); - bool isTDRtype(YAxisType type); +public slots: + void axisSetupDialog(); + protected: virtual void updateContextMenu() override; virtual bool supported(Trace *t) override; @@ -85,20 +92,27 @@ private: std::set tracesAxis[2]; - class Axis { + class YAxis { public: - union { - YAxisType Ytype; - XAxisType Xtype; - }; - bool log; + YAxisType type; + bool log; // not used yet bool autorange; double rangeMin; double rangeMax; double rangeDiv; }; - Axis YAxis[2]; - Axis XAxis; + class XAxis { + public: + XAxisType type; + XAxisMode mode; + bool log; // not used yet + double rangeMin; + double rangeMax; + double rangeDiv; + }; + + YAxis YAxis[2]; + XAxis XAxis; double sweep_fmin, sweep_fmax; using CurveData = struct { diff --git a/Software/PC_Application/Traces/xyplotaxisdialog.cpp b/Software/PC_Application/Traces/xyplotaxisdialog.cpp index 805856b..9f508a2 100644 --- a/Software/PC_Application/Traces/xyplotaxisdialog.cpp +++ b/Software/PC_Application/Traces/xyplotaxisdialog.cpp @@ -59,16 +59,17 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) : ui->Xmin->setEnabled(!checked); ui->Xmax->setEnabled(!checked); ui->Xdivs->setEnabled(!checked); + ui->Xautomode->setEnabled(checked); }); - ui->XType->setCurrentIndex((int) plot->XAxis.Xtype); + ui->XType->setCurrentIndex((int) plot->XAxis.type); ui->Xmin->setPrefixes("pnum kMG"); ui->Xmax->setPrefixes("pnum kMG"); ui->Xdivs->setPrefixes("pnum kMG"); // Fill initial values // assume same order in YAxisType enum as in ComboBox items - ui->Y1type->setCurrentIndex((int) plot->YAxis[0].Ytype); + ui->Y1type->setCurrentIndex((int) plot->YAxis[0].type); if(plot->YAxis[0].log) { ui->Y1log->setChecked(true); } else { @@ -79,7 +80,7 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) : ui->Y1max->setValueQuiet(plot->YAxis[0].rangeMax); ui->Y1divs->setValueQuiet(plot->YAxis[0].rangeDiv); - ui->Y2type->setCurrentIndex((int) plot->YAxis[1].Ytype); + ui->Y2type->setCurrentIndex((int) plot->YAxis[1].type); if(plot->YAxis[1].log) { ui->Y2log->setChecked(true); } else { @@ -90,7 +91,12 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) : ui->Y2max->setValueQuiet(plot->YAxis[1].rangeMax); ui->Y2divs->setValueQuiet(plot->YAxis[1].rangeDiv); - ui->Xauto->setChecked(plot->XAxis.autorange); + ui->Xauto->setChecked(plot->XAxis.mode != TraceXYPlot::XAxisMode::Manual); + if(plot->XAxis.mode == TraceXYPlot::XAxisMode::UseSpan) { + ui->Xautomode->setCurrentIndex(0); + } else { + ui->Xautomode->setCurrentIndex(1); + } ui->Xmin->setValueQuiet(plot->XAxis.rangeMin); ui->Xmax->setValueQuiet(plot->XAxis.rangeMax); ui->Xdivs->setValueQuiet(plot->XAxis.rangeDiv); @@ -106,7 +112,24 @@ void XYplotAxisDialog::on_buttonBox_accepted() // set plot values to the ones selected in the dialog plot->setYAxis(0, (TraceXYPlot::YAxisType) ui->Y1type->currentIndex(), ui->Y1log->isChecked(), ui->Y1auto->isChecked(), ui->Y1min->value(), ui->Y1max->value(), ui->Y1divs->value()); plot->setYAxis(1, (TraceXYPlot::YAxisType) ui->Y2type->currentIndex(), ui->Y2log->isChecked(), ui->Y2auto->isChecked(), ui->Y2min->value(), ui->Y2max->value(), ui->Y2divs->value()); - plot->setXAxis((TraceXYPlot::XAxisType) ui->XType->currentIndex(), ui->Xauto->isChecked(), ui->Xmin->value(), ui->Xmax->value(), ui->Xdivs->value()); + TraceXYPlot::XAxisMode mode; + if(ui->Xauto->isChecked()) { + if(ui->Xautomode->currentIndex() == 0) { + mode = TraceXYPlot::XAxisMode::UseSpan; + } else { + mode = TraceXYPlot::XAxisMode::FitTraces; + } + } else { + mode = TraceXYPlot::XAxisMode::Manual; + } + plot->setXAxis((TraceXYPlot::XAxisType) ui->XType->currentIndex(), mode, ui->Xmin->value(), ui->Xmax->value(), ui->Xdivs->value()); +} + +static void enableComboBoxItem(QComboBox *cb, int itemNum, bool enable) { + auto *model = qobject_cast(cb->model()); + auto item = model->item(itemNum); + item->setFlags(enable ? item->flags() | Qt::ItemIsEnabled + : item->flags() & ~Qt::ItemIsEnabled); } void XYplotAxisDialog::XAxisTypeChanged(int XAxisIndex) @@ -116,14 +139,8 @@ void XYplotAxisDialog::XAxisTypeChanged(int XAxisIndex) for(auto t : TraceXYPlot::YAxisTypes) { auto enable = supported.count(t) > 0; auto index = (int) t; - auto *model = qobject_cast(ui->Y1type->model()); - auto item = model->item(index); - item->setFlags(enable ? item->flags() | Qt::ItemIsEnabled - : item->flags() & ~Qt::ItemIsEnabled); - model = qobject_cast(ui->Y2type->model()); - item = model->item(index); - item->setFlags(enable ? item->flags() | Qt::ItemIsEnabled - : item->flags() & ~Qt::ItemIsEnabled); + enableComboBoxItem(ui->Y1type, index, enable); + enableComboBoxItem(ui->Y2type, index, enable); } // Disable Yaxis if previously selected type is not supported if(!supported.count((TraceXYPlot::YAxisType)ui->Y1type->currentIndex())) { @@ -133,6 +150,16 @@ void XYplotAxisDialog::XAxisTypeChanged(int XAxisIndex) ui->Y2type->setCurrentIndex(0); } + if(type == TraceXYPlot::XAxisType::Frequency) { + enableComboBoxItem(ui->Xautomode, 0, true); + } else { + // auto mode using span not supported in time mode + if(ui->Xautomode->currentIndex() == 0) { + ui->Xautomode->setCurrentIndex(1); + enableComboBoxItem(ui->Xautomode, 0, false); + } + } + QString unit; switch(type) { case TraceXYPlot::XAxisType::Frequency: unit = "Hz"; break; diff --git a/Software/PC_Application/Traces/xyplotaxisdialog.ui b/Software/PC_Application/Traces/xyplotaxisdialog.ui index e4dcc4e..faf48f0 100644 --- a/Software/PC_Application/Traces/xyplotaxisdialog.ui +++ b/Software/PC_Application/Traces/xyplotaxisdialog.ui @@ -6,7 +6,7 @@ 0 0 - 715 + 689 282 @@ -16,487 +16,493 @@ true - - - - 9 - 248 - 166 - 25 - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 10 - 10 - 701 - 233 - - - - - - - - - - 15 - - - - Primary Y axis - - - Qt::AlignCenter - - - - - - - - - Type: - - - - - - + + + + + + + + + + 15 + + + + Primary Y axis + + + Qt::AlignCenter + + + + + + + - Disabled + Type: - - + + + + + + + Disabled + + + + + Magnitude + + + + + Phase + + + + + VSWR + + + + + Impulse Response + + + + + Step Response + + + + + Impedance + + + + + + + + + + Qt::Horizontal + + + + + + + - Magnitude + Linear + + + Y1group + + + + + + + false - - - Phase + Log - - + + Y1group + + + + + + + + + Qt::Horizontal + + + + + + + - VSWR + Range: - - + + + + - Impulse Response + Auto - - + + + + - Step Response + Maximum: - - + + + + + + + - Impedance + Minimum: - - - - - - - - - Qt::Horizontal - - - - - - - - - Linear - - - Y1group - - - - - - - false - - - Log - - - Y1group - - - - - - - - - Qt::Horizontal - - - - - - - - - Range: - - - - - - - Auto - - - - - - - Maximum: - - - - - - - - - - Minimum: - - - - - - - - - - Divisions: - - - - - - - - - - - - - - Qt::Vertical - - - - - - - - - - 15 - - - - Secondary Y axis - - - Qt::AlignCenter - - - - - - - - - Type: - - - - - - + + + + + + + - Disabled + Divisions: - - + + + + + + + + + + + + + Qt::Vertical + + + + + + + + + + 15 + + + + Secondary Y axis + + + Qt::AlignCenter + + + + + + + - Magnitude + Type: - - + + + + + + + Disabled + + + + + Magnitude + + + + + Phase + + + + + VSWR + + + + + Impulse Response + + + + + Step Response + + + + + Impedance + + + + + + + + + + Qt::Horizontal + + + + + + + - Phase + Linear + + + Y2group + + + + + + + false - - - VSWR + Log - - + + Y2group + + + + + + + + + Qt::Horizontal + + + + + + + - Impulse Response + Range: - - + + + + - Step Response + Auto - - + + + + - Impedance + Maximum: - - - - - - - - - Qt::Horizontal - - - - - - - - - Linear - - - Y2group - - - - - - - false - - - Log - - - Y2group - - - - - - - - - Qt::Horizontal - - - - - - - - - Range: - - - - - - - Auto - - - - - - - Maximum: - - - - - - - - - - Minimum: - - - - - - - - - - Divisions: - - - - - - - - - - - - - - Qt::Vertical - - - - - - - - - - 0 - 0 - - - - - 15 - - - - X axis - - - Qt::AlignCenter - - - - - - - - - Type: - - - - - - + + + + + + + - Frequency + Minimum: - - + + + + + + + - Time + Divisions: - - + + + + + + + + + + + + + Qt::Vertical + + + + + + + + + + 0 + 0 + + + + + 15 + + + + X axis + + + Qt::AlignCenter + + + + + + + - Distance + Type: - - - - - - - - - Qt::Horizontal - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Range: - - - - - - - Auto - - - - - - - Maximum: - - - - - - - - - - Minimum: - - - - - - - - - - Divisions: - - - - - - - - - - - - + + + + + + + Frequency + + + + + Time + + + + + Distance + + + + + + + + + + Qt::Horizontal + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Range: + + + + + + + + + Auto + + + + + + + + Use Span + + + + + Fit Traces + + + + + + + + + + Maximum: + + + + + + + + + + Minimum: + + + + + + + + + + Divisions: + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + +