Add setting for graph behavior when trace no longer supported

This commit is contained in:
Jan Käberich 2021-07-10 13:12:30 +02:00
parent b45645f04e
commit dda149f3d5
11 changed files with 363 additions and 227 deletions

View file

@ -83,8 +83,8 @@ void Marker::assignTrace(Trace *t)
// Marker was just created and this is the first assignment to a trace.
// Use display format on graph from preferences
auto p = Preferences::getInstance();
if(p.General.markerDefault.showDataOnGraphs) {
if(p.General.markerDefault.showAllData) {
if(p.Graphs.markerBehavior.showDataOnGraphs) {
if(p.Graphs.markerBehavior.showAllData) {
for(auto f : applicableFormats()) {
formatGraph.insert(f);
}

View file

@ -334,8 +334,8 @@ void Math::TimeGateGraph::paintEvent(QPaintEvent *event)
auto pref = Preferences::getInstance();
QPainter p(this);
// fill background
p.setBackground(QBrush(pref.General.graphColors.background));
p.fillRect(0, 0, width(), height(), QBrush(pref.General.graphColors.background));
p.setBackground(QBrush(pref.Graphs.Color.background));
p.fillRect(0, 0, width(), height(), QBrush(pref.Graphs.Color.background));
// plot trace
auto pen = QPen(Qt::green, 1);

View file

@ -15,6 +15,7 @@ TracePlot::TracePlot(TraceModel &model, QWidget *parent)
: QWidget(parent),
model(model),
selectedMarker(nullptr),
traceRemovalPending(false),
dropPending(false),
dropTrace(nullptr)
{
@ -96,6 +97,17 @@ void TracePlot::initializeTraceInfo()
connect(&model, &TraceModel::traceAdded, this, &TracePlot::newTraceAvailable);
}
std::vector<Trace *> TracePlot::activeTraces()
{
std::vector<Trace*> ret;
for(auto t : traces) {
if(t.second) {
ret.push_back(t.first);
}
}
return ret;
}
void TracePlot::contextMenuEvent(QContextMenuEvent *event)
{
auto m = markerAtPosition(event->pos());
@ -117,13 +129,25 @@ void TracePlot::contextMenuEvent(QContextMenuEvent *event)
void TracePlot::paintEvent(QPaintEvent *event)
{
if(traceRemovalPending) {
for(auto t : traces) {
if(!t.second) {
// trace already disabled
}
if(!supported(t.first)) {
enableTrace(t.first, false);
}
}
traceRemovalPending = false;
}
Q_UNUSED(event)
auto pref = Preferences::getInstance();
QPainter p(this);
// p.setRenderHint(QPainter::Antialiasing);
// fill background
p.setBackground(QBrush(pref.General.graphColors.background));
p.fillRect(0, 0, width(), height(), QBrush(pref.General.graphColors.background));
p.setBackground(QBrush(pref.Graphs.Color.background));
p.fillRect(0, 0, width(), height(), QBrush(pref.Graphs.Color.background));
// show names of active traces and marker data (if enabled)
bool hasMarkerData = false;
@ -374,7 +398,27 @@ void TracePlot::checkIfStillSupported(Trace *t)
{
if(!supported(t)) {
// something with this trace changed and it can no longer be displayed on this graph
enableTrace(t, false);
// behavior depends on preferences
switch(Preferences::getInstance().Graphs.domainChangeBehavior) {
case GraphDomainChangeBehavior::RemoveChangedTraces:
// simply remove the changed trace
enableTrace(t, false);
break;
case GraphDomainChangeBehavior::AdjustGrahpsIfOnlyTrace:
// remove trace if other traces are present, otherwise try to adjust graph
if(activeTraces().size() > 1) {
enableTrace(t, false);
break;
}
[[fallthrough]];
case GraphDomainChangeBehavior::AdjustGraphs:
// attempt to configure the graph for the changed trace, remove only if this fails
if(!configureForTrace(t)) {
enableTrace(t, false);
}
break;
}
}
}

View file

@ -39,6 +39,9 @@ protected:
static constexpr int MinUpdateInterval = 100;
// need to be called in derived class constructor
void initializeTraceInfo();
std::vector<Trace*> activeTraces();
// changes the graph settings to make it possible to display a specific trace. The trace is not aded yet
virtual bool configureForTrace(Trace *t) { Q_UNUSED(t) return false; }; // default implementation fails for all traces
void contextMenuEvent(QContextMenuEvent *event) override;
void paintEvent(QPaintEvent *event) override;
virtual void updateContextMenu(){};
@ -92,6 +95,9 @@ protected:
TraceModel &model;
Marker *selectedMarker;
// graph settings have been changed, check and possibly remove incompatible traces before next paint event
bool traceRemovalPending;
bool dropPending;
QPoint dropPosition;
Trace *dropTrace;

View file

@ -145,14 +145,14 @@ void TraceSmithChart::draw(QPainter &p) {
transform = p.transform();
// Outer circle
auto pen = QPen(pref.General.graphColors.axis);
auto pen = QPen(pref.Graphs.Color.axis);
pen.setCosmetic(true);
p.setPen(pen);
QRectF rectangle(-smithCoordMax, -smithCoordMax, 2*smithCoordMax, 2*smithCoordMax);
p.drawArc(rectangle, 0, 5760);
constexpr int Circles = 6;
pen = QPen(pref.General.graphColors.divisions, 0.5, Qt::DashLine);
pen = QPen(pref.Graphs.Color.divisions, 0.5, Qt::DashLine);
pen.setCosmetic(true);
p.setPen(pen);
for(int i=1;i<Circles;i++) {

View file

@ -77,7 +77,7 @@ void TraceXYPlot::setYAxis(int axis, TraceXYPlot::YAxisType type, bool log, bool
YAxis[axis].rangeMin = min;
YAxis[axis].rangeMax = max;
YAxis[axis].rangeDiv = div;
removeUnsupportedTraces();
traceRemovalPending = true;
updateAxisTicks();
updateContextMenu();
replot();
@ -90,7 +90,7 @@ void TraceXYPlot::setXAxis(XAxisType type, XAxisMode mode, double min, double ma
XAxis.rangeMin = min;
XAxis.rangeMax = max;
XAxis.rangeDiv = div;
removeUnsupportedTraces();
traceRemovalPending = true;
updateAxisTicks();
updateContextMenu();
replot();
@ -223,6 +223,32 @@ void TraceXYPlot::axisSetupDialog()
setup->show();
}
bool TraceXYPlot::configureForTrace(Trace *t)
{
switch(t->outputType()) {
case Trace::DataType::Frequency:
setXAxis(XAxisType::Frequency, XAxisMode::FitTraces, 0, 1, 0.1);
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
break;
case Trace::DataType::Time:
setXAxis(XAxisType::Time, XAxisMode::FitTraces, 0, 1, 0.1);
setYAxis(0, YAxisType::ImpulseMag, false, true, 0, 1, 1.0);
setYAxis(1, YAxisType::Disabled, false, true, 0, 1, 1.0);
break;
case Trace::DataType::Power:
setXAxis(XAxisType::Power, XAxisMode::FitTraces, 0, 1, 0.1);
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
break;
case Trace::DataType::Invalid:
// unable to add
return false;
}
traceRemovalPending = true;
return true;
}
void TraceXYPlot::updateContextMenu()
{
contextmenu->clear();
@ -322,7 +348,7 @@ void TraceXYPlot::draw(QPainter &p)
constexpr int yAxisDisabledSpace = 10;
constexpr int xAxisSpace = 30;
auto w = p.window();
auto pen = QPen(pref.General.graphColors.axis, 0);
auto pen = QPen(pref.Graphs.Color.axis, 0);
pen.setCosmetic(true);
p.setPen(pen);
plotAreaLeft = YAxis[0].type == YAxisType::Disabled ? yAxisDisabledSpace : yAxisSpace;
@ -378,14 +404,14 @@ void TraceXYPlot::draw(QPainter &p)
p.setPen(QPen(QColor("orange")));
QRect bounding;
p.drawText(QRect(2, plotAreaBottom + AxisLabelSize + 5, w.width(), AxisLabelSize), 0, front, &bounding);
p.setPen(pref.General.graphColors.axis);
p.setPen(pref.Graphs.Color.axis);
p.drawText(QRect(bounding.x() + bounding.width(), plotAreaBottom + AxisLabelSize + 5, w.width(), AxisLabelSize), 0, back);
}
for(auto t : XAxis.ticks) {
auto xCoord = Util::Scale<double>(t, XAxis.rangeMin, XAxis.rangeMax, plotAreaLeft, plotAreaLeft + plotAreaWidth);
auto tickValue = Unit::ToString(t, "", prefixes, significantDigits);
p.setPen(QPen(pref.General.graphColors.axis, 1));
p.setPen(QPen(pref.Graphs.Color.axis, 1));
if(displayFullFreq) {
p.drawText(QRect(xCoord - 40, plotAreaBottom + 5, 80, AxisLabelSize), Qt::AlignHCenter, tickValue);
} else {
@ -400,11 +426,11 @@ void TraceXYPlot::draw(QPainter &p)
p.drawText(QRect(xCoord - 40, plotAreaBottom + 5, 80, AxisLabelSize), Qt::AlignHCenter, tickValue, &bounding);
p.setPen(QPen(QColor("orange")));
p.drawText(QRect(0, plotAreaBottom + 5, bounding.x() - 1, AxisLabelSize), Qt::AlignRight, "..");
p.setPen(QPen(pref.General.graphColors.axis, 1));
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.General.graphColors.divisions, 0.5, Qt::DashLine));
p.setPen(QPen(pref.Graphs.Color.divisions, 0.5, Qt::DashLine));
p.drawLine(xCoord, 0, xCoord, plotAreaBottom);
}
}
@ -415,7 +441,7 @@ void TraceXYPlot::draw(QPainter &p)
continue;
}
QString labelY = AxisTypeToName(YAxis[i].type);
p.setPen(QPen(pref.General.graphColors.axis, 1));
p.setPen(QPen(pref.Graphs.Color.axis, 1));
auto xStart = i == 0 ? 0 : w.width() - AxisLabelSize * 1.5;
p.save();
p.translate(xStart, w.height()-xAxisSpace);
@ -436,7 +462,7 @@ void TraceXYPlot::draw(QPainter &p)
int significantDigits = floor(log10(max)) - floor(log10(step)) + 1;
for(auto t : YAxis[i].ticks) {
auto yCoord = Util::Scale<double>(t, YAxis[i].rangeMax, YAxis[i].rangeMin, 0, w.height() - xAxisSpace);
p.setPen(QPen(pref.General.graphColors.axis, 1));
p.setPen(QPen(pref.Graphs.Color.axis, 1));
// draw tickmark on axis
auto tickStart = i == 0 ? plotAreaLeft : plotAreaLeft + plotAreaWidth;
auto tickLen = i == 0 ? -2 : 2;
@ -455,7 +481,7 @@ void TraceXYPlot::draw(QPainter &p)
}
if(i == 0) {
// only draw tick lines for primary axis
p.setPen(QPen(pref.General.graphColors.divisions, 0.5, Qt::DashLine));
p.setPen(QPen(pref.Graphs.Color.divisions, 0.5, Qt::DashLine));
p.drawLine(plotAreaLeft, yCoord, plotAreaLeft + plotAreaWidth, yCoord);
}
}
@ -839,18 +865,6 @@ bool TraceXYPlot::supported(Trace *t, TraceXYPlot::YAxisType type)
return true;
}
void TraceXYPlot::removeUnsupportedTraces()
{
for(unsigned int i=0;i<2;i++) {
auto set_copy = tracesAxis[i];
for(auto t : set_copy) {
if(!supported(t, YAxis[i].type)) {
enableTraceAxis(t, i, false);
}
}
}
}
QPointF TraceXYPlot::traceToCoordinate(Trace *t, unsigned int sample, TraceXYPlot::YAxisType type)
{
QPointF ret = QPointF(numeric_limits<double>::quiet_NaN(), numeric_limits<double>::quiet_NaN());
@ -981,24 +995,8 @@ void TraceXYPlot::traceDropped(Trace *t, QPoint position)
// user declined to change domain, to not add trace
return;
}
switch(t->outputType()) {
case Trace::DataType::Frequency:
setXAxis(XAxisType::Frequency, XAxisMode::FitTraces, 0, 1, 0.1);
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
break;
case Trace::DataType::Time:
setXAxis(XAxisType::Time, XAxisMode::FitTraces, 0, 1, 0.1);
setYAxis(0, YAxisType::ImpulseMag, false, true, 0, 1, 1.0);
setYAxis(1, YAxisType::Disabled, false, true, 0, 1, 1.0);
break;
case Trace::DataType::Power:
setXAxis(XAxisType::Power, XAxisMode::FitTraces, 0, 1, 0.1);
setYAxis(0, YAxisType::Magnitude, false, true, 0, 1, 1.0);
setYAxis(1, YAxisType::Phase, false, true, 0, 1, 1.0);
break;
case Trace::DataType::Invalid:
// unable to add
if(!configureForTrace(t)) {
// failed to configure
return;
}
}

View file

@ -60,6 +60,7 @@ public slots:
void axisSetupDialog();
protected:
virtual bool configureForTrace(Trace *t) override;
virtual void updateContextMenu() override;
virtual bool dropSupported(Trace *t) override;
virtual void draw(QPainter &p) override;
@ -77,7 +78,6 @@ private:
void enableTraceAxis(Trace *t, int axis, bool enabled);
bool supported(Trace *t) override;
bool supported(Trace *t, YAxisType type);
void removeUnsupportedTraces();
QPointF traceToCoordinate(Trace *t, unsigned int sample, YAxisType type);
QPoint plotValueToPixel(QPointF plotValue, int Yaxis);
QPointF pixelToPlotValue(QPoint pixel, int YAxis);