/***************************************************************************** * Qwt Examples - Copyright (C) 2002 Uwe Rathmann * This file may be used under the terms of the 3-clause BSD License *****************************************************************************/ #include "Plot.h" #include "CircularBuffer.h" #include "Settings.h" #include #include #include #include #include #include #include #include #ifndef QWT_NO_OPENGL #if QT_VERSION >= 0x050400 #define USE_OPENGL_WIDGET 1 #endif #if USE_OPENGL_WIDGET #include #else #include #endif #endif static double wave( double x ) { const double period = 1.0; const double c = 5.0; double v = std::fmod( x, period ); const double amplitude = qAbs( x - qRound( x / c ) * c ) / ( 0.5 * c ); v = amplitude * std::sin( v / period * 2 * M_PI ); return v; } static double noise( double ) { return 2.0 * ( qwtRand() / ( static_cast< double >( RAND_MAX ) + 1 ) ) - 1.0; } Plot::Plot( QWidget* parent ) : QwtPlot( parent ) , m_interval( 10.0 ) // seconds , m_timerId( -1 ) { // Assign a title setTitle( "Testing Refresh Rates" ); QwtPlotCanvas* canvas = new QwtPlotCanvas(); canvas->setFrameStyle( QFrame::Box | QFrame::Plain ); canvas->setLineWidth( 1 ); canvas->setPalette( Qt::white ); setCanvas( canvas ); alignScales(); // Insert grid m_grid = new QwtPlotGrid(); m_grid->attach( this ); // Insert curve m_curve = new QwtPlotCurve( "Data Moving Right" ); m_curve->setPen( Qt::black ); m_curve->setData( new CircularBuffer( m_interval, 10 ) ); m_curve->attach( this ); // Axis setAxisTitle( QwtAxis::XBottom, "Seconds" ); setAxisScale( QwtAxis::XBottom, -m_interval, 0.0 ); setAxisTitle( QwtAxis::YLeft, "Values" ); setAxisScale( QwtAxis::YLeft, -1.0, 1.0 ); m_elapsedTimer.start(); setSettings( m_settings ); } // // Set a plain canvas frame and align the scales to it // void Plot::alignScales() { // The code below shows how to align the scales to // the canvas frame, but is also a good example demonstrating // why the spreaded API needs polishing. for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ ) { QwtScaleWidget* scaleWidget = axisWidget( axisPos ); if ( scaleWidget ) scaleWidget->setMargin( 0 ); QwtScaleDraw* scaleDraw = axisScaleDraw( axisPos ); if ( scaleDraw ) scaleDraw->enableComponent( QwtAbstractScaleDraw::Backbone, false ); } plotLayout()->setAlignCanvasToScales( true ); } void Plot::setSettings( const Settings& s ) { if ( m_timerId >= 0 ) killTimer( m_timerId ); m_timerId = startTimer( s.updateInterval ); m_grid->setPen( s.grid.pen ); m_grid->setVisible( s.grid.pen.style() != Qt::NoPen ); CircularBuffer* buffer = static_cast< CircularBuffer* >( m_curve->data() ); if ( s.curve.numPoints != buffer->size() || s.curve.functionType != m_settings.curve.functionType ) { switch( s.curve.functionType ) { case Settings::Wave: buffer->setFunction( wave ); break; case Settings::Noise: buffer->setFunction( noise ); break; default: buffer->setFunction( NULL ); } buffer->fill( m_interval, s.curve.numPoints ); } m_curve->setPen( s.curve.pen ); m_curve->setBrush( s.curve.brush ); m_curve->setPaintAttribute( QwtPlotCurve::ClipPolygons, s.curve.paintAttributes & QwtPlotCurve::ClipPolygons ); m_curve->setPaintAttribute( QwtPlotCurve::FilterPoints, s.curve.paintAttributes & QwtPlotCurve::FilterPoints ); m_curve->setPaintAttribute( QwtPlotCurve::FilterPointsAggressive, s.curve.paintAttributes & QwtPlotCurve::FilterPointsAggressive ); m_curve->setRenderHint( QwtPlotItem::RenderAntialiased, s.curve.renderHint & QwtPlotItem::RenderAntialiased ); #ifndef QWT_NO_OPENGL if ( s.canvas.openGL ) { #if USE_OPENGL_WIDGET QwtPlotOpenGLCanvas* plotCanvas = qobject_cast< QwtPlotOpenGLCanvas* >( canvas() ); if ( plotCanvas == NULL ) { plotCanvas = new QwtPlotOpenGLCanvas(); plotCanvas->setPalette( QColor( "NavajoWhite" ) ); plotCanvas->setPalette( QColor( "khaki" ) ); plotCanvas->setFrameStyle( QFrame::Box | QFrame::Plain ); plotCanvas->setLineWidth( 1 ); setCanvas( plotCanvas ); } #else QwtPlotGLCanvas* plotCanvas = qobject_cast< QwtPlotGLCanvas* >( canvas() ); if ( plotCanvas == NULL ) { plotCanvas = new QwtPlotGLCanvas(); plotCanvas->setPalette( QColor( "khaki" ) ); plotCanvas->setFrameStyle( QFrame::Box | QFrame::Plain ); plotCanvas->setLineWidth( 1 ); setCanvas( plotCanvas ); } #endif } else #endif { QwtPlotCanvas* plotCanvas = qobject_cast< QwtPlotCanvas* >( canvas() ); if ( plotCanvas == NULL ) { plotCanvas = new QwtPlotCanvas(); plotCanvas->setFrameStyle( QFrame::Box | QFrame::Plain ); plotCanvas->setLineWidth( 1 ); plotCanvas->setPalette( Qt::white ); setCanvas( plotCanvas ); } plotCanvas->setAttribute( Qt::WA_PaintOnScreen, s.canvas.paintOnScreen ); plotCanvas->setPaintAttribute( QwtPlotCanvas::BackingStore, s.canvas.useBackingStore ); plotCanvas->setPaintAttribute( QwtPlotCanvas::ImmediatePaint, s.canvas.immediatePaint ); } QwtPainter::setPolylineSplitting( s.curve.lineSplitting ); m_settings = s; } void Plot::timerEvent( QTimerEvent* ) { CircularBuffer* buffer = static_cast< CircularBuffer* >( m_curve->data() ); buffer->setReferenceTime( m_elapsedTimer.elapsed() / 1000.0 ); if ( m_settings.updateType == Settings::RepaintCanvas ) { // the axes in this example doesn't change. So all we need to do // is to repaint the canvas. QMetaObject::invokeMethod( canvas(), "replot", Qt::DirectConnection ); } else { replot(); } } #include "moc_Plot.cpp"