Make a partial replot using reimplemented QwtPlot::replot()
Hello!
Is there a way for doing a partial replot using a reimplemented QwtPlot::replot()? This partial replot would be essentially to tell which area of the graph I want to be reploted instead of the entire canvas.
I noticed the code for QwtPlot::replot() in 6.1.0 is:
Code:
{
bool doAutoReplot = autoReplot();
setAutoReplot( false );
updateAxes();
/*
Maybe the layout needs to be updated, because of changed
axes labels. We need to process them here before painting
to avoid that scales and canvas get out of sync.
*/
if ( d_data->canvas )
{
d_data->canvas, "replot", Qt::DirectConnection );
if ( !ok )
{
// fallback, when canvas has no a replot method
d_data->canvas->update( d_data->canvas->contentsRect() );
}
}
setAutoReplot( doAutoReplot );
}
When I tried, the problems arised when considering the "replot" method of the canvas:
Code:
{
invalidateBackingStore();
repaint( contentsRect() );
else
update( contentsRect() );
}
If I understood correctly, I'll have to create a new QwtPlotCanvas for my custom QwtPlot with a reimplemented replot() method in which instead of using contentsRect(), I'll use a QRect with customized form previously set by a new method.
Is this all ok or did I miss something?
Thanks,
Momergil
Re: Make a partial replot using reimplemented QwtPlot::replot()
Assuming that you have new curve points in the area [x1,x2] ( in plot coordinates ) and the backingstore ( QwtPlotCanvas::BackingStore ) of the canvas is disabled:
Code:
void updatePlot
( QwtPlot* plot,
double x1,
double x2
) {
const int l = xMap.transform( x1 );
const int r = xMap.transform( x2 );
const QRect cr
= plot
->canvas
()->contentsRect
();
plot->canvas()->repaint( l, cr.y(), r - l, cr,height() );
}
The rectangle you have passed to the paint event will end up as clip region of the painter and you could overload QwtPlot::drawItems():
Code:
virtual void YourPlot
::drawItems( QPainter *painter,
const QRectF &canvasRect,
{
const QRectF rect
= painter
->clipRegion
().
boundingRect();
// rect should have been filled with the background of the canvas
// before. When you have other plot items ( f.e. a grid ) you have to restore
// them for rect() too.
...
double x1 = maps[curve->xAxis()].invTransform( rect.x() );
double x2 = maps[curve->xAxis()].invTransform( rect.x() + rect.width() );
// find the segment of your curve for [x1, x2]
// f.e. using qwtUpperSampleIndex() ?
int from = ...;
int to = ...
curve->drawSeries( painter,
maps[curve->xAxis()], maps[curve->yAxis()], canvasRect, from, to );
}
You could try to use QwtPlotGLCanvas, that offers hardware acceleration and its limitations should be no big issue for your type of application. For QwtPlotCanvas ( = anything derived from QWidget ) there is only Qt4/X11 ( native graphicssystem ) where you have hardware acceleration.
Uwe