9#include "qwt_polar_plot.h" 
   10#include "qwt_polar_canvas.h" 
   11#include "qwt_polar_layout.h" 
   12#include "qwt_painter.h" 
   13#include "qwt_scale_engine.h" 
   14#include "qwt_scale_div.h" 
   15#include "qwt_text_label.h" 
   16#include "qwt_round_scale_draw.h" 
   17#include "qwt_legend.h" 
   18#include "qwt_dyngrid_layout.h" 
   21#include <qpaintengine.h> 
   25static inline double qwtDistance(
 
   26    const QPointF& p1, 
const QPointF& p2 )
 
   28    double dx = p2.x() - p1.x();
 
   29    double dy = p2.y() - p1.y();
 
   30    return qSqrt( dx * dx + dy * dy );
 
   65class QwtPolarPlot::PrivateData
 
   75    ScaleData scaleData[QwtPolar::ScaleCount];
 
   76    QPointer< QwtTextLabel > titleLabel;
 
   77    QPointer< QwtPolarCanvas > canvas;
 
   78    QPointer< QwtAbstractLegend > legend;
 
  110    delete m_data->layout;
 
 
  120    if ( 
title != m_data->titleLabel->text().text() )
 
  122        m_data->titleLabel->setText( 
title );
 
  124            m_data->titleLabel->show();
 
  126            m_data->titleLabel->hide();
 
 
  136    if ( 
title != m_data->titleLabel->text() )
 
  138        m_data->titleLabel->setText( 
title );
 
  140            m_data->titleLabel->show();
 
  142            m_data->titleLabel->hide();
 
 
  149    return m_data->titleLabel->text();
 
 
  155    return m_data->titleLabel;
 
 
  161    return m_data->titleLabel;
 
 
  196    if ( 
legend != m_data->legend )
 
  198        if ( m_data->legend && m_data->legend->parent() == 
this )
 
  199            delete m_data->legend;
 
  203        if ( m_data->legend )
 
  213            if ( m_data->legend->parent() != 
this )
 
  214                m_data->legend->setParent( 
this );
 
 
  255    for ( QwtPolarItemIterator it = itmList.begin();
 
  256        it != itmList.end(); ++it )
 
 
  270    if ( plotItem == NULL )
 
 
  288    return m_data->legend;
 
 
  297    return m_data->legend;
 
 
  311    if ( brush != m_data->canvasBrush )
 
  313        m_data->canvasBrush = brush;
 
 
  324    return m_data->canvasBrush;
 
 
  344    m_data->autoReplot = enable;
 
 
  350    return m_data->autoReplot;
 
 
  370    if ( scaleId != QwtPolar::ScaleRadius )
 
  373    ScaleData& scaleData = m_data->scaleData[scaleId];
 
  374    if ( !scaleData.doAutoScale )
 
  376        scaleData.doAutoScale = 
true;
 
 
  388    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  391    return m_data->scaleData[scaleId].doAutoScale;
 
 
  403    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  406    maxMinor = qBound( 0, maxMinor, 100 );
 
  408    ScaleData& scaleData = m_data->scaleData[scaleId];
 
  410    if ( maxMinor != scaleData.maxMinor )
 
  412        scaleData.maxMinor = maxMinor;
 
  413        scaleData.isValid = 
false;
 
 
  425    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  428    return m_data->scaleData[scaleId].maxMinor;
 
 
  440    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  443    maxMajor = qBound( 1, maxMajor, 10000 );
 
  445    ScaleData& scaleData = m_data->scaleData[scaleId];
 
  446    if ( maxMajor != scaleData.maxMinor )
 
  448        scaleData.maxMajor = maxMajor;
 
  449        scaleData.isValid = 
false;
 
 
  462    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  465    return m_data->scaleData[scaleId].maxMajor;
 
 
  478    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  481    ScaleData& scaleData = m_data->scaleData[scaleId];
 
  485    delete scaleData.scaleEngine;
 
  488    scaleData.isValid = 
false;
 
 
  501    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  504    return m_data->scaleData[scaleId].scaleEngine;
 
 
  515    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  518    return m_data->scaleData[scaleId].scaleEngine;
 
 
  531    double min, 
