qwt_polar_plot.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * QwtPolar Widget Library
3  * Copyright (C) 2008 Uwe Rathmann
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the Qwt License, Version 1.0
7  *****************************************************************************/
8 
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"
19 
20 #include <qpointer.h>
21 #include <qpaintengine.h>
22 #include <qpainter.h>
23 #include <qevent.h>
24 
25 static inline double qwtDistance(
26  const QPointF& p1, const QPointF& p2 )
27 {
28  double dx = p2.x() - p1.x();
29  double dy = p2.y() - p1.y();
30  return qSqrt( dx * dx + dy * dy );
31 }
32 
33 namespace
34 {
35  class ScaleData
36  {
37  public:
38  ScaleData()
39  : isValid( false )
40  , scaleEngine( NULL )
41  {
42  }
43 
44  ~ScaleData()
45  {
46  delete scaleEngine;
47  }
48 
49  bool doAutoScale;
50 
51  double minValue;
52  double maxValue;
53  double stepSize;
54 
55  int maxMajor;
56  int maxMinor;
57 
58  bool isValid;
59 
60  QwtScaleDiv scaleDiv;
61  QwtScaleEngine* scaleEngine;
62  };
63 }
64 
66 {
67  public:
68  QBrush canvasBrush;
69 
70  bool autoReplot;
71 
73  double zoomFactor;
74 
75  ScaleData scaleData[QwtPolar::ScaleCount];
76  QPointer< QwtTextLabel > titleLabel;
77  QPointer< QwtPolarCanvas > canvas;
78  QPointer< QwtAbstractLegend > legend;
79  double azimuthOrigin;
80 
82 };
83 
88 QwtPolarPlot::QwtPolarPlot( QWidget* parent )
89  : QFrame( parent )
90 {
91  initPlot( QwtText() );
92 }
93 
99 QwtPolarPlot::QwtPolarPlot( const QwtText& title, QWidget* parent )
100  : QFrame( parent )
101 {
102  initPlot( title );
103 }
104 
107 {
109 
110  delete m_data->layout;
111  delete m_data;
112 }
113 
118 void QwtPolarPlot::setTitle( const QString& title )
119 {
120  if ( title != m_data->titleLabel->text().text() )
121  {
122  m_data->titleLabel->setText( title );
123  if ( !title.isEmpty() )
124  m_data->titleLabel->show();
125  else
126  m_data->titleLabel->hide();
127  }
128 }
129 
135 {
136  if ( title != m_data->titleLabel->text() )
137  {
138  m_data->titleLabel->setText( title );
139  if ( !title.isEmpty() )
140  m_data->titleLabel->show();
141  else
142  m_data->titleLabel->hide();
143  }
144 }
145 
148 {
149  return m_data->titleLabel->text();
150 }
151 
154 {
155  return m_data->titleLabel;
156 }
157 
160 {
161  return m_data->titleLabel;
162 }
163 
192  QwtPolarPlot::LegendPosition pos, double ratio )
193 {
194  m_data->layout->setLegendPosition( pos, ratio );
195 
196  if ( legend != m_data->legend )
197  {
198  if ( m_data->legend && m_data->legend->parent() == this )
199  delete m_data->legend;
200 
201  m_data->legend = legend;
202 
203  if ( m_data->legend )
204  {
205  connect( this,
206  SIGNAL(legendDataChanged(
207  const QVariant&,const QList<QwtLegendData>&)),
208  m_data->legend,
209  SLOT(updateLegend(
210  const QVariant&,const QList<QwtLegendData>&))
211  );
212 
213  if ( m_data->legend->parent() != this )
214  m_data->legend->setParent( this );
215 
216  updateLegend();
217 
218  QwtLegend* lgd = qobject_cast< QwtLegend* >( legend );
219  if ( lgd )
220  {
221  switch ( m_data->layout->legendPosition() )
222  {
223  case LeftLegend:
224  case RightLegend:
225  {
226  if ( lgd->maxColumns() == 0 )
227  lgd->setMaxColumns( 1 ); // 1 column: align vertical
228  break;
229  }
230  case TopLegend:
231  case BottomLegend:
232  {
233  lgd->setMaxColumns( 0 ); // unlimited
234  break;
235  }
236  default:
237  break;
238  }
239  }
240 
241  }
242  }
243 
244  updateLayout();
245 }
246 
253 {
254  const QwtPolarItemList& itmList = itemList();
255  for ( QwtPolarItemIterator it = itmList.begin();
256  it != itmList.end(); ++it )
257  {
258  updateLegend( *it );
259  }
260 }
261 
269 {
270  if ( plotItem == NULL )
271  return;
272 
273  QList< QwtLegendData > legendData;
274 
275  if ( plotItem->testItemAttribute( QwtPolarItem::Legend ) )
276  legendData = plotItem->legendData();
277 
278  const QVariant itemInfo = itemToInfo( const_cast< QwtPolarItem* >( plotItem ) );
279  Q_EMIT legendDataChanged( itemInfo, legendData );
280 }
281 
287 {
288  return m_data->legend;
289 }
290 
296 {
297  return m_data->legend;
298 }
299 
309 void QwtPolarPlot::setPlotBackground( const QBrush& brush )
310 {
311  if ( brush != m_data->canvasBrush )
312  {
313  m_data->canvasBrush = brush;
314  autoRefresh();
315  }
316 }
317 
322 const QBrush& QwtPolarPlot::plotBackground() const
323 {
324  return m_data->canvasBrush;
325 }
326 
343 {
345 }
346 
349 {
350  return m_data->autoReplot;
351 }
352 
368 void QwtPolarPlot::setAutoScale( int scaleId )
369 {
370  if ( scaleId != QwtPolar::ScaleRadius )
371  return;
372 
373  ScaleData& scaleData = m_data->scaleData[scaleId];
374  if ( !scaleData.doAutoScale )
375  {
376  scaleData.doAutoScale = true;
377  autoRefresh();
378  }
379 }
380 
386 bool QwtPolarPlot::hasAutoScale( int scaleId ) const
387 {
388  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
389  return false;
390 
391  return m_data->scaleData[scaleId].doAutoScale;
392 }
393 
401 void QwtPolarPlot::setScaleMaxMinor( int scaleId, int maxMinor )
402 {
403  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
404  return;
405 
406  maxMinor = qBound( 0, maxMinor, 100 );
407 
408  ScaleData& scaleData = m_data->scaleData[scaleId];
409 
410  if ( maxMinor != scaleData.maxMinor )
411  {
412  scaleData.maxMinor = maxMinor;
413  scaleData.isValid = false;
414  autoRefresh();
415  }
416 }
417 
423 int QwtPolarPlot::scaleMaxMinor( int scaleId ) const
424 {
425  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
426  return 0;
427 
428  return m_data->scaleData[scaleId].maxMinor;
429 }
430 
438 void QwtPolarPlot::setScaleMaxMajor( int scaleId, int maxMajor )
439 {
440  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
441  return;
442 
443  maxMajor = qBound( 1, maxMajor, 10000 );
444 
445  ScaleData& scaleData = m_data->scaleData[scaleId];
446  if ( maxMajor != scaleData.maxMinor )
447  {
448  scaleData.maxMajor = maxMajor;
449  scaleData.isValid = false;
450  autoRefresh();
451  }
452 }
453 
460 int QwtPolarPlot::scaleMaxMajor( int scaleId ) const
461 {
462  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
463  return 0;
464 
465  return m_data->scaleData[scaleId].maxMajor;
466 }
467 
477 {
478  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
479  return;
480 
481  ScaleData& scaleData = m_data->scaleData[scaleId];
482  if ( scaleEngine == NULL || scaleEngine == scaleData.scaleEngine )
483  return;
484 
485  delete scaleData.scaleEngine;
486  scaleData.scaleEngine = scaleEngine;
487 
488  scaleData.isValid = false;
489 
490  autoRefresh();
491 }
492 
500 {
501  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
502  return NULL;
503 
504  return m_data->scaleData[scaleId].scaleEngine;
505 }
506 
513 const QwtScaleEngine* QwtPolarPlot::scaleEngine( int scaleId ) const
514 {
515  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
516  return NULL;
517 
518  return m_data->scaleData[scaleId].scaleEngine;
519 }
520 
530 void QwtPolarPlot::setScale( int scaleId,
531  double min, double max, double stepSize )
532 {
533  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
534  return;
535 
536  ScaleData& scaleData = m_data->scaleData[scaleId];
537 
538  scaleData.isValid = false;
539 
540  scaleData.minValue = min;
541  scaleData.maxValue = max;
542  scaleData.stepSize = stepSize;
543  scaleData.doAutoScale = false;
544 
545  autoRefresh();
546 }
547 
554 void QwtPolarPlot::setScaleDiv( int scaleId, const QwtScaleDiv& scaleDiv )
555 {
556  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
557  return;
558 
559  ScaleData& scaleData = m_data->scaleData[scaleId];
560 
561  scaleData.scaleDiv = scaleDiv;
562  scaleData.isValid = true;
563  scaleData.doAutoScale = false;
564 
565  autoRefresh();
566 }
567 
579 const QwtScaleDiv* QwtPolarPlot::scaleDiv( int scaleId ) const
580 {
581  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
582  return NULL;
583 
584  return &m_data->scaleData[scaleId].scaleDiv;
585 }
586 
599 {
600  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
601  return NULL;
602 
603  return &m_data->scaleData[scaleId].scaleDiv;
604 }
605 
615 void QwtPolarPlot::setAzimuthOrigin( double origin )
616 {
617  origin = ::fmod( origin, 2 * M_PI );
618  if ( origin != m_data->azimuthOrigin )
619  {
620  m_data->azimuthOrigin = origin;
621  autoRefresh();
622  }
623 }
624 
632 double QwtPolarPlot::azimuthOrigin() const
633 {
634  return m_data->azimuthOrigin;
635 }
636 
652 {
653  zoomFactor = qAbs( zoomFactor );
654  if ( zoomPos != m_data->zoomPos ||
655  zoomFactor != m_data->zoomFactor )
656  {
659  updateLayout();
660  autoRefresh();
661  }
662 }
663 
669 {
670  if ( m_data->zoomFactor != 1.0 || m_data->zoomPos.isValid() )
671  {
672  m_data->zoomFactor = 1.0;
674  autoRefresh();
675  }
676 }
677 
683 {
684  return m_data->zoomPos;
685 }
686 
692 {
693  return m_data->zoomFactor;
694 }
695 
711 {
712  const QRectF pr = plotRect();
713  return scaleMap( scaleId, pr.width() / 2.0 );
714 }
715 
730 QwtScaleMap QwtPolarPlot::scaleMap( int scaleId, const double radius ) const
731 {
732  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
733  return QwtScaleMap();
734 
735  QwtScaleMap map;
736  map.setTransformation( scaleEngine( scaleId )->transformation() );
737 
738  const QwtScaleDiv* sd = scaleDiv( scaleId );
739  map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
740 
741  if ( scaleId == QwtPolar::Azimuth )
742  {
744  m_data->azimuthOrigin + 2 * M_PI );
745  }
746  else
747  {
748  map.setPaintInterval( 0.0, radius );
749  }
750 
751  return map;
752 }
753 
762 bool QwtPolarPlot::event( QEvent* e )
763 {
764  bool ok = QWidget::event( e );
765  switch( e->type() )
766  {
767  case QEvent::LayoutRequest:
768  {
769  updateLayout();
770  break;
771  }
772  case QEvent::PolishRequest:
773  {
774  updateLayout();
775  replot();
776  break;
777  }
778  default:;
779  }
780  return ok;
781 }
782 
784 void QwtPolarPlot::resizeEvent( QResizeEvent* e )
785 {
786  QFrame::resizeEvent( e );
787  updateLayout();
788 }
789 
791 {
792  m_data = new PrivateData;
794 
795  QwtText text( title );
796  text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
797 
798  m_data->titleLabel = new QwtTextLabel( text, this );
799  m_data->titleLabel->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );
800  if ( !text.isEmpty() )
801  m_data->titleLabel->show();
802  else
803  m_data->titleLabel->hide();
804 
805  m_data->canvas = new QwtPolarCanvas( this );
806 
807  m_data->autoReplot = false;
808  m_data->canvasBrush = QBrush( Qt::white );
809 
810  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
811  {
812  ScaleData& scaleData = m_data->scaleData[scaleId];
813 
814  if ( scaleId == QwtPolar::Azimuth )
815  {
816  scaleData.minValue = 0.0;
817  scaleData.maxValue = 360.0;
818  scaleData.stepSize = 30.0;
819  }
820  else
821  {
822  scaleData.minValue = 0.0;
823  scaleData.maxValue = 1000.0;
824  scaleData.stepSize = 0.0;
825  }
826 
827  scaleData.doAutoScale = true;
828 
829  scaleData.maxMinor = 5;
830  scaleData.maxMajor = 8;
831 
832  scaleData.isValid = false;
833 
834  scaleData.scaleEngine = new QwtLinearScaleEngine;
835  }
836  m_data->zoomFactor = 1.0;
837  m_data->azimuthOrigin = 0.0;
838 
839  setSizePolicy( QSizePolicy::MinimumExpanding,
840  QSizePolicy::MinimumExpanding );
841 
842  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
843  updateScale( scaleId );
844 }
845 
848 {
849  if ( m_data->autoReplot )
850  replot();
851 }
852 
855 {
856  m_data->layout->activate( this, contentsRect() );
857 
858  // resize and show the visible widgets
859  if ( m_data->titleLabel )
860  {
861  if ( !m_data->titleLabel->text().isEmpty() )
862  {
863  m_data->titleLabel->setGeometry( m_data->layout->titleRect().toRect() );
864  if ( !m_data->titleLabel->isVisible() )
865  m_data->titleLabel->show();
866  }
867  else
868  m_data->titleLabel->hide();
869  }
870 
871  if ( m_data->legend )
872  {
873  if ( m_data->legend->isEmpty() )
874  {
875  m_data->legend->hide();
876  }
877  else
878  {
879  const QRectF legendRect = m_data->layout->legendRect();
880  m_data->legend->setGeometry( legendRect.toRect() );
881  m_data->legend->show();
882  }
883  }
884 
885  m_data->canvas->setGeometry( m_data->layout->canvasRect().toRect() );
886  Q_EMIT layoutChanged();
887 }
888 
900 {
901  bool doAutoReplot = autoReplot();
902  setAutoReplot( false );
903 
904  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
905  updateScale( scaleId );
906 
907  m_data->canvas->invalidateBackingStore();
908  m_data->canvas->repaint();
909 
910  setAutoReplot( doAutoReplot );
911 }
912 
915 {
916  return m_data->canvas;
917 }
918 
921 {
922  return m_data->canvas;
923 }
924 
930 void QwtPolarPlot::drawCanvas( QPainter* painter,
931  const QRectF& canvasRect ) const
932 {
933  const QRectF cr = canvasRect;
934  const QRectF pr = plotRect( cr );
935 
936  const double radius = pr.width() / 2.0;
937 
938  if ( m_data->canvasBrush.style() != Qt::NoBrush )
939  {
940  painter->save();
941  painter->setPen( Qt::NoPen );
942  painter->setBrush( m_data->canvasBrush );
943 
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 )
948  {
949  QwtPainter::drawRect( painter, cr );
950  }
951  else
952  {
953  painter->setRenderHint( QPainter::Antialiasing, true );
954  QwtPainter::drawEllipse( painter, pr );
955  }
956  painter->restore();
957  }
958 
959  drawItems( painter,
960  scaleMap( QwtPolar::Azimuth, radius ),
961  scaleMap( QwtPolar::Radius, radius ),
962  pr.center(), radius, canvasRect );
963 }
964 
975 void QwtPolarPlot::drawItems( QPainter* painter,
976  const QwtScaleMap& azimuthMap, const QwtScaleMap& radialMap,
977  const QPointF& pole, double radius,
978  const QRectF& canvasRect ) const
979 {
980  const QRectF pr = plotRect( canvasRect );
981 
982  const QwtPolarItemList& itmList = itemList();
983  for ( QwtPolarItemIterator it = itmList.begin();
984  it != itmList.end(); ++it )
985  {
986  QwtPolarItem* item = *it;
987  if ( item && item->isVisible() )
988  {
989  painter->save();
990 
991  // Unfortunately circular clipping slows down
992  // painting a lot. So we better try to avoid it.
993 
994  bool doClipping = false;
995  if ( item->rtti() != QwtPolarItem::Rtti_PolarGrid )
996  {
997  const QwtInterval intv =
999 
1000  if ( !intv.isValid() )
1001  doClipping = true;
1002  else
1003  {
1004  if ( radialMap.s1() < radialMap.s2() )
1005  doClipping = intv.maxValue() > radialMap.s2();
1006  else
1007  doClipping = intv.minValue() < radialMap.s2();
1008  }
1009  }
1010 
1011  if ( doClipping )
1012  {
1013  const int margin = item->marginHint();
1014 
1015  const QRectF clipRect = pr.adjusted(
1016  -margin, -margin, margin, margin );
1017  if ( !clipRect.contains( canvasRect ) )
1018  {
1019  QRegion clipRegion( clipRect.toRect(), QRegion::Ellipse );
1020  painter->setClipRegion( clipRegion, Qt::IntersectClip );
1021  }
1022  }
1023 
1024  painter->setRenderHint( QPainter::Antialiasing,
1026 
1027  item->draw( painter, azimuthMap, radialMap,
1028  pole, radius, canvasRect );
1029 
1030  painter->restore();
1031  }
1032  }
1033 }
1034 
1040 void QwtPolarPlot::updateScale( int scaleId )
1041 {
1042  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
1043  return;
1044 
1045  ScaleData& d = m_data->scaleData[scaleId];
1046 
1047  double minValue = d.minValue;
1048  double maxValue = d.maxValue;
1049  double stepSize = d.stepSize;
1050 
1051  if ( scaleId == QwtPolar::ScaleRadius && d.doAutoScale )
1052  {
1053  QwtInterval interval;
1054 
1055  const QwtPolarItemList& itmList = itemList();
1056  for ( QwtPolarItemIterator it = itmList.begin();
1057  it != itmList.end(); ++it )
1058  {
1059  const QwtPolarItem* item = *it;
1061  interval |= item->boundingInterval( scaleId );
1062  }
1063 
1064  minValue = interval.minValue();
1065  maxValue = interval.maxValue();
1066 
1067  d.scaleEngine->autoScale( d.maxMajor,
1068  minValue, maxValue, stepSize );
1069  d.isValid = false;
1070  }
1071 
1072  if ( !d.isValid )
1073  {
1074  d.scaleDiv = d.scaleEngine->divideScale(
1075  minValue, maxValue, d.maxMajor, d.maxMinor, stepSize );
1076  d.isValid = true;
1077  }
1078 
1079  const QwtInterval interval = visibleInterval();
1080 
1081  const QwtPolarItemList& itmList = itemList();
1082  for ( QwtPolarItemIterator it = itmList.begin();
1083  it != itmList.end(); ++it )
1084  {
1085  QwtPolarItem* item = *it;
1087  *scaleDiv( QwtPolar::Radius ), interval );
1088  }
1089 }
1090 
1096 {
1097  int margin = 0;
1098  const QwtPolarItemList& itmList = itemList();
1099  for ( QwtPolarItemIterator it = itmList.begin();
1100  it != itmList.end(); ++it )
1101  {
1102  QwtPolarItem* item = *it;
1103  if ( item && item->isVisible() )
1104  {
1105  const int hint = item->marginHint();
1106  if ( hint > margin )
1107  margin = hint;
1108  }
1109  }
1110  return margin;
1111 }
1112 
1121 {
1122  return plotRect( canvas()->contentsRect() );
1123 }
1124 
1133 QRectF QwtPolarPlot::plotRect( const QRectF& canvasRect ) const
1134 {
1135  const QwtScaleDiv* sd = scaleDiv( QwtPolar::Radius );
1137 
1138  const int margin = plotMarginHint();
1139  const QRectF cr = canvasRect;
1140  const int radius = qMin( cr.width(), cr.height() ) / 2 - margin;
1141 
1142  QwtScaleMap map;
1143  map.setTransformation( se->transformation() );
1144  map.setPaintInterval( 0.0, radius / m_data->zoomFactor );
1145  map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
1146 
1147  double v = map.s1();
1148  if ( map.s1() <= map.s2() )
1149  v += m_data->zoomPos.radius();
1150  else
1151  v -= m_data->zoomPos.radius();
1152  v = map.transform( v );
1153 
1154  const QPointF off =
1155  QwtPointPolar( m_data->zoomPos.azimuth(), v ).toPoint();
1156 
1157  QPointF center( cr.center().x(), cr.top() + margin + radius );
1158  center -= QPointF( off.x(), -off.y() );
1159 
1160  QRectF rect( 0, 0, 2 * map.p2(), 2 * map.p2() );
1161  rect.moveCenter( center );
1162 
1163  return rect;
1164 }
1165 
1171 {
1172  const QwtScaleDiv* sd = scaleDiv( QwtPolar::Radius );
1173 
1174  const QRectF cRect = canvas()->contentsRect();
1175  const QRectF pRect = plotRect( cRect );
1176  if ( cRect.contains( pRect ) || !cRect.intersects( pRect ) )
1177  {
1178  return QwtInterval( sd->lowerBound(), sd->upperBound() );
1179  }
1180 
1181  const QPointF pole = pRect.center();
1182  const QRectF scaleRect = pRect & cRect;
1183 
1184  const QwtScaleMap map = scaleMap( QwtPolar::Radius );
1185 
1186  double dmin = 0.0;
1187  double dmax = 0.0;
1188  if ( scaleRect.contains( pole ) )
1189  {
1190  dmin = 0.0;
1191 
1192  QPointF corners[4];
1193  corners[0] = scaleRect.bottomRight();
1194  corners[1] = scaleRect.topRight();
1195  corners[2] = scaleRect.topLeft();
1196  corners[3] = scaleRect.bottomLeft();
1197 
1198  dmax = 0.0;
1199  for ( int i = 0; i < 4; i++ )
1200  {
1201  const double dist = qwtDistance( pole, corners[i] );
1202  if ( dist > dmax )
1203  dmax = dist;
1204  }
1205  }
1206  else
1207  {
1208  if ( pole.x() < scaleRect.left() )
1209  {
1210  if ( pole.y() < scaleRect.top() )
1211  {
1212  dmin = qwtDistance( pole, scaleRect.topLeft() );
1213  dmax = qwtDistance( pole, scaleRect.bottomRight() );
1214  }
1215  else if ( pole.y() > scaleRect.bottom() )
1216  {
1217  dmin = qwtDistance( pole, scaleRect.bottomLeft() );
1218  dmax = qwtDistance( pole, scaleRect.topRight() );
1219  }
1220  else
1221  {
1222  dmin = scaleRect.left() - pole.x();
1223  dmax = qMax( qwtDistance( pole, scaleRect.bottomRight() ),
1224  qwtDistance( pole, scaleRect.topRight() ) );
1225  }
1226  }
1227  else if ( pole.x() > scaleRect.right() )
1228  {
1229  if ( pole.y() < scaleRect.top() )
1230  {
1231  dmin = qwtDistance( pole, scaleRect.topRight() );
1232  dmax = qwtDistance( pole, scaleRect.bottomLeft() );
1233  }
1234  else if ( pole.y() > scaleRect.bottom() )
1235  {
1236  dmin = qwtDistance( pole, scaleRect.bottomRight() );
1237  dmax = qwtDistance( pole, scaleRect.topLeft() );
1238  }
1239  else
1240  {
1241  dmin = pole.x() - scaleRect.right();
1242  dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ),
1243  qwtDistance( pole, scaleRect.topLeft() ) );
1244  }
1245  }
1246  else if ( pole.y() < scaleRect.top() )
1247  {
1248  dmin = scaleRect.top() - pole.y();
1249  dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ),
1250  qwtDistance( pole, scaleRect.bottomRight() ) );
1251  }
1252  else if ( pole.y() > scaleRect.bottom() )
1253  {
1254  dmin = pole.y() - scaleRect.bottom();
1255  dmax = qMax( qwtDistance( pole, scaleRect.topLeft() ),
1256  qwtDistance( pole, scaleRect.topRight() ) );
1257  }
1258  }
1259 
1260  const double radius = pRect.width() / 2.0;
1261  if ( dmax > radius )
1262  dmax = radius;
1263 
1264  QwtInterval interval;
1265  interval.setMinValue( map.invTransform( dmin ) );
1266  interval.setMaxValue( map.invTransform( dmax ) );
1267 
1268  return interval;
1269 }
1270 
1275 {
1276  return m_data->layout;
1277 }
1278 
1283 {
1284  return m_data->layout;
1285 }
1286 
1293 void QwtPolarPlot::attachItem( QwtPolarItem* plotItem, bool on )
1294 {
1295  if ( on )
1296  insertItem( plotItem );
1297  else
1298  removeItem( plotItem );
1299 
1300  Q_EMIT itemAttached( plotItem, on );
1301 
1302  if ( plotItem->testItemAttribute( QwtPolarItem::Legend ) )
1303  {
1304  // the item wants to be represented on the legend
1305 
1306  if ( on )
1307  {
1308  updateLegend( plotItem );
1309  }
1310  else
1311  {
1312  const QVariant itemInfo = itemToInfo( plotItem );
1313  Q_EMIT legendDataChanged( itemInfo, QList< QwtLegendData >() );
1314  }
1315  }
1316 
1317  if ( autoReplot() )
1318  update();
1319 }
1320 
1337 QVariant QwtPolarPlot::itemToInfo( QwtPolarItem* plotItem ) const
1338 {
1339  return QVariant::fromValue( plotItem );
1340 }
1341 
1357 QwtPolarItem* QwtPolarPlot::infoToItem( const QVariant& itemInfo ) const
1358 {
1359  if ( itemInfo.canConvert< QwtPolarItem* >() )
1360  return qvariant_cast< QwtPolarItem* >( itemInfo );
1361 
1362  return NULL;
1363 }
1364 
1365 #if QWT_MOC_INCLUDE
1366 #include "moc_qwt_polar_plot.cpp"
1367 #endif
double invTransform(double p) const
d
int scaleMaxMinor(int scaleId) const
double lowerBound() const
virtual bool event(QEvent *) QWT_OVERRIDE
Qt event handler.
void setScaleMaxMajor(int scaleId, int maxMajor)
bool testRenderHint(RenderHint) const
The legend will be between canvas and title.
bool isValid() const
Definition: qwt_interval.h:210
virtual void drawItems(QPainter *painter, const QwtScaleMap &radialMap, const QwtScaleMap &azimuthMap, const QPointF &pole, double radius, const QRectF &canvasRect) const
const QwtScaleDiv * scaleDiv(int scaleId) const
Return the scale division of a specified scale.
A point in polar coordinates.
const QBrush & plotBackground() const
Unspecific value, that can be used, when it doesn&#39;t matter.
static double qwtDistance(const QPointF &p1, const QPointF &p2)
void updateScale(int scaleId)
double radius() const
Returns the radius.
bool isValid(int axisPos)
Definition: qwt_axis.h:45
QwtPolarLayout * plotLayout()
A Widget which displays a QwtText.
A class representing an interval.
Definition: qwt_interval.h:22
void setRenderFlags(int)
Change the render flags.
Definition: qwt_text.cpp:304
double minValue() const
Definition: qwt_interval.h:192
QwtPolarCanvas * canvas()
The legend will be below the canvas.
virtual void updateLayout()
Rebuild the layout.
const QRectF & titleRect() const
Azimuth.
Definition: qwt_polar.h:36
QwtScaleMap scaleMap(int scaleId, double radius) const
void removeItem(QwtPolarItem *)
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 void activate(const QwtPolarPlot *, const QRectF &rect, Options options=Options())
Recalculate the geometry of all components.
ScaleData scaleData[QwtPolar::ScaleCount]
bool isVisible() const
A class representing a scale division.
Definition: qwt_scale_div.h:33
void layoutChanged()
virtual QList< QwtLegendData > legendData() const
Return all information, that is needed to represent the item on the legend.
void setScaleInterval(double s1, double s2)
Specify the borders of the scale interval.
virtual void updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &, const QwtInterval &)
Update the item to changes of the axes scale division.
void detachItems(int rtti=QwtPolarItem::Rtti_PolarItem, bool autoDelete=true)
QwtPolarPlot::LegendPosition legendPosition() const
void setScaleEngine(int scaleId, QwtScaleEngine *)
void legendDataChanged(const QVariant &itemInfo, const QList< QwtLegendData > &data)
bool hasAutoScale(int scaleId) const
virtual void drawCanvas(QPainter *, const QRectF &) const
QwtScaleEngine * scaleEngine(int scaleId)
The legend will be right from the canvas.
void setAutoReplot(bool tf=true)
Set or reset the autoReplot option.
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
Base class for items on a polar plot.
void insertItem(QwtPolarItem *)
double azimuthOrigin() const
virtual QwtInterval boundingInterval(int scaleId) const
Radius.
Definition: qwt_polar.h:39
Definition: lz4.c:1706
QList< QwtPolarItem *>::ConstIterator QwtPolarItemIterator
QPointer< QwtTextLabel > titleLabel
void zoom(const QwtPointPolar &, double factor)
Translate and in/decrease the zoom factor.
bool isEmpty() const
Definition: qwt_text.cpp:739
const QRectF & legendRect() const
QwtPolarPlot(QWidget *parent=NULL)
void setTransformation(QwtTransform *)
bool isValid() const
Returns true if radius() >= 0.0.
QPointer< QwtPolarCanvas > canvas
virtual QwtPolarItem * infoToItem(const QVariant &) const
Identify the plot item according to an item info object, that has bee generated from itemToInfo()...
void setPaintInterval(double p1, double p2)
Specify the borders of the paint device interval.
QwtTextLabel * titleLabel()
A class representing a text.
Definition: qwt_text.h:51
void autoRefresh()
Replots the plot if QwtPlot::autoReplot() is true.
virtual void resizeEvent(QResizeEvent *) QWT_OVERRIDE
Resize and update internal layout.
int plotMarginHint() const
void setScale(int scaleId, double min, double max, double step=0)
Disable autoscaling and specify a fixed scale for a selected scale.
void setScaleDiv(int scaleId, const QwtScaleDiv &)
Disable autoscaling and specify a fixed scale for a selected scale.
void attachItem(QwtPolarItem *, bool)
Attach/Detach a plot item.
Canvas of a QwtPolarPlot.
double azimuth() const
Returns the azimuth.
void insertLegend(QwtAbstractLegend *, LegendPosition=RightLegend, double ratio=-1.0)
Insert a legend.
virtual int marginHint() const
A scale map.
Definition: qwt_scale_map.h:26
void setAzimuthOrigin(double)
Change the origin of the azimuth scale.
Number of scales.
Definition: qwt_polar.h:80
static void drawEllipse(QPainter *, const QRectF &)
Wrapper for QPainter::drawEllipse()
void itemAttached(QwtPolarItem *plotItem, bool on)
QwtPointPolar zoomPos() const
void setAutoScale(int scaleId)
Enable autoscaling.
QwtAbstractLegend * legend()
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
void setMinValue(double)
Definition: qwt_interval.h:176
PrivateData * m_data
#define M_PI
Definition: qwt_math.h:56
QPointer< QwtAbstractLegend > legend
virtual QVariant itemToInfo(QwtPolarItem *) const
Build an information, that can be used to identify a plot item on the legend.
Abstract base class for legend widgets.
void setTitle(const QString &)
virtual ~QwtPolarPlot()
Destructor.
The legend widget.
Definition: qwt_legend.h:31
Radial scale.
Definition: qwt_polar.h:77
std::enable_if_t< all< Args... >::value, enable_t > enable
Definition: sol.hpp:2244
The legend will be left from the canvas.
int scaleMaxMajor(int scaleId) const
bool autoReplot() const
double zoomFactor() const
double s1() const
Definition: qwt_scale_map.h:83
void setLegendPosition(QwtPolarPlot::LegendPosition pos, double ratio)
Specify the position of the legend.
uint maxColumns() const
Definition: qwt_legend.cpp:310
The item is represented on the legend.
virtual int rtti() const
QwtText title() const
void setMaxColumns(uint numColums)
Set the maximum number of entries in a row.
Definition: qwt_legend.cpp:296
bool testItemAttribute(ItemAttribute) const
A scale engine for linear scales.
void setPlotBackground(const QBrush &c)
Set the background of the plot area.
double upperBound() const
const QRectF & canvasRect() const
QwtInterval visibleInterval() const
const QwtPolarItemList & itemList() const
A QwtPolarItemList of all attached plot items.
void initPlot(const QwtText &)
Layout class for QwtPolarPlot.
void setMaxValue(double)
Definition: qwt_interval.h:186
virtual void replot()
Redraw the plot.
void setScaleMaxMinor(int scaleId, int maxMinor)
double s2() const
Definition: qwt_scale_map.h:91
double maxValue() const
Definition: qwt_interval.h:198
QwtTransform * transformation() const
Base class for scale engines.
QRectF plotRect() const


plotjuggler
Author(s): Davide Faconti
autogenerated on Mon Jun 19 2023 03:01:39