Alignment options for waterfall plot
This commit is contained in:
parent
bd69646c32
commit
1a779531ea
@ -5,6 +5,7 @@
|
|||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
#include "waterfallaxisdialog.h"
|
#include "waterfallaxisdialog.h"
|
||||||
#include "appwindow.h"
|
#include "appwindow.h"
|
||||||
|
#include "tracexyplot.h"
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
@ -14,6 +15,7 @@ using namespace std;
|
|||||||
TraceWaterfall::TraceWaterfall(TraceModel &model, QWidget *parent)
|
TraceWaterfall::TraceWaterfall(TraceModel &model, QWidget *parent)
|
||||||
: TracePlot(model, parent),
|
: TracePlot(model, parent),
|
||||||
dir(Direction::TopToBottom),
|
dir(Direction::TopToBottom),
|
||||||
|
align(Alignment::PrimaryOnly),
|
||||||
trace(nullptr),
|
trace(nullptr),
|
||||||
pixelsPerLine(1),
|
pixelsPerLine(1),
|
||||||
keepDataBeyondPlotSize(false),
|
keepDataBeyondPlotSize(false),
|
||||||
@ -63,6 +65,10 @@ void TraceWaterfall::fromJSON(nlohmann::json j)
|
|||||||
} else {
|
} else {
|
||||||
dir = Direction::BottomToTop;
|
dir = Direction::BottomToTop;
|
||||||
}
|
}
|
||||||
|
align = AlignmentFromString(QString::fromStdString(j.value("alignment", "")));
|
||||||
|
if(align == Alignment::Last) {
|
||||||
|
align = Alignment::PrimaryOnly;
|
||||||
|
}
|
||||||
|
|
||||||
for(unsigned int hash : j["traces"]) {
|
for(unsigned int hash : j["traces"]) {
|
||||||
// attempt to find the traces with this hash
|
// attempt to find the traces with this hash
|
||||||
@ -87,6 +93,7 @@ nlohmann::json TraceWaterfall::toJSON()
|
|||||||
j["direction"] = dir == Direction::TopToBottom ? "TopToBottom" : "BottomToTop";
|
j["direction"] = dir == Direction::TopToBottom ? "TopToBottom" : "BottomToTop";
|
||||||
j["keepDataBeyondPlot"] = keepDataBeyondPlotSize;
|
j["keepDataBeyondPlot"] = keepDataBeyondPlotSize;
|
||||||
j["maxLines"] = maxDataSweeps;
|
j["maxLines"] = maxDataSweeps;
|
||||||
|
j["alignment"] = AlignmentToString(align).toStdString();
|
||||||
nlohmann::json jtraces;
|
nlohmann::json jtraces;
|
||||||
for(auto t : traces) {
|
for(auto t : traces) {
|
||||||
if(t.second) {
|
if(t.second) {
|
||||||
@ -202,26 +209,40 @@ void TraceWaterfall::draw(QPainter &p)
|
|||||||
{
|
{
|
||||||
auto pref = Preferences::getInstance();
|
auto pref = Preferences::getInstance();
|
||||||
|
|
||||||
constexpr int yAxisLegendSpace = 25;
|
// constexpr int yAxisLegendSpace = 25;
|
||||||
constexpr int yAxisDisabledSpace = 10;
|
// constexpr int yAxisDisabledSpace = 10;
|
||||||
constexpr int xAxisSpace = 30;
|
constexpr int xAxisSpace = 30;
|
||||||
|
constexpr int topMargin = 10;
|
||||||
auto w = p.window();
|
auto w = p.window();
|
||||||
auto pen = QPen(pref.Graphs.Color.axis, 0);
|
auto pen = QPen(pref.Graphs.Color.axis, 0);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
plotAreaLeft = yAxisDisabledSpace;
|
// plotAreaLeft = yAxisDisabledSpace;
|
||||||
plotAreaWidth = w.width() - 3 * yAxisDisabledSpace - yAxisLegendSpace;
|
// plotAreaWidth = w.width() - 3 * yAxisDisabledSpace - yAxisLegendSpace;
|
||||||
plotAreaTop = 10;
|
|
||||||
plotAreaBottom = w.height() - xAxisSpace;
|
auto leftMargin = TraceXYPlot::sideMargin(align == Alignment::PrimaryOnly || align == Alignment::BothAxes);
|
||||||
|
auto rightMargin = TraceXYPlot::sideMargin(align == Alignment::SecondaryOnly || align == Alignment::BothAxes);
|
||||||
|
auto plotRect = QRect(leftMargin, topMargin, w.width() - leftMargin - rightMargin, w.height()-topMargin-xAxisSpace);
|
||||||
|
|
||||||
|
plotAreaTop = plotRect.y();
|
||||||
|
plotAreaLeft = plotRect.x();
|
||||||
|
plotAreaWidth = plotRect.width();
|
||||||
|
plotAreaBottom = plotRect.y()+plotRect.height();
|
||||||
|
|
||||||
// draw Y legend
|
// draw Y legend
|
||||||
auto plotRect = QRect(w.width() - yAxisDisabledSpace - yAxisLegendSpace, plotAreaTop, yAxisLegendSpace, plotAreaBottom-plotAreaTop);
|
QRect legendRect;
|
||||||
p.drawRect(plotRect);
|
constexpr int legendMargin = 10;
|
||||||
|
if(leftMargin < rightMargin) {
|
||||||
|
legendRect = QRect(QPoint(plotRect.x()+plotRect.width()+legendMargin, plotAreaTop), QPoint(width() - legendMargin, plotAreaBottom));
|
||||||
|
} else {
|
||||||
|
legendRect = QRect(QPoint(legendMargin, plotAreaTop), QPoint(leftMargin - legendMargin, plotAreaBottom));
|
||||||
|
}
|
||||||
|
p.drawRect(legendRect);
|
||||||
for(int i=plotAreaTop + 1;i<plotAreaBottom;i++) {
|
for(int i=plotAreaTop + 1;i<plotAreaBottom;i++) {
|
||||||
auto color = getColor(Util::Scale<double>(i, plotAreaTop, plotAreaBottom, 1.0, 0.0));
|
auto color = getColor(Util::Scale<double>(i, plotAreaTop, plotAreaBottom, 1.0, 0.0));
|
||||||
p.setPen(QColor(color));
|
p.setPen(QColor(color));
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
p.drawLine(w.width() - yAxisDisabledSpace - yAxisLegendSpace + 1, i, w.width() - yAxisDisabledSpace - 1, i);
|
p.drawLine(legendRect.x()+1, i, legendRect.x()+legendRect.width()-1, i);
|
||||||
}
|
}
|
||||||
QString unit = "";
|
QString unit = "";
|
||||||
if(pref.Graphs.showUnits) {
|
if(pref.Graphs.showUnits) {
|
||||||
@ -231,17 +252,17 @@ void TraceWaterfall::draw(QPainter &p)
|
|||||||
QString labelMax = Unit::ToString(yAxis.getRangeMax(), unit, yAxis.Prefixes(), 4);
|
QString labelMax = Unit::ToString(yAxis.getRangeMax(), unit, yAxis.Prefixes(), 4);
|
||||||
p.setPen(QPen(pref.Graphs.Color.axis, 1));
|
p.setPen(QPen(pref.Graphs.Color.axis, 1));
|
||||||
p.save();
|
p.save();
|
||||||
p.translate(w.width() - yAxisDisabledSpace - yAxisLegendSpace, w.height());
|
p.translate(legendRect.x(), w.height());
|
||||||
p.rotate(-90);
|
p.rotate(-90);
|
||||||
p.drawText(QRect(xAxisSpace + 10, 0, plotAreaBottom - plotAreaTop - 20, yAxisLegendSpace), Qt::AlignRight | Qt::AlignVCenter, labelMax);
|
p.drawText(QRect(xAxisSpace + 10, 0, plotAreaBottom - plotAreaTop - 20, legendRect.width()), Qt::AlignRight | Qt::AlignVCenter, labelMax);
|
||||||
p.drawText(QRect(xAxisSpace + 10, 0, plotAreaBottom - plotAreaTop - 20, yAxisLegendSpace), Qt::AlignLeft | Qt::AlignVCenter, labelMin);
|
p.drawText(QRect(xAxisSpace + 10, 0, plotAreaBottom - plotAreaTop - 20, legendRect.width()), Qt::AlignLeft | Qt::AlignVCenter, labelMin);
|
||||||
|
p.drawText(QRect(xAxisSpace + 10, 0, plotAreaBottom - plotAreaTop - 20, legendRect.width()), Qt::AlignHCenter | Qt::AlignVCenter, yAxis.TypeToName());
|
||||||
p.restore();
|
p.restore();
|
||||||
|
|
||||||
|
|
||||||
pen = QPen(pref.Graphs.Color.axis, 0);
|
pen = QPen(pref.Graphs.Color.axis, 0);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
plotRect = QRect(plotAreaLeft, plotAreaTop, plotAreaWidth + 1, plotAreaBottom-plotAreaTop);
|
|
||||||
p.drawRect(plotRect);
|
p.drawRect(plotRect);
|
||||||
|
|
||||||
// draw axis types
|
// draw axis types
|
||||||
@ -557,3 +578,24 @@ QColor TraceWaterfall::getColor(double scale)
|
|||||||
return Qt::black;
|
return Qt::black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString TraceWaterfall::AlignmentToString(Alignment a)
|
||||||
|
{
|
||||||
|
switch(a) {
|
||||||
|
case Alignment::PrimaryOnly: return "Primary Y axis only";
|
||||||
|
case Alignment::SecondaryOnly: return "Secondary Y axis only";
|
||||||
|
case Alignment::BothAxes: return "Both Y axes";
|
||||||
|
case Alignment::Last:
|
||||||
|
default: return "Invalid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TraceWaterfall::Alignment TraceWaterfall::AlignmentFromString(QString s)
|
||||||
|
{
|
||||||
|
for(unsigned int i=0;i<(int) Alignment::Last;i++) {
|
||||||
|
if(s == AlignmentToString((Alignment) i)) {
|
||||||
|
return (Alignment) i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Alignment::Last;
|
||||||
|
}
|
||||||
|
@ -54,7 +54,19 @@ private:
|
|||||||
BottomToTop,
|
BottomToTop,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// match alignment of XYplot with either one or both Y axes enabled
|
||||||
|
enum class Alignment {
|
||||||
|
PrimaryOnly = 0,
|
||||||
|
SecondaryOnly = 1,
|
||||||
|
BothAxes = 2,
|
||||||
|
Last,
|
||||||
|
};
|
||||||
|
|
||||||
|
static QString AlignmentToString(Alignment a);
|
||||||
|
static Alignment AlignmentFromString(QString s);
|
||||||
|
|
||||||
Direction dir;
|
Direction dir;
|
||||||
|
Alignment align;
|
||||||
|
|
||||||
Trace *trace;
|
Trace *trace;
|
||||||
|
|
||||||
|
@ -189,6 +189,15 @@ bool TraceXYPlot::isTDRtype(YAxis::Type type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TraceXYPlot::sideMargin(bool YAxisEnabled)
|
||||||
|
{
|
||||||
|
if(YAxisEnabled) {
|
||||||
|
return yAxisSpace;
|
||||||
|
} else {
|
||||||
|
return yAxisDisabledSpace;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TraceXYPlot::axisSetupDialog()
|
void TraceXYPlot::axisSetupDialog()
|
||||||
{
|
{
|
||||||
auto setup = new XYplotAxisDialog(this);
|
auto setup = new XYplotAxisDialog(this);
|
||||||
@ -321,9 +330,6 @@ void TraceXYPlot::draw(QPainter &p)
|
|||||||
{
|
{
|
||||||
auto pref = Preferences::getInstance();
|
auto pref = Preferences::getInstance();
|
||||||
|
|
||||||
constexpr int yAxisSpace = 55;
|
|
||||||
constexpr int yAxisDisabledSpace = 10;
|
|
||||||
constexpr int xAxisSpace = 30;
|
|
||||||
auto w = p.window();
|
auto w = p.window();
|
||||||
auto pen = QPen(pref.Graphs.Color.axis, 0);
|
auto pen = QPen(pref.Graphs.Color.axis, 0);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
|
@ -32,6 +32,8 @@ public:
|
|||||||
|
|
||||||
bool isTDRtype(YAxis::Type type);
|
bool isTDRtype(YAxis::Type type);
|
||||||
|
|
||||||
|
static int sideMargin(bool YAxisEnabled);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void axisSetupDialog();
|
void axisSetupDialog();
|
||||||
|
|
||||||
@ -45,6 +47,9 @@ private slots:
|
|||||||
void updateAxisTicks();
|
void updateAxisTicks();
|
||||||
private:
|
private:
|
||||||
static constexpr int AxisLabelSize = 10;
|
static constexpr int AxisLabelSize = 10;
|
||||||
|
static constexpr int yAxisSpace = 55;
|
||||||
|
static constexpr int yAxisDisabledSpace = 10;
|
||||||
|
static constexpr int xAxisSpace = 30;
|
||||||
static QString AxisModeToName(XAxisMode mode);
|
static QString AxisModeToName(XAxisMode mode);
|
||||||
static XAxisMode AxisModeFromName(QString name);
|
static XAxisMode AxisModeFromName(QString name);
|
||||||
void enableTraceAxis(Trace *t, int axis, bool enabled);
|
void enableTraceAxis(Trace *t, int axis, bool enabled);
|
||||||
|
@ -39,6 +39,10 @@ WaterfallAxisDialog::WaterfallAxisDialog(TraceWaterfall *plot) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(unsigned int i=0;i<(int) TraceWaterfall::Alignment::Last;i++) {
|
||||||
|
ui->Xalignment->addItem(TraceWaterfall::AlignmentToString((TraceWaterfall::Alignment) i));
|
||||||
|
}
|
||||||
|
|
||||||
// Setup GUI connections
|
// Setup GUI connections
|
||||||
connect(ui->Wtype, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
connect(ui->Wtype, qOverload<int>(&QComboBox::currentIndexChanged), [=](int index) {
|
||||||
//ui->Y1log->setEnabled(index != 0);
|
//ui->Y1log->setEnabled(index != 0);
|
||||||
@ -95,6 +99,7 @@ WaterfallAxisDialog::WaterfallAxisDialog(TraceWaterfall *plot) :
|
|||||||
} else {
|
} else {
|
||||||
ui->Xlinear->setChecked(true);
|
ui->Xlinear->setChecked(true);
|
||||||
}
|
}
|
||||||
|
ui->Xalignment->setCurrentIndex((int) plot->align);
|
||||||
}
|
}
|
||||||
|
|
||||||
WaterfallAxisDialog::~WaterfallAxisDialog()
|
WaterfallAxisDialog::~WaterfallAxisDialog()
|
||||||
@ -119,6 +124,7 @@ void WaterfallAxisDialog::on_buttonBox_accepted()
|
|||||||
} else {
|
} else {
|
||||||
plot->keepDataBeyondPlotSize = true;
|
plot->keepDataBeyondPlotSize = true;
|
||||||
}
|
}
|
||||||
|
plot->align = (TraceWaterfall::Alignment) ui->Xalignment->currentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaterfallAxisDialog::XAxisTypeChanged(int XAxisIndex)
|
void WaterfallAxisDialog::XAxisTypeChanged(int XAxisIndex)
|
||||||
@ -158,7 +164,6 @@ std::set<YAxis::Type> WaterfallAxisDialog::supportedYAxis(XAxis::Type type)
|
|||||||
ret.insert(YAxis::Type::Magnitude);
|
ret.insert(YAxis::Type::Magnitude);
|
||||||
ret.insert(YAxis::Type::MagnitudeLinear);
|
ret.insert(YAxis::Type::MagnitudeLinear);
|
||||||
ret.insert(YAxis::Type::Phase);
|
ret.insert(YAxis::Type::Phase);
|
||||||
ret.insert(YAxis::Type::UnwrappedPhase);
|
|
||||||
ret.insert(YAxis::Type::VSWR);
|
ret.insert(YAxis::Type::VSWR);
|
||||||
ret.insert(YAxis::Type::Real);
|
ret.insert(YAxis::Type::Real);
|
||||||
ret.insert(YAxis::Type::Imaginary);
|
ret.insert(YAxis::Type::Imaginary);
|
||||||
@ -167,7 +172,6 @@ std::set<YAxis::Type> WaterfallAxisDialog::supportedYAxis(XAxis::Type type)
|
|||||||
ret.insert(YAxis::Type::Capacitance);
|
ret.insert(YAxis::Type::Capacitance);
|
||||||
ret.insert(YAxis::Type::Inductance);
|
ret.insert(YAxis::Type::Inductance);
|
||||||
ret.insert(YAxis::Type::QualityFactor);
|
ret.insert(YAxis::Type::QualityFactor);
|
||||||
ret.insert(YAxis::Type::GroupDelay);
|
|
||||||
break;
|
break;
|
||||||
case XAxis::Type::Time:
|
case XAxis::Type::Time:
|
||||||
case XAxis::Type::Distance:
|
case XAxis::Type::Distance:
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>539</width>
|
<width>451</width>
|
||||||
<height>351</height>
|
<height>351</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -19,9 +19,9 @@
|
|||||||
<property name="modal">
|
<property name="modal">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,1">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
@ -198,6 +198,9 @@
|
|||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QSpinBox" name="WmaxSweeps">
|
<widget class="QSpinBox" name="WmaxSweeps">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
@ -292,6 +295,32 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line_8">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Alignment</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_11">
|
||||||
|
<property name="text">
|
||||||
|
<string>Match XY-Plot with:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="Xalignment"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -305,13 +334,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line_8">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -371,8 +393,7 @@
|
|||||||
</connection>
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
<buttongroups>
|
<buttongroups>
|
||||||
<buttongroup name="Y1group"/>
|
|
||||||
<buttongroup name="Y2group"/>
|
|
||||||
<buttongroup name="Xgroup"/>
|
<buttongroup name="Xgroup"/>
|
||||||
|
<buttongroup name="Y1group"/>
|
||||||
</buttongroups>
|
</buttongroups>
|
||||||
</ui>
|
</ui>
|
||||||
|
Loading…
Reference in New Issue
Block a user