double max, 
double stepSize )
 
  533    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  536    ScaleData& scaleData = m_data->scaleData[scaleId];
 
  538    scaleData.isValid = 
false;
 
  540    scaleData.minValue = min;
 
  541    scaleData.maxValue = max;
 
  542    scaleData.stepSize = stepSize;
 
  543    scaleData.doAutoScale = 
false;
 
 
  556    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  559    ScaleData& scaleData = m_data->scaleData[scaleId];
 
  562    scaleData.isValid = 
true;
 
  563    scaleData.doAutoScale = 
false;
 
 
  581    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  584    return &m_data->scaleData[scaleId].scaleDiv;
 
 
  600    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  603    return &m_data->scaleData[scaleId].scaleDiv;
 
 
  617    origin = ::fmod( origin, 2 * M_PI );
 
  618    if ( origin != m_data->azimuthOrigin )
 
  620        m_data->azimuthOrigin = origin;
 
 
  634    return m_data->azimuthOrigin;
 
 
  654    if ( 
zoomPos != m_data->zoomPos ||
 
 
  670    if ( m_data->zoomFactor != 1.0 || m_data->zoomPos.
isValid() )
 
  672        m_data->zoomFactor = 1.0;
 
 
  684    return m_data->zoomPos;
 
 
  693    return m_data->zoomFactor;
 
 
  713    return scaleMap( scaleId, pr.width() / 2.0 );
 
 
  732    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  741    if ( scaleId == QwtPolar::Azimuth )
 
  744            m_data->azimuthOrigin + 2 * M_PI );
 
 
  764    bool ok = QWidget::event( e );
 
  767        case QEvent::LayoutRequest:
 
  772        case QEvent::PolishRequest:
 
 
  786    QFrame::resizeEvent( e );
 
 
  790void QwtPolarPlot::initPlot( 
const QwtText& title )
 
  792    m_data = 
new PrivateData;
 
  796    text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
 
  799    m_data->titleLabel->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );
 
  800    if ( !text.isEmpty() )
 
  801        m_data->titleLabel->show();
 
  803        m_data->titleLabel->hide();
 
  807    m_data->autoReplot = 
false;
 
  808    m_data->canvasBrush = QBrush( Qt::white );
 
  810    for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  812        ScaleData& scaleData = m_data->scaleData[scaleId];
 
  814        if ( scaleId == QwtPolar::Azimuth )
 
  816            scaleData.minValue = 0.0;
 
  817            scaleData.maxValue = 360.0;
 
  818            scaleData.stepSize = 30.0;
 
  822            scaleData.minValue = 0.0;
 
  823            scaleData.maxValue = 1000.0;
 
  824            scaleData.stepSize = 0.0;
 
  827        scaleData.doAutoScale = 
true;
 
  829        scaleData.maxMinor = 5;
 
  830        scaleData.maxMajor = 8;
 
  832        scaleData.isValid = 
false;
 
  836    m_data->zoomFactor = 1.0;
 
  837    m_data->azimuthOrigin = 0.0;
 
  839    setSizePolicy( QSizePolicy::MinimumExpanding,
 
  840        QSizePolicy::MinimumExpanding );
 
  842    for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  849    if ( m_data->autoReplot )
 
 
  856    m_data->layout->
activate( 
this, contentsRect() );
 
  859    if ( m_data->titleLabel )
 
  861        if ( !m_data->titleLabel->text().isEmpty() )
 
  863            m_data->titleLabel->setGeometry( m_data->layout->
titleRect().toRect() );
 
  864            if ( !m_data->titleLabel->isVisible() )
 
  865                m_data->titleLabel->show();
 
  868            m_data->titleLabel->hide();
 
  871    if ( m_data->legend )
 
  873        if ( m_data->legend->isEmpty() )
 
  875            m_data->legend->hide();
 
  879            const QRectF legendRect = m_data->layout->
