diff --git a/src/framebufferseries.cpp b/src/framebufferseries.cpp
--- a/src/framebufferseries.cpp
+++ b/src/framebufferseries.cpp
@@ -27,7 +27,7 @@ FrameBufferSeries::FrameBufferSeries(Fra
_xmax = 1;
_buffer = buffer;
int_index_start = 0;
- int_index_end = 0;
+ int_index_end = _buffer->size();
}
void FrameBufferSeries::setXAxis(bool asIndex, double xmin, double xmax)
@@ -85,6 +85,6 @@ void FrameBufferSeries::setRectOfInteres
int_index_end = ceil(bsize * (rect.right()-_xmin) / xsize)+1;
}
- int_index_start = std::max(int_index_start, (size_t) 0);
- int_index_end = std::min(_buffer->size(), int_index_end);
+ int_index_start = std::max(int_index_start, 0);
+ int_index_end = std::min((int) _buffer->size(), int_index_end);
}
diff --git a/src/framebufferseries.h b/src/framebufferseries.h
--- a/src/framebufferseries.h
+++ b/src/framebufferseries.h
@@ -52,8 +52,8 @@ private:
double _xmin;
double _xmax;
- size_t int_index_start; ///< starting index of "rectangle of interest"
- size_t int_index_end; ///< ending index of "rectangle of interest"
+ int int_index_start; ///< starting index of "rectangle of interest"
+ int int_index_end; ///< ending index of "rectangle of interest"
};
#endif // FRAMEBUFFERSERIES_H
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -151,6 +151,9 @@ MainWindow::MainWindow(QWidget *parent)
connect(&plotControlPanel, &PlotControlPanel::xScaleChanged,
plotMan, &PlotManager::setXAxis);
+ connect(&plotControlPanel, &PlotControlPanel::plotWidthChanged,
+ plotMan, &PlotManager::setPlotWidth);
+
QObject::connect(ui->actionClear, SIGNAL(triggered(bool)),
this, SLOT(clearPlot()));
@@ -226,6 +229,7 @@ MainWindow::MainWindow(QWidget *parent)
plotMan->setXAxis(plotControlPanel.xAxisAsIndex(),
plotControlPanel.xMin(), plotControlPanel.xMax());
plotMan->setNumOfSamples(numOfSamples);
+ plotMan->setPlotWidth(plotControlPanel.plotWidth());
// Init sps (sample per second) counter
spsLabel.setText("0sps");
diff --git a/src/plot.cpp b/src/plot.cpp
--- a/src/plot.cpp
+++ b/src/plot.cpp
@@ -39,6 +39,7 @@ Plot::Plot(QWidget* parent) :
isAutoScaled = true;
symbolSize = 0;
numOfSamples = 1;
+ plotWidth = 1;
showSymbols = Plot::ShowSymbolsAuto;
QObject::connect(&zoomer, &Zoomer::unzoomed, this, &Plot::unzoomed);
@@ -109,17 +110,18 @@ void Plot::setXAxis(double xMin, double
_xMin = xMin;
_xMax = xMax;
+ zoomer.setXLimits(xMin, xMax);
zoomer.zoom(0); // unzoom
// set axis
- setAxisScale(QwtPlot::xBottom, xMin, xMax);
+ // setAxisScale(QwtPlot::xBottom, xMin, xMax);
replot(); // Note: if we don't replot here scale at startup isn't set correctly
// reset zoom base
- auto base = zoomer.zoomBase();
- base.setLeft(xMin);
- base.setRight(xMax);
- zoomer.setZoomBase(base);
+ // auto base = zoomer.zoomBase();
+ // base.setLeft(xMin);
+ // base.setRight(xMax);
+ // zoomer.setZoomBase(base);
onXScaleChanged();
}
@@ -301,7 +303,8 @@ void Plot::calcSymbolSize()
auto scaleDist = sw->scaleDraw()->scaleMap().sDist();
auto fullScaleDist = zoomer.zoomBase().width();
auto zoomRate = fullScaleDist / scaleDist;
- float samplesInView = numOfSamples / zoomRate;
+ float plotWidthNumSamp = abs(numOfSamples * plotWidth / (_xMax - _xMin));
+ float samplesInView = plotWidthNumSamp / zoomRate;
int symDisPx = round(paintDist / samplesInView);
if (symDisPx < SYMBOL_SHOW_AT_WIDTH)
@@ -347,3 +350,9 @@ void Plot::setNumOfSamples(unsigned valu
numOfSamples = value;
onXScaleChanged();
}
+
+void Plot::setPlotWidth(double width)
+{
+ plotWidth = width;
+ zoomer.setHViewSize(width);
+}
diff --git a/src/plot.h b/src/plot.h
--- a/src/plot.h
+++ b/src/plot.h
@@ -73,6 +73,8 @@ public slots:
void setNumOfSamples(unsigned value);
+ void setPlotWidth(double width);
+
protected:
/// update the display of symbols depending on `symbolSize`
void updateSymbols();
@@ -82,6 +84,7 @@ private:
double yMin, yMax;
double _xMin, _xMax;
unsigned numOfSamples;
+ double plotWidth;
int symbolSize;
Zoomer zoomer;
ScaleZoomer sZoomer;
diff --git a/src/plotcontrolpanel.cpp b/src/plotcontrolpanel.cpp
--- a/src/plotcontrolpanel.cpp
+++ b/src/plotcontrolpanel.cpp
@@ -29,7 +29,7 @@
#include "setting_defines.h"
/// Confirm if #samples is being set to a value greater than this
-const int NUMSAMPLES_CONFIRM_AT = 10000;
+const int NUMSAMPLES_CONFIRM_AT = 1000000;
/// Used for scale range selection combobox
struct Range
@@ -89,6 +89,9 @@ PlotControlPanel::PlotControlPanel(QWidg
connect(ui->spXmin, SIGNAL(valueChanged(double)),
this, SLOT(onXScaleChanged()));
+ connect(ui->spPlotWidth, SIGNAL(valueChanged(int)),
+ this, SLOT(onPlotWidthChanged()));
+
// init scale range preset list
for (int nbits = 8; nbits <= 24; nbits++) // signed binary formats
{
@@ -275,6 +278,7 @@ void PlotControlPanel::onIndexChecked(bo
emit xScaleChanged(false, ui->spXmin->value(), ui->spXmax->value());
}
+ emit plotWidthChanged(plotWidth());
}
void PlotControlPanel::onXScaleChanged()
@@ -282,9 +286,29 @@ void PlotControlPanel::onXScaleChanged()
if (!xAxisAsIndex())
{
emit xScaleChanged(false, ui->spXmin->value(), ui->spXmax->value());
+ emit plotWidthChanged(plotWidth());
}
}
+double PlotControlPanel::plotWidth() const
+{
+ double value = ui->spPlotWidth->value();
+ if (!xAxisAsIndex())
+ {
+ // scale by xmin and xmax
+ auto xmax = ui->spXmax->value();
+ auto xmin = ui->spXmin->value();
+ double scale = (xmax - xmin) / _numOfSamples;
+ value *= scale;
+ }
+ return value;
+}
+
+void PlotControlPanel::onPlotWidthChanged()
+{
+ emit plotWidthChanged(plotWidth());
+}
+
void PlotControlPanel::setChannelInfoModel(ChannelInfoModel* model)
{
ui->tvChannelInfo->setModel(model);
@@ -362,6 +386,7 @@ void PlotControlPanel::saveSettings(QSet
{
settings->beginGroup(SettingGroup_Plot);
settings->setValue(SG_Plot_NumOfSamples, numOfSamples());
+ settings->setValue(SG_Plot_PlotWidth, ui->spPlotWidth->value());
settings->setValue(SG_Plot_IndexAsX, xAxisAsIndex());
settings->setValue(SG_Plot_XMax, xMax());
settings->setValue(SG_Plot_XMin, xMin());
@@ -376,6 +401,8 @@ void PlotControlPanel::loadSettings(QSet
settings->beginGroup(SettingGroup_Plot);
ui->spNumOfSamples->setValue(
settings->value(SG_Plot_NumOfSamples, numOfSamples()).toInt());
+ ui->spPlotWidth->setValue(
+ settings->value(SG_Plot_PlotWidth, ui->spPlotWidth->value()).toInt());
ui->cbIndex->setChecked(
settings->value(SG_Plot_IndexAsX, xAxisAsIndex()).toBool());
ui->spXmax->setValue(settings->value(SG_Plot_XMax, xMax()).toDouble());
diff --git a/src/plotcontrolpanel.h b/src/plotcontrolpanel.h
--- a/src/plotcontrolpanel.h
+++ b/src/plotcontrolpanel.h
@@ -46,6 +46,8 @@ public:
bool xAxisAsIndex() const;
double xMax() const;
double xMin() const;
+ /// Returns the plot width adjusted for x axis scaling.
+ double plotWidth() const;
void setChannelInfoModel(ChannelInfoModel* model);
@@ -58,6 +60,7 @@ signals:
void numOfSamplesChanged(int value);
void yScaleChanged(bool autoScaled, double yMin = 0, double yMax = 1);
void xScaleChanged(bool asIndex, double xMin = 0, double xMax = 1);
+ void plotWidthChanged(double width);
private:
Ui::PlotControlPanel *ui;
@@ -80,6 +83,7 @@ private slots:
void onRangeSelected();
void onIndexChecked(bool checked);
void onXScaleChanged();
+ void onPlotWidthChanged();
};
#endif // PLOTCONTROLPANEL_H
diff --git a/src/plotcontrolpanel.ui b/src/plotcontrolpanel.ui
--- a/src/plotcontrolpanel.ui
+++ b/src/plotcontrolpanel.ui
@@ -7,7 +7,7 @@
0
0
706
- 187
+ 195
@@ -132,15 +132,30 @@
-
+
+
+
- Number Of Samples:
+ Buffer Size:
-
+
+
+ 100
+ 0
+
+
+
+
+ 100
+ 16777215
+
+
- length of X axis
+ Length of acquisition as number of samples
false
@@ -149,14 +164,14 @@
2
- 1000000
+ 10000000
1000
- -
+
-
Index as X AXis
@@ -166,7 +181,7 @@
- -
+
-
-
@@ -237,7 +252,7 @@
- -
+
-
Auto Scale Y Axis
@@ -247,7 +262,7 @@
- -
+
-
-
@@ -318,16 +333,57 @@
- -
+
-
Select Range Preset:
- -
+
-
+ -
+
+
+
+
+
+ Plot Width:
+
+
+
+ -
+
+
+
+ 100
+ 0
+
+
+
+
+ 100
+ 16777215
+
+
+
+ Width of X axis as maximum number of samples that are shown in plot
+
+
+ false
+
+
+ 2
+
+
+ 100000
+
+
+ 1000
+
+
+
-
diff --git a/src/plotmanager.cpp b/src/plotmanager.cpp
--- a/src/plotmanager.cpp
+++ b/src/plotmanager.cpp
@@ -46,6 +46,7 @@ PlotManager::PlotManager(QWidget* plotAr
isDemoShown = false;
_infoModel = infoModel;
_numOfSamples = 1;
+ _plotWidth = 1;
showSymbols = Plot::ShowSymbolsAuto;
emptyPlot = NULL;
@@ -316,6 +317,7 @@ Plot* PlotManager::addPlotWidget()
plot->setNumOfSamples(_numOfSamples);
plot->setSymbols(showSymbols);
+ plot->setPlotWidth(_plotWidth);
if (_xAxisAsIndex)
{
plot->setXAxis(0, _numOfSamples);
@@ -542,6 +544,15 @@ void PlotManager::setNumOfSamples(unsign
}
}
+void PlotManager::setPlotWidth(double width)
+{
+ _plotWidth = width;
+ for (auto plot : plotWidgets)
+ {
+ plot->setPlotWidth(width);
+ }
+}
+
PlotViewSettings PlotManager::viewSettings() const
{
return PlotViewSettings(
diff --git a/src/plotmanager.h b/src/plotmanager.h
--- a/src/plotmanager.h
+++ b/src/plotmanager.h
@@ -88,6 +88,8 @@ public slots:
void flashSnapshotOverlay();
/// Should be called to update zoom base
void setNumOfSamples(unsigned value);
+ /// Maximum width of X axis (limit of hscroll)
+ void setPlotWidth(double width);
private:
bool isMulti;
@@ -106,6 +108,7 @@ private:
double _xMin;
double _xMax;
unsigned _numOfSamples;
+ double _plotWidth;
Plot::ShowSymbols showSymbols;
// menu actions
diff --git a/src/scrollzoomer.cpp b/src/scrollzoomer.cpp
--- a/src/scrollzoomer.cpp
+++ b/src/scrollzoomer.cpp
@@ -42,6 +42,10 @@ ScrollZoomer::ScrollZoomer( QWidget *can
d_vScrollData( NULL ),
d_inZoom( false )
{
+ xMin = 0.;
+ xMax = 10000.;
+ hViewSize = 10000;
+
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
d_alignCanvasToScales[ axis ] = false;
@@ -50,6 +54,8 @@ ScrollZoomer::ScrollZoomer( QWidget *can
d_hScrollData = new ScrollData;
d_vScrollData = new ScrollData;
+ hscrollmove = false;
+ vscrollmove = false;
}
ScrollZoomer::~ScrollZoomer()
@@ -59,6 +65,37 @@ ScrollZoomer::~ScrollZoomer()
delete d_hScrollData;
}
+void ScrollZoomer::setXLimits(double min, double max)
+{
+ xMin = min;
+ xMax = max;
+ setZoomBase();
+}
+
+void ScrollZoomer::setHViewSize(double size)
+{
+ hViewSize = size;
+ setZoomBase();
+}
+
+void ScrollZoomer::setZoomBase(bool doReplot)
+{
+ QwtPlotZoomer::setZoomBase(doReplot);
+ auto zb = zoomBase();
+ auto zs = zoomStack();
+ zb.setRight(xMax);
+ if ((xMax - xMin) < hViewSize)
+ {
+ zb.setLeft(xMin);
+ }
+ else
+ {
+ zb.setLeft(xMax-hViewSize);
+ }
+ zs[0] = zb;
+ setZoomStack(zs);
+}
+
void ScrollZoomer::rescale()
{
QwtScaleWidget *xScale = plot()->axisWidget( xAxis() );
@@ -112,7 +149,45 @@ void ScrollZoomer::rescale()
}
}
- QwtPlotZoomer::rescale();
+ // NOTE: Below snippet is copied from QwtPlotZoomer::rescale() just so that
+ // we can refrain from updating y axis when moving horizontal scrollbar, so
+ // that auto-scale isn't disrupted. Also we don't want to jump around in
+ // x-axis when moving vertical scroll.
+ {
+ QwtPlot *plt = plot();
+ if ( !plt )
+ return;
+
+ const QRectF &rect = zoomStack()[zoomRectIndex()];
+ if ( rect != scaleRect() )
+ {
+ const bool doReplot = plt->autoReplot();
+ plt->setAutoReplot( false );
+
+ if (!vscrollmove)
+ {
+ double x1 = rect.left();
+ double x2 = rect.right();
+ if ( !plt->axisScaleDiv( xAxis() ).isIncreasing() )
+ qSwap( x1, x2 );
+
+ plt->setAxisScale( xAxis(), x1, x2 );
+ }
+
+ if (!hscrollmove)
+ {
+ double y1 = rect.top();
+ double y2 = rect.bottom();
+ if ( !plt->axisScaleDiv( yAxis() ).isIncreasing() )
+ qSwap( y1, y2 );
+
+ plt->setAxisScale( yAxis(), y1, y2 );
+
+ plt->setAutoReplot( doReplot );
+ }
+ plt->replot();
+ }
+ }
updateScrollBars();
}
@@ -237,6 +312,11 @@ bool ScrollZoomer::eventFilter( QObject
layoutScrollBars( rect );
break;
}
+ case QEvent::Show:
+ {
+ layoutScrollBars( canvas()->contentsRect() );
+ break;
+ }
case QEvent::ChildRemoved:
{
const QObject *child =
@@ -265,8 +345,8 @@ bool ScrollZoomer::needScrollBar( Qt::Or
if ( orientation == Qt::Horizontal )
{
mode = d_hScrollData->mode;
- baseMin = zoomBase().left();
- baseMax = zoomBase().right();
+ baseMin = xMin;
+ baseMax = xMax;
zoomMin = zoomRect().left();
zoomMax = zoomRect().right();
}
@@ -323,7 +403,7 @@ void ScrollZoomer::updateScrollBars()
ScrollBar *sb = scrollBar( Qt::Horizontal );
sb->setPalette( plot()->palette() );
sb->setInverted( !plot()->axisScaleDiv( xAxis ).isIncreasing() );
- sb->setBase( zoomBase().left(), zoomBase().right() );
+ sb->setBase( xMin, xMax );
sb->moveSlider( zoomRect().left(), zoomRect().right() );
if ( !sb->isVisibleTo( canvas() ) )
@@ -462,9 +542,17 @@ void ScrollZoomer::scrollBarMoved(
Q_UNUSED( max );
if ( o == Qt::Horizontal )
+ {
+ hscrollmove = true;
moveTo( QPointF( min, zoomRect().top() ) );
+ hscrollmove = false;
+ }
else
+ {
+ vscrollmove = true;
moveTo( QPointF( zoomRect().left(), min ) );
+ vscrollmove = false;
+ }
Q_EMIT zoomed( zoomRect() );
}
@@ -487,3 +575,30 @@ int ScrollZoomer::oppositeAxis( int axis
return axis;
}
+
+void ScrollZoomer::moveTo( const QPointF &pos )
+{
+ // QwtPlotZoomer::moveTo(pos);
+ // return;
+
+ double x = pos.x();
+ double y = pos.y();
+
+ if ( x < xMin )
+ x = xMin;
+ if ( x > xMax - zoomRect().width() )
+ x = xMax - zoomRect().width();
+
+ if ( y < zoomBase().top() )
+ y = zoomBase().top();
+ if ( y > zoomBase().bottom() - zoomRect().height() )
+ y = zoomBase().bottom() - zoomRect().height();
+
+ if ( x != zoomRect().left() || y != zoomRect().top() )
+ {
+ auto zs = zoomStack();
+ zs[zoomRectIndex()].moveTo( x, y );
+ setZoomStack(zs, zoomRectIndex());
+ rescale();
+ }
+}
diff --git a/src/scrollzoomer.h b/src/scrollzoomer.h
--- a/src/scrollzoomer.h
+++ b/src/scrollzoomer.h
@@ -50,8 +50,14 @@ public:
virtual bool eventFilter( QObject *, QEvent * );
+ void setXLimits(double min, double max);
+ void setHViewSize(double size);
+ virtual void setZoomBase(bool doReplot = true);
virtual void rescale();
+public Q_SLOTS:
+ virtual void moveTo( const QPointF & );
+
protected:
virtual ScrollBar *scrollBar( Qt::Orientation );
virtual void updateScrollBars();
@@ -61,6 +67,10 @@ private Q_SLOTS:
void scrollBarMoved( Qt::Orientation o, double min, double max );
private:
+ QRectF d_limits;
+ double xMin, xMax;
+ double hViewSize;
+
bool needScrollBar( Qt::Orientation ) const;
int oppositeAxis( int ) const;
@@ -71,6 +81,8 @@ private:
bool d_inZoom;
bool d_alignCanvasToScales[ QwtPlot::axisCnt ];
+ bool hscrollmove;
+ bool vscrollmove;
};
#endif
diff --git a/src/setting_defines.h b/src/setting_defines.h
--- a/src/setting_defines.h
+++ b/src/setting_defines.h
@@ -79,6 +79,7 @@ const char SG_Channels_Visible[] = "visi
// plot settings keys
const char SG_Plot_NumOfSamples[] = "numOfSamples";
+const char SG_Plot_PlotWidth[] = "plotWidth";
const char SG_Plot_IndexAsX[] = "indexAsX";
const char SG_Plot_XMax[] = "xMax";
const char SG_Plot_XMin[] = "xMin";