9 #include "qwt_polar_grid.h" 
   10 #include "qwt_painter.h" 
   12 #include "qwt_clipper.h" 
   13 #include "qwt_scale_map.h" 
   14 #include "qwt_scale_engine.h" 
   15 #include "qwt_scale_div.h" 
   16 #include "qwt_scale_draw.h" 
   17 #include "qwt_round_scale_draw.h" 
   23 static inline bool isClose( 
double value1, 
double value2 )
 
   25     return qAbs( value1 - value2 ) < DBL_EPSILON;
 
   55             , isMinorVisible( false )
 
   68 class QwtPolarGrid::PrivateData
 
   71     GridData gridData[QwtPolar::ScaleCount];
 
   72     AxisData axisData[QwtPolar::AxesCount];
 
   87     m_data = 
new PrivateData;
 
   89     for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
   91         AxisData& axis = m_data->axisData[axisId];
 
   94             case QwtPolar::AxisAzimuth:
 
  100                 axis.isVisible = 
true;
 
  103             case QwtPolar::AxisLeft:
 
  109                 axis.isVisible = 
false;
 
  112             case QwtPolar::AxisRight:
 
  118                 axis.isVisible = 
true;
 
  121             case QwtPolar::AxisTop:
 
  127                 axis.isVisible = 
false;
 
  130             case QwtPolar::AxisBottom:
 
  136                 axis.isVisible = 
true;
 
  176     if ( ( ( m_data->displayFlags & flag ) != 0 ) != on )
 
  179             m_data->displayFlags |= flag;
 
  181             m_data->displayFlags &= ~flag;
 
  193     return ( m_data->displayFlags & flag );
 
  207     if ( 
bool( m_data->attributes & attribute ) == on )
 
  211         m_data->attributes |= attribute;
 
  213         m_data->attributes &= ~attribute;
 
  224     return m_data->attributes & attribute;
 
  237     if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  240     AxisData& axisData = m_data->axisData[axisId];
 
  241     if ( axisData.pen != pen )
 
  256     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  259     GridData& grid = m_data->gridData[scaleId];
 
  260     if ( grid.isVisible != 
show )
 
  262         grid.isVisible = 
show;
 
  274     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  277     return m_data->gridData[scaleId].isVisible;
 
  292     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  295     GridData& grid = m_data->gridData[scaleId];
 
  296     if ( grid.isMinorVisible != 
show )
 
  298         grid.isMinorVisible = 
show;
 
  310     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  313     return m_data->gridData[scaleId].isMinorVisible;
 
  326     if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  329     AxisData& axisData = m_data->axisData[axisId];
 
  330     if ( axisData.isVisible != 
show )
 
  332         axisData.isVisible = 
show;
 
  345     if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  348     return m_data->axisData[axisId].isVisible;
 
  359     bool isChanged = 
false;
 
  361     for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  363         GridData& grid = m_data->gridData[scaleId];
 
  364         if ( grid.majorPen != pen || grid.minorPen != pen )
 
  371     for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  373         AxisData& axis = m_data->axisData[axisId];
 
  374         if ( axis.pen != pen )
 
  392     bool isChanged = 
false;
 
  393     for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  395         AxisData& axis = m_data->axisData[axisId];
 
  396         if ( axis.font != font )
 
  414     bool isChanged = 
false;
 
  416     for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  418         GridData& grid = m_data->gridData[scaleId];
 
  419         if ( grid.majorPen != pen )
 
  438     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  441     GridData& grid = m_data->gridData[scaleId];
 
  442     if ( grid.majorPen != pen )
 
  456     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  459     const GridData& grid = m_data->gridData[scaleId];
 
  460     return grid.majorPen;
 
  471     bool isChanged = 