legendRect();
 
  880            m_data->legend->setGeometry( legendRect.toRect() );
 
  881            m_data->legend->show();
 
  885    m_data->canvas->setGeometry( m_data->layout->
canvasRect().toRect() );
 
 
  904    for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  907    m_data->canvas->invalidateBackingStore();
 
  908    m_data->canvas->repaint();
 
 
  916    return m_data->canvas;
 
 
  922    return m_data->canvas;
 
 
  931    const QRectF& canvasRect )
 const 
  933    const QRectF cr = canvasRect;
 
  936    const double radius = pr.width() / 2.0;
 
  938    if ( m_data->canvasBrush.style() != Qt::NoBrush )
 
  941        painter->setPen( Qt::NoPen );
 
  942        painter->setBrush( m_data->canvasBrush );
 
  944        if ( qwtDistance( pr.center(), cr.topLeft() ) < radius &&
 
  945            qwtDistance( pr.center(), cr.topRight() ) < radius &&
 
  946            qwtDistance( pr.center(), cr.bottomRight() ) < radius &&
 
  947            qwtDistance( pr.center(), cr.bottomLeft() ) < radius )
 
  953            painter->setRenderHint( QPainter::Antialiasing, 
true );
 
  960        scaleMap( QwtPolar::Azimuth, radius ),
 
  961        scaleMap( QwtPolar::Radius, radius ),
 
  962        pr.center(), radius, canvasRect );
 
 
  977    const QPointF& pole, 
double radius,
 
  978    const QRectF& canvasRect )
 const 
  980    const QRectF pr = 
plotRect( canvasRect );
 
  983    for ( QwtPolarItemIterator it = itmList.begin();
 
  984        it != itmList.end(); ++it )
 
  994            bool doClipping = 
false;
 
 1004                    if ( radialMap.
s1() < radialMap.
s2() )
 
 1005                        doClipping = intv.
maxValue() > radialMap.
s2();
 
 1007                        doClipping = intv.
minValue() < radialMap.
s2();
 
 1015                const QRectF clipRect = pr.adjusted(
 
 1016                    -margin, -margin, margin, margin );
 
 1017                if ( !clipRect.contains( canvasRect ) )
 
 1019                    QRegion clipRegion( clipRect.toRect(), QRegion::Ellipse );
 
 1020                    painter->setClipRegion( clipRegion, Qt::IntersectClip );
 
 1024            painter->setRenderHint( QPainter::Antialiasing,
 
 1027            item->
draw( painter, azimuthMap, radialMap,
 
 1028                pole, radius, canvasRect );
 
 
 1042    if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
 1045    ScaleData& d = m_data->scaleData[scaleId];
 
 1047    double minValue = d.minValue;
 
 1048    double maxValue = d.maxValue;
 
 1049    double stepSize = d.stepSize;
 
 1051    if ( scaleId == QwtPolar::ScaleRadius && d.doAutoScale )
 
 1056        for ( QwtPolarItemIterator it = itmList.begin();
 
 1057            it != itmList.end(); ++it )
 
 1068            minValue, maxValue, stepSize );
 
 1075            minValue, maxValue, d.maxMajor, d.maxMinor, stepSize );
 
 1082    for ( QwtPolarItemIterator it = itmList.begin();
 
 1083        it != itmList.end(); ++it )
 
 1087            *
scaleDiv( QwtPolar::Radius ), interval );
 
 
 1099    for ( QwtPolarItemIterator it = itmList.begin();
 
 1100        it != itmList.end(); ++it )
 
 1106            if ( hint > margin )
 
 
 1139    const QRectF cr = canvasRect;
 
 1140    const int radius = qMin( cr.width(), cr.height() ) / 2 - margin;
 
 1147    double v = map.
s1();
 
 1148    if ( map.
s1() <= map.
s2() )
 
 1149        v += m_data->zoomPos.
radius();
 
 1151        v -= m_data->zoomPos.
radius();
 
 1157    QPointF center( cr.center().x(), cr.top() + margin + radius );
 
 1158    center -= QPointF( off.x(), -off.y() );
 
 1160    QRectF rect( 0, 0, 2 * map.
p2(), 2 * map.
p2() );
 
 1161    rect.moveCenter( center );
 
 
 1174    const QRectF cRect = 
canvas()->contentsRect();
 
 1175    const QRectF pRect = 
