View Full Version : Sharing zoom with multiple plots
SeanM
7th February 2014, 17:14
I've got multiple plots that are aligned vertically, displaying data samples that share a common time scale. I've implemented a zoom feature using the mousewheel to zoom in/out based on current cursor position and that works great on the individual plot. What I'd like to do is sync all the plots together so that when a zoom happens on one plot, the others all zoom the same way, ensuring the plots all stay in sync.
Any thoughts on the best way to do that? Right now I maintain an internal zoom stack, so I could emit a signal that propagates that zoom stack out to the others. I'm not sure if that's the cleanest way to do it though?
Cah
9th February 2014, 00:19
I experimented with two plots...
I subclassed QwtPlotZoomer (see below)
class Zoomer : public QwtPlotZoomer
{
public:
Zoomer( QwtPlot* otherPlot, QWidget*w):QwtPlotZoomer(w), _otherPlot(otherPlot)
{
}
virtual void zoom( const QRectF & rc)
{
QwtPlotZoomer::zoom(rc);
QwtInterval intv = plot()->axisInterval (QwtPlot::xBottom);
_otherPlot->setAxisScale(QwtPlot::xBottom, intv.minValue(), intv.maxValue());
intv = plot()->axisInterval (QwtPlot::yLeft);
_otherPlot->setAxisScale(QwtPlot::yLeft, intv.minValue(), intv.maxValue());
_otherPlot->replot();
}
private:
QwtPlot* _otherPlot; //This could be list of plots
};
Now the custom zoomer is aware of _otherPlot whose scale is adjusted should any zooming occur.
Clients of custom plot do...
QwtPlot * plot = new QwtPlot(this);
QwtPlot * plot1 = new QwtPlot(this);
...
...
Zoomer* z = new Zoomer(plot1, plot->canvas());
Zoomer* z1 = new Zoomer(plot, plot1->canvas());
I did not check this thoroughly.
Added after 1 48 minutes:
Clients of custom plot do... Error...
This should read Clients of Zoomer do ...
Uwe
9th February 2014, 08:55
Maybe a more general approach would be to connect to the QwtScaleWidget::scaleDivChanged() signal.
Uwe
Cah
9th February 2014, 14:51
Maybe a more general approach would be to connect to the QwtScaleWidget::scaleDivChanged() signal.
Absolutely...
class Plot: public QwtPlot
{
Q_OBJECT
public:
Plot( QWidget * parent= NULL):QwtPlot(parent)
{
}
private slots:
void scaleDivChangedSlot ()
{
QwtPlot* plt = static_cast<QwtPlot*>((sender())->parent());
QwtInterval intv = plt->axisInterval (QwtPlot::xBottom);
this->setAxisScale(QwtPlot::xBottom, intv.minValue(), intv.maxValue());
intv = plt->axisInterval (QwtPlot::yLeft);
this->setAxisScale(QwtPlot::yLeft, intv.minValue(), intv.maxValue());
this->replot();
}
};
Plot* plot = new Plot;
Plot* plot1 = new Plot;
QObject::connect(((QObject*)plot->axisWidget(QwtPlot::xBottom)) , SIGNAL(scaleDivChanged () ), plot1, SLOT(scaleDivChangedSlot () ));
QObject::connect(((QObject*)plot1->axisWidget(QwtPlot::xBottom)) , SIGNAL(scaleDivChanged () ), plot, SLOT(scaleDivChangedSlot () ));
With this arrangement QwtPlotZoomer, QwtPlotMagnifier and QwtPlotPanner can operate and keep things in sync.
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.