Autoscale improvements
This commit is contained in:
parent
3976db8f9d
commit
32270dc747
@ -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 *)
|
||||
|
@ -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()
|
||||
|
@ -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<complex<double>> 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<fft_bins;i++) {
|
||||
TimedomainData t;
|
||||
t.time = fs * i;
|
||||
t.distance = t.time * c * 0.66; // TODO user settable velocity factor
|
||||
if(isReflection()) {
|
||||
t.distance /= 2;
|
||||
}
|
||||
t.impulseResponse = real(frequencyDomain[i]) / fft_bins;
|
||||
t.stepResponse = last_step;
|
||||
last_step += t.impulseResponse;
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
class TimedomainData {
|
||||
public:
|
||||
double time;
|
||||
double distance;
|
||||
double impulseResponse;
|
||||
double stepResponse;
|
||||
};
|
||||
|
@ -20,6 +20,9 @@ TraceModel::~TraceModel()
|
||||
void TraceModel::addTrace(Trace *t)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), traces.size(), traces.size());
|
||||
connect(t, &Trace::nameChanged, [=]() {
|
||||
emit traceNameChanged(t);
|
||||
});
|
||||
traces.push_back(t);
|
||||
endInsertRows();
|
||||
emit traceAdded(t);
|
||||
|
@ -32,6 +32,7 @@ signals:
|
||||
void traceAdded(Trace *t);
|
||||
void traceRemoved(Trace *t);
|
||||
void requiredExcitation(bool excitePort1, bool excitePort2);
|
||||
void traceNameChanged(Trace *t);
|
||||
|
||||
public slots:
|
||||
void clearVNAData();
|
||||
|
@ -121,8 +121,8 @@ void TracePlot::triggerReplot()
|
||||
{
|
||||
auto now = QTime::currentTime();
|
||||
if (lastUpdate.msecsTo(now) >= MinUpdateInterval) {
|
||||
replot();
|
||||
lastUpdate = now;
|
||||
replot();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<TracePlot *> getPlots();
|
||||
|
||||
|
@ -91,8 +91,11 @@ public:
|
||||
case TraceXYPlot::YAxisType::Impedance: {
|
||||
auto sample = t.getTDR()[i];
|
||||
QPointF p;
|
||||
// TODO set distance
|
||||
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<double, double>(&TraceXYPlot::setXAxis));
|
||||
connect(&model, &TraceModel::SpanChanged, this, qOverload<double, double>(&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<double>::lowest();
|
||||
double min = std::numeric_limits<double>::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<double> 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<double>(), QList<double>(), tickList);
|
||||
QwtScaleDiv scalediv(min, max, QList<double>(), QList<double>(), tickList);
|
||||
plot->setAxisScaleDiv(QwtPlot::xBottom, scalediv);
|
||||
} else {
|
||||
plot->setAxisScale(QwtPlot::xBottom, XAxis.rangeMin, XAxis.rangeMax, XAxis.rangeDiv);
|
||||
}
|
||||
triggerReplot();
|
||||
}
|
||||
|
||||
QwtSeriesData<QPointF> *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();
|
||||
}
|
||||
|
||||
|
@ -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<Trace*> 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 {
|
||||
|
@ -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<QStandardItemModel *>(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<QStandardItemModel *>(ui->Y1type->model());
|
||||
auto item = model->item(index);
|
||||
item->setFlags(enable ? item->flags() | Qt::ItemIsEnabled
|
||||
: item->flags() & ~Qt::ItemIsEnabled);
|
||||
model = qobject_cast<QStandardItemModel *>(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;
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>715</width>
|
||||
<width>689</width>
|
||||
<height>282</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -16,32 +16,9 @@
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>9</x>
|
||||
<y>248</y>
|
||||
<width>166</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>701</width>
|
||||
<height>233</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
@ -455,12 +432,30 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="Xauto">
|
||||
<property name="text">
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="Xautomode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use Span</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Fit Traces</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
@ -496,7 +491,18 @@
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
Loading…
Reference in New Issue
Block a user