plotRect( cRect );
 
 1176    if ( cRect.contains( pRect ) || !cRect.intersects( pRect ) )
 
 1181    const QPointF pole = pRect.center();
 
 1182    const QRectF scaleRect = pRect & cRect;
 
 1188    if ( scaleRect.contains( pole ) )
 
 1193        corners[0] = scaleRect.bottomRight();
 
 1194        corners[1] = scaleRect.topRight();
 
 1195        corners[2] = scaleRect.topLeft();
 
 1196        corners[3] = scaleRect.bottomLeft();
 
 1199        for ( 
int i = 0; i < 4; i++ )
 
 1201            const double dist = qwtDistance( pole, corners[i] );
 
 1208        if ( pole.x() < scaleRect.left() )
 
 1210            if ( pole.y() < scaleRect.top() )
 
 1212                dmin = qwtDistance( pole, scaleRect.topLeft() );
 
 1213                dmax = qwtDistance( pole, scaleRect.bottomRight() );
 
 1215            else if ( pole.y() > scaleRect.bottom() )
 
 1217                dmin = qwtDistance( pole, scaleRect.bottomLeft() );
 
 1218                dmax = qwtDistance( pole, scaleRect.topRight() );
 
 1222                dmin = scaleRect.left() - pole.x();
 
 1223                dmax = qMax( qwtDistance( pole, scaleRect.bottomRight() ),
 
 1224                    qwtDistance( pole, scaleRect.topRight() ) );
 
 1227        else if ( pole.x() > scaleRect.right() )
 
 1229            if ( pole.y() < scaleRect.top() )
 
 1231                dmin = qwtDistance( pole, scaleRect.topRight() );
 
 1232                dmax = qwtDistance( pole, scaleRect.bottomLeft() );
 
 1234            else if ( pole.y() > scaleRect.bottom() )
 
 1236                dmin = qwtDistance( pole, scaleRect.bottomRight() );
 
 1237                dmax = qwtDistance( pole, scaleRect.topLeft() );
 
 1241                dmin = pole.x() - scaleRect.right();
 
 1242                dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ),
 
 1243                    qwtDistance( pole, scaleRect.topLeft() ) );
 
 1246        else if ( pole.y() < scaleRect.top() )
 
 1248            dmin = scaleRect.top() - pole.y();
 
 1249            dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ),
 
 1250                qwtDistance( pole, scaleRect.bottomRight() ) );
 
 1252        else if ( pole.y() > scaleRect.bottom() )
 
 1254            dmin = pole.y() - scaleRect.bottom();
 
 1255            dmax = qMax( qwtDistance( pole, scaleRect.topLeft() ),
 
 1256                qwtDistance( pole, scaleRect.topRight() ) );
 
 1260    const double radius = pRect.width() / 2.0;
 
 1261    if ( dmax > radius )
 
 
 1276    return m_data->layout;
 
 
 1284    return m_data->layout;
 
 
 1293void QwtPolarPlot::attachItem( 
QwtPolarItem* plotItem, 
bool on )
 
 1312            const QVariant itemInfo = 
itemToInfo( plotItem );
 
 1339    return QVariant::fromValue( plotItem );
 
 
 1360        return qvariant_cast< QwtPolarItem* >( itemInfo );
 
 
 1365#include "moc_qwt_polar_plot.cpp" 
