Files
qwt/examples/sinusplot/main.cpp
2023-10-31 09:22:42 +01:00

226 lines
6.0 KiB
C++

/*****************************************************************************
* Qwt Examples - Copyright (C) 2002 Uwe Rathmann
* This file may be used under the terms of the 3-clause BSD License
*****************************************************************************/
#include <QwtPlot>
#include <QwtPlotMarker>
#include <QwtPlotCurve>
#include <QwtLegend>
#include <QwtSyntheticPointData>
#include <QwtPlotCanvas>
#include <QwtPlotPanner>
#include <QwtPlotMagnifier>
#include <QwtSymbol>
#include <QwtText>
#include <QwtMath>
#include <QApplication>
#include <QPainterPath>
#include <QLayout>
//-----------------------------------------------------------------
// A simple example which shows how to use QwtPlot connected
// to a data class without any storage, calculating each values
// on the fly.
//-----------------------------------------------------------------
namespace
{
class FunctionData : public QwtSyntheticPointData
{
public:
FunctionData( double( *fy )( double ) )
: QwtSyntheticPointData( 100 ),
m_y( fy )
{
}
virtual double y( double x ) const QWT_OVERRIDE
{
return m_y( x );
}
private:
double ( * m_y )( double );
};
class ArrowSymbol : public QwtSymbol
{
public:
ArrowSymbol()
{
QPen pen( Qt::black, 0 );
pen.setJoinStyle( Qt::MiterJoin );
setPen( pen );
setBrush( Qt::red );
QPainterPath path;
path.moveTo( 0, 8 );
path.lineTo( 0, 5 );
path.lineTo( -3, 5 );
path.lineTo( 0, 0 );
path.lineTo( 3, 5 );
path.lineTo( 0, 5 );
QTransform transform;
transform.rotate( -30.0 );
path = transform.map( path );
setPath( path );
setPinPoint( QPointF( 0, 0 ) );
setSize( 10, 14 );
}
};
class Plot : public QwtPlot
{
public:
Plot( QWidget* parent = NULL );
protected:
virtual void resizeEvent( QResizeEvent* ) QWT_OVERRIDE;
private:
void populate();
void updateGradient();
};
}
Plot::Plot( QWidget* parent )
: QwtPlot( parent )
{
setAutoFillBackground( true );
setPalette( QPalette( QColor( 165, 193, 228 ) ) );
updateGradient();
setTitle( "A Simple QwtPlot Demonstration" );
insertLegend( new QwtLegend(), QwtPlot::RightLegend );
// axes
setAxisTitle( QwtAxis::XBottom, "x -->" );
setAxisScale( QwtAxis::XBottom, 0.0, 10.0 );
setAxisTitle( QwtAxis::YLeft, "y -->" );
setAxisScale( QwtAxis::YLeft, -1.0, 1.0 );
// canvas
QwtPlotCanvas* canvas = new QwtPlotCanvas();
canvas->setLineWidth( 1 );
canvas->setFrameStyle( QFrame::Box | QFrame::Plain );
canvas->setBorderRadius( 15 );
QPalette canvasPalette( Qt::white );
canvasPalette.setColor( QPalette::WindowText, QColor( 133, 190, 232 ) );
canvas->setPalette( canvasPalette );
setCanvas( canvas );
// panning with the left mouse button
( void ) new QwtPlotPanner( canvas );
// zoom in/out with the wheel
( void ) new QwtPlotMagnifier( canvas );
populate();
}
void Plot::populate()
{
// Insert new curves
QwtPlotCurve* cSin = new QwtPlotCurve( "y = sin(x)" );
cSin->setRenderHint( QwtPlotItem::RenderAntialiased );
cSin->setLegendAttribute( QwtPlotCurve::LegendShowLine, true );
cSin->setPen( Qt::red );
cSin->attach( this );
QwtPlotCurve* cCos = new QwtPlotCurve( "y = cos(x)" );
cCos->setRenderHint( QwtPlotItem::RenderAntialiased );
cCos->setLegendAttribute( QwtPlotCurve::LegendShowLine, true );
cCos->setPen( Qt::blue );
cCos->attach( this );
// Create sin and cos data
cSin->setData( new FunctionData( std::sin ) );
cCos->setData( new FunctionData( std::cos ) );
// Insert markers
// ...a horizontal line at y = 0...
QwtPlotMarker* mY = new QwtPlotMarker();
mY->setLabel( QString::fromLatin1( "y = 0" ) );
mY->setLabelAlignment( Qt::AlignRight | Qt::AlignTop );
mY->setLineStyle( QwtPlotMarker::HLine );
mY->setYValue( 0.0 );
mY->attach( this );
// ...a vertical line at x = 2 * pi
QwtPlotMarker* mX = new QwtPlotMarker();
mX->setLabel( QString::fromLatin1( "x = 2 pi" ) );
mX->setLabelAlignment( Qt::AlignLeft | Qt::AlignBottom );
mX->setLabelOrientation( Qt::Vertical );
mX->setLineStyle( QwtPlotMarker::VLine );
mX->setLinePen( Qt::black, 0, Qt::DashDotLine );
mX->setXValue( 2.0 * M_PI );
mX->attach( this );
const double x = 7.7;
// an arrow at a specific position
QwtPlotMarker* mPos = new QwtPlotMarker( "Marker" );
mPos->setRenderHint( QwtPlotItem::RenderAntialiased, true );
mPos->setItemAttribute( QwtPlotItem::Legend, true );
mPos->setSymbol( new ArrowSymbol() );
mPos->setValue( QPointF( x, std::sin( x ) ) );
mPos->setLabel( QString( "x = %1" ).arg( x ) );
mPos->setLabelAlignment( Qt::AlignRight | Qt::AlignBottom );
mPos->attach( this );
}
void Plot::updateGradient()
{
QPalette pal = palette();
const QColor buttonColor = pal.color( QPalette::Button );
QLinearGradient gradient( rect().topLeft(), rect().bottomLeft() );
gradient.setColorAt( 0.0, Qt::white );
gradient.setColorAt( 0.7, buttonColor );
gradient.setColorAt( 1.0, buttonColor );
pal.setBrush( QPalette::Window, gradient );
setPalette( pal );
}
void Plot::resizeEvent( QResizeEvent* event )
{
QwtPlot::resizeEvent( event );
// Qt 4.7.1: QGradient::StretchToDeviceMode is buggy on X11
updateGradient();
}
int main( int argc, char* argv[] )
{
QApplication app( argc, argv );
Plot* plot = new Plot();
// We put a dummy widget around to have
// so that Qt paints a widget background
// when resizing
QWidget window;
QHBoxLayout* layout = new QHBoxLayout( &window );
layout->setContentsMargins( 0, 0, 0, 0 );
layout->addWidget( plot );
window.resize( 600, 400 );
window.show();
return app.exec();
}