false;
 
  473     for ( 
int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
 
  475         GridData& grid = m_data->gridData[scaleId];
 
  476         if ( grid.minorPen != pen )
 
  495     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  498     GridData& grid = m_data->gridData[scaleId];
 
  499     if ( grid.minorPen != pen )
 
  512     if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
 
  515     const GridData& grid = m_data->gridData[scaleId];
 
  516     return grid.minorPen;
 
  527     if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  530     return m_data->axisData[axisId].pen;
 
  541     if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  544     AxisData& axisData = m_data->axisData[axisId];
 
  545     if ( axisData.font != font )
 
  547         axisData.font = font;
 
  558     if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  561     return m_data->axisData[axisId].font;
 
  576     const QPointF& pole, 
double radius,
 
  577     const QRectF& canvasRect )
 const 
  579     updateScaleDraws( azimuthMap, radialMap, pole, radius );
 
  585         QRegion clipRegion( canvasRect.toRect() );
 
  586         for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  588             const AxisData& axis = m_data->axisData[axisId];
 
  589             if ( axisId != QwtPolar::AxisAzimuth && axis.isVisible )
 
  596                     for ( 
int i = 0; i < int( ticks.size() ); i++ )
 
  604                         const int margin = 2;
 
  605                         labelRect.adjust( -margin, -margin, margin, margin );
 
  607                         if ( labelRect.isValid() )
 
  608                             clipRegion -= QRegion( labelRect );
 
  613         painter->setClipRegion( clipRegion );
 
  618     const GridData& radialGrid = m_data->gridData[QwtPolar::Radius];
 
  619     if ( radialGrid.isVisible && radialGrid.isMinorVisible )
 
  621         painter->setPen( radialGrid.minorPen );
 
  628     if ( radialGrid.isVisible )
 
  630         painter->setPen( radialGrid.majorPen );
 
  638     const GridData& azimuthGrid =
 
  639         m_data->gridData[QwtPolar::Azimuth];
 
  641     if ( azimuthGrid.isVisible && azimuthGrid.isMinorVisible )
 
  643         painter->setPen( azimuthGrid.minorPen );
 
  645         drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
  647         drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
  650     if ( azimuthGrid.isVisible )
 
  652         painter->setPen( azimuthGrid.majorPen );
 
  654         drawRays( painter, canvasRect, pole, radius, azimuthMap,
 
  659     for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  661         const AxisData& axis = m_data->axisData[axisId];
 
  662         if ( axis.isVisible )
 
  682     QPainter* painter, 
const QRectF& canvasRect,
 
  683     const QPointF& pole, 
double radius,
 
  686     for ( 
int i = 0; i < int( values.size() ); i++ )
 
  688         double azimuth = azimuthMap.
transform( values[i] );
 
  689         azimuth = ::fmod( azimuth, 2 * M_PI );
 
  691         bool skipLine = 
false;
 
  696             if ( isClose( azimuth, 0.0 ) )
 
  698                 const AxisData& axis = m_data->axisData[QwtPolar::AxisRight];
 
  699                 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  702             else if ( isClose( azimuth, M_PI / 2 ) )
 
  704                 const AxisData& axis = m_data->axisData[QwtPolar::AxisTop];
 
  705                 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  708             else if ( isClose( azimuth, M_PI ) )
 
  710                 const AxisData& axis = m_data->axisData[QwtPolar::AxisLeft];
 
  711                 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  714             else if ( isClose( azimuth, 3 * M_PI / 2.0 ) )
 
  716                 const AxisData& axis = m_data->axisData[QwtPolar::AxisBottom];
 
  717                 if ( axis.isVisible && axis.scaleDraw->hasComponent( bone ) )
 
  723             const QPointF pos = qwtPolar2Pos( pole, radius, azimuth );
 
  730             QPolygonF polygon( 2 );
 
  731             polygon[0] = pole.toPoint();
 
  732             polygon[1] = pos.toPoint();
 
  752     QPainter* painter, 
const QRectF& canvasRect,
 
  756     for ( 
int i = 0; i < int( values.size() ); i++ )
 
  758         const double val = values[i];
 
  760         const GridData& gridData =
 
  761             m_data->gridData[QwtPolar::Radius];
 
  763         bool skipLine = 
false;
 
  766             const AxisData& axis = m_data->axisData[QwtPolar::AxisAzimuth];
 
  767             if ( axis.isVisible &&
 
  770                 if ( isClose( val, gridData.scaleDiv.upperBound() ) )
 
  775         if ( isClose( val, gridData.scaleDiv.lowerBound() ) )
 
  780             const double radius = radialMap.
transform( val );
 
  782             QRectF outerRect( 0, 0, 2 * radius, 2 * radius );
 
  783             outerRect.moveCenter( pole );
 
  796                 for ( 
int j = 0; j < angles.size(); j++ )
 
  806                         const double from = qwtDegrees( intv.
minValue() );
 
  807                         const double to = qwtDegrees( intv.
maxValue() );
 
  809                         double span = to - from;
 
  813                         painter->drawArc( outerRect,
 
  814                             qRound( from * 16 ), qRound( span * 16 ) );
 
  834     if ( axisId < 0 || axisId >= QwtPolar::AxesCount )
 
  837     AxisData& axis = m_data->axisData[axisId];
 
  839     painter->setPen( axis.pen );
 
  840     painter->setFont( axis.font );
 
  843     pal.setColor( QPalette::WindowText, axis.pen.color() );
 
  844     pal.setColor( QPalette::Text, axis.pen.color() );
 
  846     axis.scaleDraw->draw( painter, pal );
 
  859 void QwtPolarGrid::updateScaleDraws(
 
  861     const QPointF& pole, 
double radius )
 const 
  863     const QPoint p = pole.toPoint();
 
  866         m_data->gridData[QwtPolar::ScaleRadius].scaleDiv.interval();
 
  870     const int l = max - min;
 
  872     for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  874         AxisData& axis = m_data->axisData[axisId];
 
  876         if ( axisId == QwtPolar::AxisAzimuth )
 
  881             scaleDraw->setRadius( qRound( radius ) );
 
  884             double from = ::fmod( 90.0 - qwtDegrees( azimuthMap.
p1() ), 360.0 );
 
  888             scaleDraw->setAngleRange( from, from - 360.0 );
 
  903                 case QwtPolar::AxisLeft:
 
  909                 case QwtPolar::AxisRight:
 
  915                 case QwtPolar::AxisTop:
 
  921                 case QwtPolar::AxisBottom:
 
  955     GridData& radialGrid = m_data->gridData[QwtPolar::Radius];
 
  968         if ( radialGrid.scaleDiv != radialScaleDiv )
 
  969             radialGrid.scaleDiv = radialScaleDiv;
 
  972     GridData& azimuthGrid = m_data->gridData[QwtPolar::Azimuth];
 
  973     if ( azimuthGrid.scaleDiv != azimuthScaleDiv )
 
  975         azimuthGrid.scaleDiv = azimuthScaleDiv;
 
  978     bool hasOrigin = 
false;
 
  979     for ( 
int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ )
 
  981         AxisData& axis = m_data->axisData[axisId];
 
  982         if ( axis.isVisible && axis.scaleDraw )
 
  984             if ( axisId == QwtPolar::AxisAzimuth )
 
  986                 axis.scaleDraw->setScaleDiv( azimuthGrid.scaleDiv );
 
  989                     axis.scaleDraw->enableComponent(
 
 1001                     bool skipOrigin = hasOrigin;
 
 1004                         if ( axisId == QwtPolar::AxisLeft
 
 1005                             || axisId == QwtPolar::AxisRight )
 
 1007                             if ( m_data->axisData[QwtPolar::AxisBottom].isVisible )
 
 1012                             if ( m_data->axisData[QwtPolar::AxisLeft].isVisible )
 
 1016                     if ( ticks.size() > 0 && ticks.first() == sd.
lowerBound() )
 
 1019                             ticks.removeFirst();
 
 1027                     if ( ticks.size() > 0 && ticks.last() == sd.
upperBound() )
 
 1032                 axis.scaleDraw->setScaleDiv( sd );
 
 1036                     axis.scaleDraw->enableComponent(
 
 1051     const AxisData& axis = m_data->axisData[QwtPolar::AxisAzimuth];
 
 1052     if ( axis.isVisible )
 
 1054         const int extent = axis.scaleDraw->extent( axis.font );
 
 1070     if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
 
 1071         return static_cast< QwtScaleDraw* 
>( m_data->axisData[axisId].scaleDraw );
 
 1085     if ( axisId >= QwtPolar::AxisLeft && axisId <= QwtPolar::AxisBottom )
 
 1086         return static_cast< QwtScaleDraw* 
>( m_data->axisData[axisId].scaleDraw );
 
 1101     if ( axisId < QwtPolar::AxisLeft || axisId > QwtPolar::AxisBottom )
 
 1104     AxisData& axisData = m_data->axisData[axisId];
 
 1107         delete axisData.scaleDraw;
 
 1120         m_data->axisData[QwtPolar::AxisAzimuth].scaleDraw );
 
 1130         m_data->axisData[QwtPolar::AxisAzimuth].scaleDraw );
 
 1141     AxisData& axisData = m_data->axisData[QwtPolar::AxisAzimuth];
 
 1144         delete axisData.scaleDraw;
 
A abstract base class for drawing scales.
@ Backbone
Backbone = the line where the ticks are located.
void setTransformation(QwtTransform *)
void setTickLength(QwtScaleDiv::TickType, double length)
bool hasComponent(ScaleComponent) const
const QwtScaleDiv & scaleDiv() const
A class representing an interval.
static void drawEllipse(QPainter *, const QRectF &)
Wrapper for QPainter::drawEllipse()
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
bool testDisplayFlag(DisplayFlag) const
GridAttribute
Grid attributes.
void setGridAttribute(GridAttribute, bool on=true)
Specify an attribute for the grid.
QFont axisFont(int axisId) const
QPen minorGridPen(int scaleId) const
QPen axisPen(int axisId) const
bool testGridAttribute(GridAttribute) const
void setScaleDraw(int axisId, QwtScaleDraw *)
Set a scale draw.
virtual ~QwtPolarGrid()
Destructor.
const QwtRoundScaleDraw * azimuthScaleDraw() const
virtual void updateScaleDiv(const QwtScaleDiv &azimuthMap, const QwtScaleDiv &radialMap, const QwtInterval &) override
Update the item to changes of the axes scale division.
void showMinorGrid(int scaleId, bool show=true)
void showGrid(int scaleId, bool show=true)
void setMinorGridPen(const QPen &p)
virtual int marginHint() const override
void setPen(const QPen &p)
void setAzimuthScaleDraw(QwtRoundScaleDraw *)
Set a scale draw for the azimuth scale.
void drawRays(QPainter *, const QRectF &, const QPointF &pole, double radius, const QwtScaleMap &azimuthMap, const QList< double > &) const
void drawCircles(QPainter *, const QRectF &, const QPointF &pole, const QwtScaleMap &radialMap, const QList< double > &) const
QFlags< GridAttribute > GridAttributes
bool isGridVisible(int scaleId) const
const QwtScaleDraw * scaleDraw(int axisId) const
bool isMinorGridVisible(int scaleId) const
virtual int rtti() const override
virtual void draw(QPainter *p, const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, double radius, const QRectF &rect) const override
bool isAxisVisible(int axisId) const
QPen majorGridPen(int scaleId) const
void setAxisFont(int axisId, const QFont &p)
void setAxisPen(int axisId, const QPen &p)
void drawAxis(QPainter *, int axisId) const
void showAxis(int axisId, bool show=true)
void setFont(const QFont &)
void setMajorGridPen(const QPen &p)
QFlags< DisplayFlag > DisplayFlags
void setDisplayFlag(DisplayFlag, bool on=true)
QwtPolarGrid()
Constructor.
Base class for items on a polar plot.
virtual void itemChanged()
@ Rtti_PolarGrid
For QwtPolarGrid.
QwtPolarPlot * plot() const
@ RenderAntialiased
Enable antialiasing.
void show()
Show the item.
void setRenderHint(RenderHint, bool on=true)
void setZ(double z)
Set the z value.
A plotting widget, displaying a polar coordinate system.
int scaleMaxMajor(int scaleId) const
int scaleMaxMinor(int scaleId) const
QwtScaleEngine * scaleEngine(int scaleId)
A class for drawing round scales.
A class representing a scale division.
double lowerBound() const
double upperBound() const
QList< double > ticks(int tickType) const
bool contains(double value) const
@ MediumTick
Medium ticks.
void setTicks(int tickType, const QList< double > &)
A class for drawing scales.
void setLength(double length)
QRect boundingLabelRect(const QFont &, double value) const
Find the bounding rectangle for the label.
void move(double x, double y)
void setAlignment(Alignment)
@ BottomScale
The scale is below.
@ LeftScale
The scale is left.
Base class for scale engines.
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
const QwtTransform * transformation() const
Get the transformation.
A class representing a text.
QWT_EXPORT void clipPolygonF(const QRectF &, QPolygonF &, bool closePolygon=false)
QWT_EXPORT QVector< QwtInterval > clipCircle(const QRectF &, const QPointF &, double radius)