Abstract base class for legend widgets.
A class representing an interval.
void setMaxColumns(uint numColums)
Set the maximum number of entries in a row.
A scale engine for linear scales.
static void drawEllipse(QPainter *, const QRectF &)
Wrapper for QPainter::drawEllipse()
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
A point in polar coordinates.
double radius() const
Returns the radius.
bool isValid() const
Returns true if radius() >= 0.0.
double azimuth() const
Returns the azimuth.
Canvas of a QwtPolarPlot.
const QwtPolarItemList & itemList() const
A QwtPolarItemList of all attached plot items.
void insertItem(QwtPolarItem *)
void detachItems(int rtti=QwtPolarItem::Rtti_PolarItem, bool autoDelete=true)
void removeItem(QwtPolarItem *)
Base class for items on a polar plot.
bool testItemAttribute(ItemAttribute) const
virtual void draw(QPainter *painter, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, double radius, const QRectF &canvasRect) const =0
Draw the item.
virtual QwtInterval boundingInterval(int scaleId) const
@ Legend
The item is represented on the legend.
virtual void updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &, const QwtInterval &)
Update the item to changes of the axes scale division.
virtual QList< QwtLegendData > legendData() const
Return all information, that is needed to represent the item on the legend.
bool testRenderHint(RenderHint) const
@ Rtti_PolarGrid
For QwtPolarGrid.
@ Rtti_PolarItem
Unspecific value, that can be used, when it doesn't matter.
virtual int marginHint() const
@ RenderAntialiased
Enable antialiasing.
Layout class for QwtPolarPlot.
const QRectF & legendRect() const
void setLegendPosition(QwtPolarPlot::LegendPosition pos, double ratio)
Specify the position of the legend.
QwtPolarPlot::LegendPosition legendPosition() const
virtual void activate(const QwtPolarPlot *, const QRectF &rect, Options options=Options())
Recalculate the geometry of all components.
const QRectF & titleRect() const
const QRectF & canvasRect() const
void setScaleMaxMinor(int scaleId, int maxMinor)
QwtPolarLayout * plotLayout()
virtual QVariant itemToInfo(QwtPolarItem *) const
Build an information, that can be used to identify a plot item on the legend.
int scaleMaxMajor(int scaleId) const
void setScale(int scaleId, double min, double max, double step=0)
Disable autoscaling and specify a fixed scale for a selected scale.
QwtInterval visibleInterval() const
QwtScaleMap scaleMap(int scaleId, double radius) const
virtual void drawCanvas(QPainter *, const QRectF &) const
int scaleMaxMinor(int scaleId) const
int plotMarginHint() const
QwtPointPolar zoomPos() const
void autoRefresh()
Replots the plot if QwtPlot::autoReplot() is true.
const QwtScaleDiv * scaleDiv(int scaleId) const
Return the scale division of a specified scale.
void setAzimuthOrigin(double)
Change the origin of the azimuth scale.
const QBrush & plotBackground() const
QwtScaleEngine * scaleEngine(int scaleId)
void setScaleMaxMajor(int scaleId, int maxMajor)
virtual void updateLayout()
Rebuild the layout.
virtual bool event(QEvent *) override
Qt event handler.
bool hasAutoScale(int scaleId) const
virtual void replot()
Redraw the plot.
void zoom(const QwtPointPolar &, double factor)
Translate and in/decrease the zoom factor.
double zoomFactor() const
virtual void resizeEvent(QResizeEvent *) override
Resize and update internal layout.
virtual ~QwtPolarPlot()
Destructor.
void itemAttached(QwtPolarItem *plotItem, bool on)
double azimuthOrigin() const
void updateScale(int scaleId)
void insertLegend(QwtAbstractLegend *, LegendPosition=RightLegend, double ratio=-1.0)
Insert a legend.
virtual void drawItems(QPainter *painter, const QwtScaleMap &radialMap, const QwtScaleMap &azimuthMap, const QPointF &pole, double radius, const QRectF &canvasRect) const
void setScaleEngine(int scaleId, QwtScaleEngine *)
void setAutoReplot(bool tf=true)
Set or reset the autoReplot option.
QwtPolarPlot(QWidget *parent=NULL)
void legendDataChanged(const QVariant &itemInfo, const QList< QwtLegendData > &data)
void setScaleDiv(int scaleId, const QwtScaleDiv &)
Disable autoscaling and specify a fixed scale for a selected scale.
QwtAbstractLegend * legend()
void setAutoScale(int scaleId)
Enable autoscaling.
void setPlotBackground(const QBrush &c)
Set the background of the plot area.
QwtPolarCanvas * canvas()
@ BottomLegend
The legend will be below the canvas.
@ LeftLegend
The legend will be left from the canvas.
@ TopLegend
The legend will be between canvas and title.
@ RightLegend
The legend will be right from the canvas.
QwtTextLabel * titleLabel()
void setTitle(const QString &)
virtual QwtPolarItem * infoToItem(const QVariant &) const
Identify the plot item according to an item info object, that has bee generated from itemToInfo().
A class representing a scale division.
double lowerBound() const
double upperBound() const
Base class for scale engines.
QwtTransform * transformation() const
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const =0
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const =0
Calculate a scale division.
double transform(double s) const
void setPaintInterval(double p1, double p2)
Specify the borders of the paint device interval.
void setScaleInterval(double s1, double s2)
Specify the borders of the scale interval.
double invTransform(double p) const
void setTransformation(QwtTransform *)
A class representing a text.
A Widget which displays a QwtText.
bool isValid(int axisPos)