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> 
   25 static 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 );
 
   65 class QwtPolarPlot::PrivateData
 
   75     ScaleData scaleData[QwtPolar::ScaleCount];
 
   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;
 
  194     m_data->layout->setLegendPosition( pos, ratio );
 
  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 );
 
  221                 switch ( m_data->layout->legendPosition() )
 
  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 );
 
  790 void 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 )
 
 1067         d.scaleEngine->autoScale( d.maxMajor,
 
 1068             minValue, maxValue, stepSize );
 
 1074         d.scaleDiv = d.scaleEngine->divideScale(
 
 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;
 
 1293 void QwtPolarPlot::attachItem( 
QwtPolarItem* plotItem, 
bool on )
 
 1312             const QVariant itemInfo = 
itemToInfo( plotItem );
 
 1339     return QVariant::fromValue( plotItem );
 
 1360         return qvariant_cast< QwtPolarItem* >( itemInfo );
 
 1366 #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.
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.
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
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)