PDA

View Full Version : QwtPlotZoomer not to change the yAxis scale



dontgonearthecastle
7th January 2013, 10:39
Hello!
I'm using ScrollZoomer class from realtime example. I wanted to zoom in and out by pushbuttons, so I made something like:

QRectF rectangle = m_zoomer->zoomStack().top();
rectangle.adjust(rectangle.width() * 0.1, 0, -(rectangle.width() * 0.1), 0);
m_zoomer->zoom(rectangle);

I only want to zoom in x-direction, so the yAxis to stay untouched. This happens to work fine, but the problem comes up when I try to set yAxis to solid minimum and maximum. I call
setAxisScale() with good parameters after I attach curves and it looks ok at the first glance. But after hitting any "zoom" button the plot is rescaled and yAxis scale changes. I tried to call setAxisAutoScale(false) for yAxis in the plot constructor, but this makes that after I hit a zoom button, yAxis scale seems to be reseted to min: 0, max: 1000 :/.
It seems like it's a minor problem, but only when one knows where to look for - any ideas?
Thanks in advance :)

Uwe
7th January 2013, 12:18
Forget QwtPlotZoomer - it has nothing to do with your situation. All you need to do is to implement slots for zoom in/out that calculate a new scale from the current scale ranges and to assign them with QwtPlot::setAxisScale() ( or QwtPlot::setAxisScaleDiv(), when you need to control the ticks in detail ).

Have a look at the implementation of QwtPlotMagnifier::rescale(), what should be pretty close to the code you need in your slots.

Uwe

dontgonearthecastle
8th January 2013, 20:10
Heh, I've overridden the zoom slots in my ScrollZoomer class to be like this:

void ScrollZoomer::zoom(const QRectF &rect)
{
QwtPlot *plt = plot();
QwtScaleDiv *div = plt->axisScaleDiv(QwtPlot::yLeft);
plt->setAxisScale(QwtPlot::yLeft, div->lowerBound(), div->upperBound());
plt->replot();
QwtPlotZoomer::zoom(rect);
}
(with zoom(int up) being exactly the same - of course with proper zoom slot called at the end)
and to be honest, I have no idea why, but it works fine! :) Unfortunately, replotting slows the whole thing down with bigger plots, but I guess there's no easy way out of it now :)
Thanks :)

Uwe
9th January 2013, 06:37
QwtPlotZoomer::zoom( rect ) also sets the scale and does a replot - so your code above has no effect beside that it slows down the operation significantly. Why don't you listen to me: QwtPlotZoomer has nothing to do with your use case.

Instead this is your code:


void zoomAxis( QwtPlot* plot, int axis, double factor )
{
const QwtScaleDiv &scaleDiv = plot->axisScaleDiv( axis );

const double center =
scaleDiv.lowerBound() + scaleDiv.range() / 2;
const double width_2 = scaleDiv.range() / 2 * factor;

plot->setAxisScale( axis, center - width_2, center + width_2 );
plot->replot();
}

When you want to zoom in/out more than one axis don't use the code above unmodified and take care that the replot is done only once.

Uwe

dontgonearthecastle
12th January 2013, 16:56
Hmm, I don't understand it still :/
As far as I know, code you suggest actually zooms the view - it's fine, but the problem is that scrollbars stay untouched. I guess this is why I stick to ScrollZoomer::zoom (being QwtPlotZoomer::zoom I guess) - it happens to manage scrollbars and other things fine. I don't know if I'm right, but with my code from the opening post I wanted just to feed the "nice working ScrollZoomer from realtime example" with the right zooming rectangle. That would leave me with ScrollZoomer code untouched because it's working fine for me. As far as I understand, your approach, Uwe, is a little bit different, right? I just thought it's going to work, when I get the idea when is the yLeft axis rescaled - I would stop it from rescaling and it will be it. Problem is: is that even possible? :)
Thank you for your patience anyways :)

Uwe
14th January 2013, 07:23
O.k. I missed that you are interested in the scroll bars - so back to your initial posting: 0.0 -> 1000.0 are the initial settings of a plot axis. Looks like the zoomBase of the zoomer is initialized with these values, what usually happens, when the zoomer gets initialized too to early.

You have 2 options:



attach the items ( that have an effect for autoscaling ) first
use QwtPlotZoomer::setZoomBase()


Uwe

dontgonearthecastle
14th January 2013, 08:43
Hah, should have known it was this easy :)
I moved setZoomBase line to be AFTER setting the axes scales (hmm... seems legit, right? :p). Now it's great! :)
Thank you very much, Uwe :)