#include "plot.h"
#include "curvedata.h"
#include "signaldata.h"
#include <qwt_plot_canvas.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_directpainter.h>
#include <qwt_curve_fitter.h>
#include <qwt_painter.h>
{
public:
{
// The backing store is important, when working with widget
// overlays ( f.e rubberbands for zooming ).
// Here we don't have them and the internal
// backing store of QWidget is good enough.
setBorderRadius( 10 );
{
#if QT_VERSION < 0x050000
// Even if not liked by the Qt development, Qt::WA_PaintOutsidePaintEvent
// works on X11. This has a nice effect on the performance.
setAttribute( Qt::WA_PaintOutsidePaintEvent, true );
#endif
// Disabling the backing store of Qt improves the performance
// for the direct painter even more, but the canvas becomes
// a native window of the window system, receiving paint events
// for resize and expose operations. Those might be expensive
// when there are many points and the backing store of
// the canvas is disabled. So in this application
// we better don't disable both backing stores.
{
setAttribute( Qt::WA_PaintOnScreen, true );
setAttribute( Qt::WA_NoSystemBackground, true );
}
}
}
};
plot( parent ),
d_paintedPoints( 0 ),
x_interval( 0.0, 100000.0 ),
y_interval( 0.0, 2000.0 )
{
d_directPainter = new QwtPlotDirectPainter();
plot->setAutoReplot( false );
plot->setCanvas( new Canvas() );
plot
->setAxisScale
( QwtPlot::xBottom, x_interval.
minValue(), x_interval.
maxValue() );
plot
->setAxisScale
( QwtPlot::yLeft, y_interval.
minValue(), y_interval.
maxValue() );
// d_curve->setPen( plot->canvas()->palette().color( QPalette::WindowText ) );
d_curve
->setRenderHint
( QwtPlotItem::RenderAntialiased,
true );
d_curve
->setPaintAttribute
( QwtPlotCurve::ClipPolygons,
false );
d_curve->setData( new CurveData() );
d_curve->attach( plot );
}
Plot::~Plot()
{
delete d_directPainter;
}
void Plot::replot()
{
CurveData *data = static_cast<CurveData *>( d_curve->data() );
data->values().lock();
plot->replot();
d_paintedPoints = data->size();
data->values().unlock();
}
void Plot::setXinterval( double min, double max )
{
x_interval.setMaxValue( max );
x_interval.setMinValue( min );
plot
->setAxisScale
( QwtPlot::xBottom,
x_interval.minValue(), x_interval.maxValue() );
replot();
}
void Plot::setYinterval( double min, double max )
{
y_interval.setMaxValue( max );
y_interval.setMinValue( min );
plot
->setAxisScale
( QwtPlot::yLeft,
y_interval.minValue(), y_interval.maxValue() );
replot();
}
void Plot
::setPen(const QColor &color, qreal width, Qt
::PenStyle style
) {
d_curve->setPen(color, width, style);
}
void Plot::updateCurve()
{
CurveData *data = static_cast<CurveData *>( d_curve->data() );
data->values().lock();
const int numPoints = data->size();
if ( numPoints > d_paintedPoints )
{
const bool doClip = !plot->canvas()->testAttribute( Qt::WA_PaintOnScreen );
if ( doClip )
{
/*
Depending on the platform setting a clip might be an important
performance issue. F.e. for Qt Embedded this reduces the
part of the backing store that has to be copied out - maybe
to an unaccelerated frame buffer device.
*/
const QwtScaleMap xMap
= plot
->canvasMap
( d_curve
->xAxis
() );
const QwtScaleMap yMap
= plot
->canvasMap
( d_curve
->yAxis
() );
QRectF br
= qwtBoundingRect
( *data,
d_paintedPoints - 1, numPoints - 1 );
d_directPainter->setClipRegion( clipRect );
}
d_directPainter->drawSeries( d_curve,
d_paintedPoints - 1, numPoints - 1 );
d_paintedPoints = numPoints;
}
data->values().unlock();
}