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)