Log option for X axis in XY plot (frequency axis only)
This commit is contained in:
parent
dd8f0c4fa9
commit
0379040a05
@ -44,7 +44,7 @@ TraceXYPlot::TraceXYPlot(TraceModel &model, QWidget *parent)
|
|||||||
setYAxis(1, YAxisType::Phase, false, false, -180, 180, 30);
|
setYAxis(1, YAxisType::Phase, false, false, -180, 180, 30);
|
||||||
// enable autoscaling and set for full span (no information about actual span available yet)
|
// enable autoscaling and set for full span (no information about actual span available yet)
|
||||||
updateSpan(0, 6000000000);
|
updateSpan(0, 6000000000);
|
||||||
setXAxis(XAxisType::Frequency, XAxisMode::UseSpan, 0, 6000000000, 600000000);
|
setXAxis(XAxisType::Frequency, XAxisMode::UseSpan, false, 0, 6000000000, 600000000);
|
||||||
initializeTraceInfo();
|
initializeTraceInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,10 +76,11 @@ void TraceXYPlot::setYAxis(int axis, TraceXYPlot::YAxisType type, bool log, bool
|
|||||||
replot();
|
replot();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TraceXYPlot::setXAxis(XAxisType type, XAxisMode mode, double min, double max, double div)
|
void TraceXYPlot::setXAxis(XAxisType type, XAxisMode mode, bool log, double min, double max, double div)
|
||||||
{
|
{
|
||||||
XAxis.type = type;
|
XAxis.type = type;
|
||||||
XAxis.mode = mode;
|
XAxis.mode = mode;
|
||||||
|
XAxis.log = log;
|
||||||
XAxis.rangeMin = min;
|
XAxis.rangeMin = min;
|
||||||
XAxis.rangeMax = max;
|
XAxis.rangeMax = max;
|
||||||
XAxis.rangeDiv = div;
|
XAxis.rangeDiv = div;
|
||||||
@ -165,7 +166,8 @@ void TraceXYPlot::fromJSON(nlohmann::json j)
|
|||||||
auto xmin = jX.value("min", 0.0);
|
auto xmin = jX.value("min", 0.0);
|
||||||
auto xmax = jX.value("max", 6000000000.0);
|
auto xmax = jX.value("max", 6000000000.0);
|
||||||
auto xdiv = jX.value("div", 600000000.0);
|
auto xdiv = jX.value("div", 600000000.0);
|
||||||
setXAxis(xtype, xmode, xmin, xmax, xdiv);
|
auto xlog = jX.value("log", false);
|
||||||
|
setXAxis(xtype, xmode, xlog, xmin, xmax, xdiv);
|
||||||
nlohmann::json jY[2] = {j["YPrimary"], j["YSecondary"]};
|
nlohmann::json jY[2] = {j["YPrimary"], j["YSecondary"]};
|
||||||
for(unsigned int i=0;i<2;i++) {
|
for(unsigned int i=0;i<2;i++) {
|
||||||
YAxisType ytype;
|
YAxisType ytype;
|
||||||
@ -220,17 +222,17 @@ bool TraceXYPlot::configureForTrace(Trace *t)
|
|||||||
{
|
{
|
||||||
switch(t->outputType()) {
|
switch(t->outputType()) {
|
||||||
case Trace::DataType::Frequency:
|
case Trace::DataType::Frequency:
|
||||||
setXAxis(XAxisType::Frequency, XAxisMode::FitTraces, 0, 1, 0.1);
|
setXAxis(XAxisType::Frequency, XAxisMode::FitTraces, false, 0, 1, 0.1);
|
||||||
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
|
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
|
||||||
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
|
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
|
||||||
break;
|
break;
|
||||||
case Trace::DataType::Time:
|
case Trace::DataType::Time:
|
||||||
setXAxis(XAxisType::Time, XAxisMode::FitTraces, 0, 1, 0.1);
|
setXAxis(XAxisType::Time, XAxisMode::FitTraces, false, 0, 1, 0.1);
|
||||||
setYAxis(0, YAxisType::ImpulseMag, false, true, 0, 1, 1.0);
|
setYAxis(0, YAxisType::ImpulseMag, false, true, 0, 1, 1.0);
|
||||||
setYAxis(1, YAxisType::Disabled, false, true, 0, 1, 1.0);
|
setYAxis(1, YAxisType::Disabled, false, true, 0, 1, 1.0);
|
||||||
break;
|
break;
|
||||||
case Trace::DataType::Power:
|
case Trace::DataType::Power:
|
||||||
setXAxis(XAxisType::Power, XAxisMode::FitTraces, 0, 1, 0.1);
|
setXAxis(XAxisType::Power, XAxisMode::FitTraces, false, 0, 1, 0.1);
|
||||||
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
|
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
|
||||||
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
|
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
|
||||||
break;
|
break;
|
||||||
@ -506,21 +508,24 @@ void TraceXYPlot::draw(QPainter &p)
|
|||||||
|
|
||||||
if(XAxis.ticks.size() >= 1) {
|
if(XAxis.ticks.size() >= 1) {
|
||||||
// draw X ticks
|
// draw X ticks
|
||||||
// this only works for evenly distributed ticks:
|
int significantDigits;
|
||||||
auto max = qMax(abs(XAxis.ticks.front()), abs(XAxis.ticks.back()));
|
bool displayFullFreq;
|
||||||
auto minLabel = qMin(abs(XAxis.ticks.front()), abs(XAxis.ticks.back()));
|
if(XAxis.log) {
|
||||||
double step;
|
significantDigits = 5;
|
||||||
if(XAxis.ticks.size() >= 2) {
|
displayFullFreq = true;
|
||||||
step = abs(XAxis.ticks[0] - XAxis.ticks[1]);
|
|
||||||
} else {
|
} else {
|
||||||
// only one tick, set arbitrary number of digits
|
// this only works for evenly distributed ticks:
|
||||||
step = max / 1000;
|
auto max = qMax(abs(XAxis.ticks.front()), abs(XAxis.ticks.back()));
|
||||||
|
double step;
|
||||||
|
if(XAxis.ticks.size() >= 2) {
|
||||||
|
step = abs(XAxis.ticks[0] - XAxis.ticks[1]);
|
||||||
|
} else {
|
||||||
|
// only one tick, set arbitrary number of digits
|
||||||
|
step = max / 1000;
|
||||||
|
}
|
||||||
|
significantDigits = floor(log10(max)) - floor(log10(step)) + 1;
|
||||||
|
displayFullFreq = significantDigits <= 5;
|
||||||
}
|
}
|
||||||
if(minLabel > 0 && minLabel < step) {
|
|
||||||
step = minLabel;
|
|
||||||
}
|
|
||||||
int significantDigits = floor(log10(max)) - floor(log10(step)) + 1;
|
|
||||||
bool displayFullFreq = significantDigits <= 5;
|
|
||||||
constexpr int displayLastDigits = 4;
|
constexpr int displayLastDigits = 4;
|
||||||
QString prefixes = "fpnum kMG";
|
QString prefixes = "fpnum kMG";
|
||||||
QString unit = "";
|
QString unit = "";
|
||||||
@ -543,12 +548,25 @@ void TraceXYPlot::draw(QPainter &p)
|
|||||||
p.drawText(QRect(bounding.x() + bounding.width(), plotAreaBottom + AxisLabelSize + 5, w.width(), AxisLabelSize), 0, back);
|
p.drawText(QRect(bounding.x() + bounding.width(), plotAreaBottom + AxisLabelSize + 5, w.width(), AxisLabelSize), 0, back);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lastTickLabelEnd = 0;
|
||||||
for(auto t : XAxis.ticks) {
|
for(auto t : XAxis.ticks) {
|
||||||
auto xCoord = Util::Scale<double>(t, XAxis.rangeMin, XAxis.rangeMax, plotAreaLeft, plotAreaLeft + plotAreaWidth);
|
auto xCoord = Util::Scale<double>(t, XAxis.rangeMin, XAxis.rangeMax, plotAreaLeft, plotAreaLeft + plotAreaWidth, XAxis.log);
|
||||||
|
p.setPen(QPen(pref.Graphs.Color.axis, 1));
|
||||||
|
p.drawLine(xCoord, plotAreaBottom, xCoord, plotAreaBottom + 2);
|
||||||
|
if(xCoord != plotAreaLeft && xCoord != plotAreaLeft + plotAreaWidth) {
|
||||||
|
p.setPen(QPen(pref.Graphs.Color.Ticks.divisions, 0.5, Qt::DashLine));
|
||||||
|
p.drawLine(xCoord, plotAreaTop, xCoord, plotAreaBottom);
|
||||||
|
}
|
||||||
|
if(xCoord - 40 <= lastTickLabelEnd) {
|
||||||
|
// would overlap previous tick label, skip
|
||||||
|
continue;
|
||||||
|
}
|
||||||
auto tickValue = Unit::ToString(t, unit, prefixes, significantDigits);
|
auto tickValue = Unit::ToString(t, unit, prefixes, significantDigits);
|
||||||
p.setPen(QPen(pref.Graphs.Color.axis, 1));
|
p.setPen(QPen(pref.Graphs.Color.axis, 1));
|
||||||
if(displayFullFreq) {
|
if(displayFullFreq) {
|
||||||
p.drawText(QRect(xCoord - 40, plotAreaBottom + 5, 80, AxisLabelSize), Qt::AlignHCenter, tickValue);
|
QRect bounding;
|
||||||
|
p.drawText(QRect(xCoord - 40, plotAreaBottom + 5, 80, AxisLabelSize), Qt::AlignHCenter, tickValue, &bounding);
|
||||||
|
lastTickLabelEnd = bounding.x() + bounding.width();
|
||||||
} else {
|
} else {
|
||||||
// check if the same prefix was used as in the fullFreq string
|
// check if the same prefix was used as in the fullFreq string
|
||||||
if(tickValue.at(tickValue.size() - 1) != commonPrefix) {
|
if(tickValue.at(tickValue.size() - 1) != commonPrefix) {
|
||||||
@ -559,14 +577,9 @@ void TraceXYPlot::draw(QPainter &p)
|
|||||||
tickValue.remove(0, tickValue.size() - displayLastDigits - unit.length());
|
tickValue.remove(0, tickValue.size() - displayLastDigits - unit.length());
|
||||||
QRect bounding;
|
QRect bounding;
|
||||||
p.drawText(QRect(xCoord - 40, plotAreaBottom + 5, 80, AxisLabelSize), Qt::AlignHCenter, tickValue, &bounding);
|
p.drawText(QRect(xCoord - 40, plotAreaBottom + 5, 80, AxisLabelSize), Qt::AlignHCenter, tickValue, &bounding);
|
||||||
|
lastTickLabelEnd = bounding.x() + bounding.width();
|
||||||
p.setPen(QPen(QColor("orange")));
|
p.setPen(QPen(QColor("orange")));
|
||||||
p.drawText(QRect(0, plotAreaBottom + 5, bounding.x() - 1, AxisLabelSize), Qt::AlignRight, "..");
|
p.drawText(QRect(0, plotAreaBottom + 5, bounding.x() - 1, AxisLabelSize), Qt::AlignRight, "..", &bounding);
|
||||||
p.setPen(QPen(pref.Graphs.Color.axis, 1));
|
|
||||||
}
|
|
||||||
p.drawLine(xCoord, plotAreaBottom, xCoord, plotAreaBottom + 2);
|
|
||||||
if(xCoord != plotAreaLeft && xCoord != plotAreaLeft + plotAreaWidth) {
|
|
||||||
p.setPen(QPen(pref.Graphs.Color.Ticks.divisions, 0.5, Qt::DashLine));
|
|
||||||
p.drawLine(xCoord, plotAreaTop, xCoord, plotAreaBottom);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -648,8 +661,48 @@ void TraceXYPlot::updateAxisTicks()
|
|||||||
return div_step;
|
return div_step;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto createLogarithmicTicks = [](vector<double>& ticks, double start, double stop, int minDivisions) {
|
||||||
|
Q_ASSERT(stop > start);
|
||||||
|
Q_ASSERT(start > 0);
|
||||||
|
ticks.clear();
|
||||||
|
|
||||||
|
auto decades = log10(stop) - log10(start);
|
||||||
|
double max_div_decade = minDivisions / decades;
|
||||||
|
int zeros = floor(log10(max_div_decade));
|
||||||
|
double decimals_shift = pow(10, zeros);
|
||||||
|
max_div_decade /= decimals_shift;
|
||||||
|
if(max_div_decade < 2) {
|
||||||
|
max_div_decade = 2;
|
||||||
|
} else if(max_div_decade < 5) {
|
||||||
|
max_div_decade = 5;
|
||||||
|
} else {
|
||||||
|
max_div_decade = 10;
|
||||||
|
}
|
||||||
|
auto step = pow(10, floor(log10(start))+1) / (max_div_decade * decimals_shift);
|
||||||
|
// round min up to next multiple of div_step
|
||||||
|
auto div = ceil(start / step) * step;
|
||||||
|
if(floor(log10(div)) != floor(log10(start))) {
|
||||||
|
// first div is already at the next decade
|
||||||
|
step *= 10;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
ticks.push_back(div);
|
||||||
|
if(ticks.size() > 1 && div != step && floor(log10(div)) != floor(log10(div - step))) {
|
||||||
|
// reached a new decade with this switch
|
||||||
|
step *= 10;
|
||||||
|
div = step;
|
||||||
|
} else {
|
||||||
|
div += step;
|
||||||
|
}
|
||||||
|
} while(div <= stop);
|
||||||
|
};
|
||||||
|
|
||||||
if(XAxis.mode == XAxisMode::Manual) {
|
if(XAxis.mode == XAxisMode::Manual) {
|
||||||
createEvenlySpacedTicks(XAxis.ticks, XAxis.rangeMin, XAxis.rangeMax, XAxis.rangeDiv);
|
if(XAxis.log) {
|
||||||
|
createLogarithmicTicks(XAxis.ticks, XAxis.rangeMin, XAxis.rangeMax, 20);
|
||||||
|
} else {
|
||||||
|
createEvenlySpacedTicks(XAxis.ticks, XAxis.rangeMin, XAxis.rangeMax, XAxis.rangeDiv);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
XAxis.ticks.clear();
|
XAxis.ticks.clear();
|
||||||
// automatic mode, figure out limits
|
// automatic mode, figure out limits
|
||||||
@ -688,7 +741,11 @@ void TraceXYPlot::updateAxisTicks()
|
|||||||
// found min/max values
|
// found min/max values
|
||||||
XAxis.rangeMin = min;
|
XAxis.rangeMin = min;
|
||||||
XAxis.rangeMax = max;
|
XAxis.rangeMax = max;
|
||||||
XAxis.rangeDiv = createAutomaticTicks(XAxis.ticks, min, max, 8);
|
if(XAxis.log) {
|
||||||
|
createLogarithmicTicks(XAxis.ticks, XAxis.rangeMin, XAxis.rangeMax, 20);
|
||||||
|
} else {
|
||||||
|
XAxis.rangeDiv = createAutomaticTicks(XAxis.ticks, min, max, 8);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1006,7 +1063,7 @@ QPointF TraceXYPlot::traceToCoordinate(Trace *t, unsigned int sample, TraceXYPlo
|
|||||||
QPoint TraceXYPlot::plotValueToPixel(QPointF plotValue, int Yaxis)
|
QPoint TraceXYPlot::plotValueToPixel(QPointF plotValue, int Yaxis)
|
||||||
{
|
{
|
||||||
QPoint p;
|
QPoint p;
|
||||||
p.setX(Util::Scale<double>(plotValue.x(), XAxis.rangeMin, XAxis.rangeMax, plotAreaLeft, plotAreaLeft + plotAreaWidth));
|
p.setX(Util::Scale<double>(plotValue.x(), XAxis.rangeMin, XAxis.rangeMax, plotAreaLeft, plotAreaLeft + plotAreaWidth, XAxis.log));
|
||||||
p.setY(Util::Scale<double>(plotValue.y(), YAxis[Yaxis].rangeMin, YAxis[Yaxis].rangeMax, plotAreaBottom, plotAreaTop));
|
p.setY(Util::Scale<double>(plotValue.y(), YAxis[Yaxis].rangeMin, YAxis[Yaxis].rangeMax, plotAreaBottom, plotAreaTop));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@ -1014,7 +1071,7 @@ QPoint TraceXYPlot::plotValueToPixel(QPointF plotValue, int Yaxis)
|
|||||||
QPointF TraceXYPlot::pixelToPlotValue(QPoint pixel, int Yaxis)
|
QPointF TraceXYPlot::pixelToPlotValue(QPoint pixel, int Yaxis)
|
||||||
{
|
{
|
||||||
QPointF p;
|
QPointF p;
|
||||||
p.setX(Util::Scale<double>(pixel.x(), plotAreaLeft, plotAreaLeft + plotAreaWidth, XAxis.rangeMin, XAxis.rangeMax));
|
p.setX(Util::Scale<double>(pixel.x(), plotAreaLeft, plotAreaLeft + plotAreaWidth, XAxis.rangeMin, XAxis.rangeMax, false, XAxis.log));
|
||||||
p.setY(Util::Scale<double>(pixel.y(), plotAreaBottom, plotAreaTop, YAxis[Yaxis].rangeMin, YAxis[Yaxis].rangeMax));
|
p.setY(Util::Scale<double>(pixel.y(), plotAreaBottom, plotAreaTop, YAxis[Yaxis].rangeMin, YAxis[Yaxis].rangeMax));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
void setYAxis(int axis, YAxisType type, bool log, bool autorange, double min, double max, double div);
|
void setYAxis(int axis, YAxisType type, bool log, bool autorange, double min, double max, double div);
|
||||||
void setXAxis(XAxisType type, XAxisMode mode, double min, double max, double div);
|
void setXAxis(XAxisType type, XAxisMode mode, bool log, double min, double max, double div);
|
||||||
void enableTrace(Trace *t, bool enabled) override;
|
void enableTrace(Trace *t, bool enabled) override;
|
||||||
void updateSpan(double min, double max) override;
|
void updateSpan(double min, double max) override;
|
||||||
void replot() override;
|
void replot() override;
|
||||||
|
@ -71,7 +71,7 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) :
|
|||||||
connect(ui->Xauto, &QCheckBox::toggled, [this](bool checked) {
|
connect(ui->Xauto, &QCheckBox::toggled, [this](bool checked) {
|
||||||
ui->Xmin->setEnabled(!checked);
|
ui->Xmin->setEnabled(!checked);
|
||||||
ui->Xmax->setEnabled(!checked);
|
ui->Xmax->setEnabled(!checked);
|
||||||
ui->Xdivs->setEnabled(!checked);
|
ui->Xdivs->setEnabled(!checked && ui->Xlinear->isChecked());
|
||||||
ui->Xautomode->setEnabled(checked);
|
ui->Xautomode->setEnabled(checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -82,6 +82,9 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) :
|
|||||||
|
|
||||||
XAxisTypeChanged((int) plot->XAxis.type);
|
XAxisTypeChanged((int) plot->XAxis.type);
|
||||||
connect(ui->XType, qOverload<int>(&QComboBox::currentIndexChanged), this, &XYplotAxisDialog::XAxisTypeChanged);
|
connect(ui->XType, qOverload<int>(&QComboBox::currentIndexChanged), this, &XYplotAxisDialog::XAxisTypeChanged);
|
||||||
|
connect(ui->Xlog, &QCheckBox::toggled, [=](bool checked){
|
||||||
|
ui->Xdivs->setEnabled(!checked && !ui->Xauto->isChecked());
|
||||||
|
});
|
||||||
|
|
||||||
// Fill initial values
|
// Fill initial values
|
||||||
ui->Y1type->setCurrentIndex((int) plot->YAxis[0].type);
|
ui->Y1type->setCurrentIndex((int) plot->YAxis[0].type);
|
||||||
@ -106,6 +109,11 @@ XYplotAxisDialog::XYplotAxisDialog(TraceXYPlot *plot) :
|
|||||||
ui->Y2max->setValueQuiet(plot->YAxis[1].rangeMax);
|
ui->Y2max->setValueQuiet(plot->YAxis[1].rangeMax);
|
||||||
ui->Y2divs->setValueQuiet(plot->YAxis[1].rangeDiv);
|
ui->Y2divs->setValueQuiet(plot->YAxis[1].rangeDiv);
|
||||||
|
|
||||||
|
if(plot->XAxis.log) {
|
||||||
|
ui->Xlog->setChecked(true);
|
||||||
|
} else {
|
||||||
|
ui->Xlinear->setChecked(true);
|
||||||
|
}
|
||||||
ui->Xauto->setChecked(plot->XAxis.mode != TraceXYPlot::XAxisMode::Manual);
|
ui->Xauto->setChecked(plot->XAxis.mode != TraceXYPlot::XAxisMode::Manual);
|
||||||
if(plot->XAxis.mode == TraceXYPlot::XAxisMode::UseSpan) {
|
if(plot->XAxis.mode == TraceXYPlot::XAxisMode::UseSpan) {
|
||||||
ui->Xautomode->setCurrentIndex(0);
|
ui->Xautomode->setCurrentIndex(0);
|
||||||
@ -137,7 +145,7 @@ void XYplotAxisDialog::on_buttonBox_accepted()
|
|||||||
} else {
|
} else {
|
||||||
mode = TraceXYPlot::XAxisMode::Manual;
|
mode = TraceXYPlot::XAxisMode::Manual;
|
||||||
}
|
}
|
||||||
plot->setXAxis((TraceXYPlot::XAxisType) ui->XType->currentIndex(), mode, ui->Xmin->value(), ui->Xmax->value(), ui->Xdivs->value());
|
plot->setXAxis((TraceXYPlot::XAxisType) ui->XType->currentIndex(), mode, ui->Xlog->isChecked(), ui->Xmin->value(), ui->Xmax->value(), ui->Xdivs->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enableComboBoxItem(QComboBox *cb, int itemNum, bool enable) {
|
static void enableComboBoxItem(QComboBox *cb, int itemNum, bool enable) {
|
||||||
@ -168,12 +176,18 @@ void XYplotAxisDialog::XAxisTypeChanged(int XAxisIndex)
|
|||||||
|
|
||||||
if(type == TraceXYPlot::XAxisType::Frequency) {
|
if(type == TraceXYPlot::XAxisType::Frequency) {
|
||||||
enableComboBoxItem(ui->Xautomode, 0, true);
|
enableComboBoxItem(ui->Xautomode, 0, true);
|
||||||
|
ui->Xlog->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
// auto mode using span not supported in time mode
|
// auto mode using span not supported in time mode
|
||||||
if(ui->Xautomode->currentIndex() == 0) {
|
if(ui->Xautomode->currentIndex() == 0) {
|
||||||
ui->Xautomode->setCurrentIndex(1);
|
ui->Xautomode->setCurrentIndex(1);
|
||||||
enableComboBoxItem(ui->Xautomode, 0, false);
|
|
||||||
}
|
}
|
||||||
|
enableComboBoxItem(ui->Xautomode, 0, false);
|
||||||
|
// log option only available for frequency axis
|
||||||
|
if(ui->Xlog->isChecked()) {
|
||||||
|
ui->Xlinear->setChecked(true);
|
||||||
|
}
|
||||||
|
ui->Xlog->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString unit = TraceXYPlot::AxisUnit(type);
|
QString unit = TraceXYPlot::AxisUnit(type);
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -325,17 +325,38 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="Xlinear">
|
||||||
|
<property name="text">
|
||||||
|
<string>Linear</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">Xgroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="Xlog">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Log</string>
|
||||||
|
</property>
|
||||||
|
<attribute name="buttonGroup">
|
||||||
|
<string notr="true">Xgroup</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line_8">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizeHint" stdset="0">
|
</widget>
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="formLayout_6">
|
<layout class="QFormLayout" name="formLayout_6">
|
||||||
@ -467,5 +488,6 @@
|
|||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="Y1group"/>
|
<buttongroup name="Y1group"/>
|
||||||
<buttongroup name="Y2group"/>
|
<buttongroup name="Y2group"/>
|
||||||
|
<buttongroup name="Xgroup"/>
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -9,10 +9,18 @@
|
|||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
|
||||||
namespace Util {
|
namespace Util {
|
||||||
template<typename T> T Scale(T value, T from_low, T from_high, T to_low, T to_high) {
|
template<typename T> T Scale(T value, T from_low, T from_high, T to_low, T to_high, bool log_from = false, bool log_to = false) {
|
||||||
value -= from_low;
|
double normalized;
|
||||||
value *= (to_high - to_low) / (from_high - from_low);
|
if(log_from) {
|
||||||
value += to_low;
|
normalized = log10(value / from_low) / log10(from_high / from_low);
|
||||||
|
} else {
|
||||||
|
normalized = (value - from_low) / (from_high - from_low);
|
||||||
|
}
|
||||||
|
if(log_to) {
|
||||||
|
value = to_low * pow(10.0, normalized * log10(to_high / to_low));
|
||||||
|
} else {
|
||||||
|
value = normalized * (to_high - to_low) + to_low;
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user