Sharing zoom with multiple plots
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?
Re: Sharing zoom with multiple plots
I experimented with two plots...
I subclassed QwtPlotZoomer (see below)
Code:
{
public:
{
}
virtual void zoom
( const QRectF & 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:
Quote:
Clients of custom plot do...
Error...
This should read Clients of Zoomer do ...
Re: Sharing zoom with multiple plots
Maybe a more general approach would be to connect to the QwtScaleWidget::scaleDivChanged() signal.
Uwe
Re: Sharing zoom with multiple plots
Quote:
Maybe a more general approach would be to connect to the QwtScaleWidget::scaleDivChanged() signal.
Absolutely...
Code:
{
Q_OBJECT
public:
{
}
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.