qwt_polar_plot.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 
34 {
35 public:
37  isValid( false ),
38  scaleEngine( NULL )
39  {
40  }
41 
43  {
44  delete scaleEngine;
45  }
46 
48 
49  double minValue;
50  double maxValue;
51  double stepSize;
52 
53  int maxMajor;
54  int maxMinor;
55 
56  bool isValid;
57 
60 };
61 
63 {
64 public:
65  QBrush canvasBrush;
66 
67  bool autoReplot;
68 
70  double zoomFactor;
71 
73  QPointer<QwtTextLabel> titleLabel;
74  QPointer<QwtPolarCanvas> canvas;
75  QPointer<QwtAbstractLegend> legend;
76  double azimuthOrigin;
77 
79 };
80 
85 QwtPolarPlot::QwtPolarPlot( QWidget *parent ):
86  QFrame( parent )
87 {
88  initPlot( QwtText() );
89 }
90 
96 QwtPolarPlot::QwtPolarPlot( const QwtText &title, QWidget *parent ):
97  QFrame( parent )
98 {
99  initPlot( title );
100 }
101 
104 {
106 
107  delete d_data->layout;
108  delete d_data;
109 }
110 
115 void QwtPolarPlot::setTitle( const QString &title )
116 {
117  if ( title != d_data->titleLabel->text().text() )
118  {
119  d_data->titleLabel->setText( title );
120  if ( !title.isEmpty() )
121  d_data->titleLabel->show();
122  else
123  d_data->titleLabel->hide();
124  }
125 }
126 
132 {
133  if ( title != d_data->titleLabel->text() )
134  {
135  d_data->titleLabel->setText( title );
136  if ( !title.isEmpty() )
137  d_data->titleLabel->show();
138  else
139  d_data->titleLabel->hide();
140  }
141 }
142 
145 {
146  return d_data->titleLabel->text();
147 }
148 
151 {
152  return d_data->titleLabel;
153 }
154 
157 {
158  return d_data->titleLabel;
159 }
160 
189  QwtPolarPlot::LegendPosition pos, double ratio )
190 {
191  d_data->layout->setLegendPosition( pos, ratio );
192 
193  if ( legend != d_data->legend )
194  {
195  if ( d_data->legend && d_data->legend->parent() == this )
196  delete d_data->legend;
197 
198  d_data->legend = legend;
199 
200  if ( d_data->legend )
201  {
202  connect( this,
203  SIGNAL( legendDataChanged(
204  const QVariant &, const QList<QwtLegendData> & ) ),
205  d_data->legend,
206  SLOT( updateLegend(
207  const QVariant &, const QList<QwtLegendData> & ) )
208  );
209 
210  if ( d_data->legend->parent() != this )
211  d_data->legend->setParent( this );
212 
213  updateLegend();
214 
215  QwtLegend *lgd = qobject_cast<QwtLegend *>( legend );
216  if ( lgd )
217  {
218  switch ( d_data->layout->legendPosition() )
219  {
220  case LeftLegend:
221  case RightLegend:
222  {
223  if ( lgd->maxColumns() == 0 )
224  lgd->setMaxColumns( 1 ); // 1 column: align vertical
225  break;
226  }
227  case TopLegend:
228  case BottomLegend:
229  {
230  lgd->setMaxColumns( 0 ); // unlimited
231  break;
232  }
233  default:
234  break;
235  }
236  }
237 
238  }
239  }
240 
241  updateLayout();
242 }
243 
250 {
251  const QwtPolarItemList& itmList = itemList();
252  for ( QwtPolarItemIterator it = itmList.begin();
253  it != itmList.end(); ++it )
254  {
255  updateLegend( *it );
256  }
257 }
258 
266 {
267  if ( plotItem == NULL )
268  return;
269 
270  QList<QwtLegendData> legendData;
271 
272  if ( plotItem->testItemAttribute( QwtPolarItem::Legend ) )
273  legendData = plotItem->legendData();
274 
275  const QVariant itemInfo = itemToInfo( const_cast< QwtPolarItem *>( plotItem) );
276  Q_EMIT legendDataChanged( itemInfo, legendData );
277 }
278 
284 {
285  return d_data->legend;
286 }
287 
293 {
294  return d_data->legend;
295 }
296 
306 void QwtPolarPlot::setPlotBackground( const QBrush &brush )
307 {
308  if ( brush != d_data->canvasBrush )
309  {
310  d_data->canvasBrush = brush;
311  autoRefresh();
312  }
313 }
314 
319 const QBrush &QwtPolarPlot::plotBackground() const
320 {
321  return d_data->canvasBrush;
322 }
323 
340 {
342 }
343 
346 {
347  return d_data->autoReplot;
348 }
349 
365 void QwtPolarPlot::setAutoScale( int scaleId )
366 {
367  if ( scaleId != QwtPolar::ScaleRadius )
368  return;
369 
370  ScaleData &scaleData = d_data->scaleData[scaleId];
371  if ( !scaleData.doAutoScale )
372  {
373  scaleData.doAutoScale = true;
374  autoRefresh();
375  }
376 }
377 
383 bool QwtPolarPlot::hasAutoScale( int scaleId ) const
384 {
385  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
386  return false;
387 
388  return d_data->scaleData[scaleId].doAutoScale;
389 }
390 
398 void QwtPolarPlot::setScaleMaxMinor( int scaleId, int maxMinor )
399 {
400  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
401  return;
402 
403  maxMinor = qBound( 0, maxMinor, 100 );
404 
405  ScaleData &scaleData = d_data->scaleData[scaleId];
406 
407  if ( maxMinor != scaleData.maxMinor )
408  {
409  scaleData.maxMinor = maxMinor;
410  scaleData.isValid = false;
411  autoRefresh();
412  }
413 }
414 
420 int QwtPolarPlot::scaleMaxMinor( int scaleId ) const
421 {
422  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
423  return 0;
424 
425  return d_data->scaleData[scaleId].maxMinor;
426 }
427 
435 void QwtPolarPlot::setScaleMaxMajor( int scaleId, int maxMajor )
436 {
437  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
438  return;
439 
440  maxMajor = qBound( 1, maxMajor, 10000 );
441 
442  ScaleData &scaleData = d_data->scaleData[scaleId];
443  if ( maxMajor != scaleData.maxMinor )
444  {
445  scaleData.maxMajor = maxMajor;
446  scaleData.isValid = false;
447  autoRefresh();
448  }
449 }
450 
457 int QwtPolarPlot::scaleMaxMajor( int scaleId ) const
458 {
459  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
460  return 0;
461 
462  return d_data->scaleData[scaleId].maxMajor;
463 }
464 
474 {
475  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
476  return;
477 
478  ScaleData &scaleData = d_data->scaleData[scaleId];
479  if ( scaleEngine == NULL || scaleEngine == scaleData.scaleEngine )
480  return;
481 
482  delete scaleData.scaleEngine;
483  scaleData.scaleEngine = scaleEngine;
484 
485  scaleData.isValid = false;
486 
487  autoRefresh();
488 }
489 
497 {
498  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
499  return NULL;
500 
501  return d_data->scaleData[scaleId].scaleEngine;
502 }
503 
510 const QwtScaleEngine *QwtPolarPlot::scaleEngine( int scaleId ) const
511 {
512  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
513  return NULL;
514 
515  return d_data->scaleData[scaleId].scaleEngine;
516 }
517 
527 void QwtPolarPlot::setScale( int scaleId,
528  double min, double max, double stepSize )
529 {
530  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
531  return;
532 
533  ScaleData &scaleData = d_data->scaleData[scaleId];
534 
535  scaleData.isValid = false;
536 
537  scaleData.minValue = min;
538  scaleData.maxValue = max;
539  scaleData.stepSize = stepSize;
540  scaleData.doAutoScale = false;
541 
542  autoRefresh();
543 }
544 
551 void QwtPolarPlot::setScaleDiv( int scaleId, const QwtScaleDiv &scaleDiv )
552 {
553  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
554  return;
555 
556  ScaleData &scaleData = d_data->scaleData[scaleId];
557 
558  scaleData.scaleDiv = scaleDiv;
559  scaleData.isValid = true;
560  scaleData.doAutoScale = false;
561 
562  autoRefresh();
563 }
564 
576 const QwtScaleDiv *QwtPolarPlot::scaleDiv( int scaleId ) const
577 {
578  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
579  return NULL;
580 
581  return &d_data->scaleData[scaleId].scaleDiv;
582 }
583 
596 {
597  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
598  return NULL;
599 
600  return &d_data->scaleData[scaleId].scaleDiv;
601 }
602 
612 void QwtPolarPlot::setAzimuthOrigin( double origin )
613 {
614  origin = ::fmod( origin, 2 * M_PI );
615  if ( origin != d_data->azimuthOrigin )
616  {
617  d_data->azimuthOrigin = origin;
618  autoRefresh();
619  }
620 }
621 
629 double QwtPolarPlot::azimuthOrigin() const
630 {
631  return d_data->azimuthOrigin;
632 }
633 
649 {
650  zoomFactor = qAbs( zoomFactor );
651  if ( zoomPos != d_data->zoomPos ||
652  zoomFactor != d_data->zoomFactor )
653  {
656  updateLayout();
657  autoRefresh();
658  }
659 }
660 
666 {
667  if ( d_data->zoomFactor != 1.0 || d_data->zoomPos.isValid() )
668  {
669  d_data->zoomFactor = 1.0;
671  autoRefresh();
672  }
673 }
674 
680 {
681  return d_data->zoomPos;
682 }
683 
689 {
690  return d_data->zoomFactor;
691 }
692 
708 {
709  const QRectF pr = plotRect();
710  return scaleMap( scaleId, pr.width() / 2.0 );
711 }
712 
727 QwtScaleMap QwtPolarPlot::scaleMap( int scaleId, const double radius ) const
728 {
729  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
730  return QwtScaleMap();
731 
732  QwtScaleMap map;
733  map.setTransformation( scaleEngine( scaleId )->transformation() );
734 
735  const QwtScaleDiv *sd = scaleDiv( scaleId );
736  map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
737 
738  if ( scaleId == QwtPolar::Azimuth )
739  {
741  d_data->azimuthOrigin + 2 * M_PI );
742  }
743  else
744  {
745  map.setPaintInterval( 0.0, radius );
746  }
747 
748  return map;
749 }
750 
759 bool QwtPolarPlot::event( QEvent *e )
760 {
761  bool ok = QWidget::event( e );
762  switch( e->type() )
763  {
764  case QEvent::LayoutRequest:
765  {
766  updateLayout();
767  break;
768  }
769  case QEvent::PolishRequest:
770  {
771  updateLayout();
772  replot();
773  break;
774  }
775  default:;
776  }
777  return ok;
778 }
779 
781 void QwtPolarPlot::resizeEvent( QResizeEvent *e )
782 {
783  QFrame::resizeEvent( e );
784  updateLayout();
785 }
786 
788 {
789  d_data = new PrivateData;
791 
792  QwtText text( title );
793  text.setRenderFlags( Qt::AlignCenter | Qt::TextWordWrap );
794 
795  d_data->titleLabel = new QwtTextLabel( text, this );
796  d_data->titleLabel->setFont( QFont( fontInfo().family(), 14, QFont::Bold ) );
797  if ( !text.isEmpty() )
798  d_data->titleLabel->show();
799  else
800  d_data->titleLabel->hide();
801 
802  d_data->canvas = new QwtPolarCanvas( this );
803 
804  d_data->autoReplot = false;
805  d_data->canvasBrush = QBrush( Qt::white );
806 
807  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
808  {
809  ScaleData &scaleData = d_data->scaleData[scaleId];
810 
811  if ( scaleId == QwtPolar::Azimuth )
812  {
813  scaleData.minValue = 0.0;
814  scaleData.maxValue = 360.0;
815  scaleData.stepSize = 30.0;
816  }
817  else
818  {
819  scaleData.minValue = 0.0;
820  scaleData.maxValue = 1000.0;
821  scaleData.stepSize = 0.0;
822  }
823 
824  scaleData.doAutoScale = true;
825 
826  scaleData.maxMinor = 5;
827  scaleData.maxMajor = 8;
828 
829  scaleData.isValid = false;
830 
831  scaleData.scaleEngine = new QwtLinearScaleEngine;
832  }
833  d_data->zoomFactor = 1.0;
834  d_data->azimuthOrigin = 0.0;
835 
836  setSizePolicy( QSizePolicy::MinimumExpanding,
837  QSizePolicy::MinimumExpanding );
838 
839  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
840  updateScale( scaleId );
841 }
842 
845 {
846  if ( d_data->autoReplot )
847  replot();
848 }
849 
852 {
853  d_data->layout->activate( this, contentsRect() );
854 
855  // resize and show the visible widgets
856  if ( d_data->titleLabel )
857  {
858  if ( !d_data->titleLabel->text().isEmpty() )
859  {
860  d_data->titleLabel->setGeometry( d_data->layout->titleRect().toRect() );
861  if ( !d_data->titleLabel->isVisible() )
862  d_data->titleLabel->show();
863  }
864  else
865  d_data->titleLabel->hide();
866  }
867 
868  if ( d_data->legend )
869  {
870  if ( d_data->legend->isEmpty() )
871  {
872  d_data->legend->hide();
873  }
874  else
875  {
876  const QRectF legendRect = d_data->layout->legendRect();
877  d_data->legend->setGeometry( legendRect.toRect() );
878  d_data->legend->show();
879  }
880  }
881 
882  d_data->canvas->setGeometry( d_data->layout->canvasRect().toRect() );
883  Q_EMIT layoutChanged();
884 }
885 
897 {
898  bool doAutoReplot = autoReplot();
899  setAutoReplot( false );
900 
901  for ( int scaleId = 0; scaleId < QwtPolar::ScaleCount; scaleId++ )
902  updateScale( scaleId );
903 
904  d_data->canvas->invalidateBackingStore();
905  d_data->canvas->repaint();
906 
907  setAutoReplot( doAutoReplot );
908 }
909 
912 {
913  return d_data->canvas;
914 }
915 
918 {
919  return d_data->canvas;
920 }
921 
927 void QwtPolarPlot::drawCanvas( QPainter *painter,
928  const QRectF &canvasRect ) const
929 {
930  const QRectF cr = canvasRect;
931  const QRectF pr = plotRect( cr );
932 
933  const double radius = pr.width() / 2.0;
934 
935  if ( d_data->canvasBrush.style() != Qt::NoBrush )
936  {
937  painter->save();
938  painter->setPen( Qt::NoPen );
939  painter->setBrush( d_data->canvasBrush );
940 
941  if ( qwtDistance( pr.center(), cr.topLeft() ) < radius &&
942  qwtDistance( pr.center(), cr.topRight() ) < radius &&
943  qwtDistance( pr.center(), cr.bottomRight() ) < radius &&
944  qwtDistance( pr.center(), cr.bottomLeft() ) < radius )
945  {
946  QwtPainter::drawRect( painter, cr );
947  }
948  else
949  {
950  painter->setRenderHint( QPainter::Antialiasing, true );
951  QwtPainter::drawEllipse( painter, pr );
952  }
953  painter->restore();
954  }
955 
956  drawItems( painter,
957  scaleMap( QwtPolar::Azimuth, radius ),
958  scaleMap( QwtPolar::Radius, radius ),
959  pr.center(), radius, canvasRect );
960 }
961 
972 void QwtPolarPlot::drawItems( QPainter *painter,
973  const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap,
974  const QPointF &pole, double radius,
975  const QRectF &canvasRect ) const
976 {
977  const QRectF pr = plotRect( canvasRect );
978 
979  const QwtPolarItemList& itmList = itemList();
980  for ( QwtPolarItemIterator it = itmList.begin();
981  it != itmList.end(); ++it )
982  {
983  QwtPolarItem *item = *it;
984  if ( item && item->isVisible() )
985  {
986  painter->save();
987 
988  // Unfortunately circular clipping slows down
989  // painting a lot. So we better try to avoid it.
990 
991  bool doClipping = false;
992  if ( item->rtti() != QwtPolarItem::Rtti_PolarGrid )
993  {
994  const QwtInterval intv =
996 
997  if ( !intv.isValid() )
998  doClipping = true;
999  else
1000  {
1001  if ( radialMap.s1() < radialMap.s2() )
1002  doClipping = intv.maxValue() > radialMap.s2();
1003  else
1004  doClipping = intv.minValue() < radialMap.s2();
1005  }
1006  }
1007 
1008  if ( doClipping )
1009  {
1010  const int margin = item->marginHint();
1011 
1012  const QRectF clipRect = pr.adjusted(
1013  -margin, -margin, margin, margin );
1014  if ( !clipRect.contains( canvasRect ) )
1015  {
1016  QRegion clipRegion( clipRect.toRect(), QRegion::Ellipse );
1017  painter->setClipRegion( clipRegion, Qt::IntersectClip );
1018  }
1019  }
1020 
1021  painter->setRenderHint( QPainter::Antialiasing,
1023 
1024  item->draw( painter, azimuthMap, radialMap,
1025  pole, radius, canvasRect );
1026 
1027  painter->restore();
1028  }
1029  }
1030 }
1031 
1037 void QwtPolarPlot::updateScale( int scaleId )
1038 {
1039  if ( scaleId < 0 || scaleId >= QwtPolar::ScaleCount )
1040  return;
1041 
1042  ScaleData &d = d_data->scaleData[scaleId];
1043 
1044  double minValue = d.minValue;
1045  double maxValue = d.maxValue;
1046  double stepSize = d.stepSize;
1047 
1048  if ( scaleId == QwtPolar::ScaleRadius && d.doAutoScale )
1049  {
1050  QwtInterval interval;
1051 
1052  const QwtPolarItemList& itmList = itemList();
1053  for ( QwtPolarItemIterator it = itmList.begin();
1054  it != itmList.end(); ++it )
1055  {
1056  const QwtPolarItem *item = *it;
1058  interval |= item->boundingInterval( scaleId );
1059  }
1060 
1061  minValue = interval.minValue();
1062  maxValue = interval.maxValue();
1063 
1065  minValue, maxValue, stepSize );
1066  d.isValid = false;
1067  }
1068 
1069  if ( !d.isValid )
1070  {
1072  minValue, maxValue, d.maxMajor, d.maxMinor, stepSize );
1073  d.isValid = true;
1074  }
1075 
1076  const QwtInterval interval = visibleInterval();
1077 
1078  const QwtPolarItemList& itmList = itemList();
1079  for ( QwtPolarItemIterator it = itmList.begin();
1080  it != itmList.end(); ++it )
1081  {
1082  QwtPolarItem *item = *it;
1084  *scaleDiv( QwtPolar::Radius ), interval );
1085  }
1086 }
1087 
1093 {
1094  int margin = 0;
1095  const QwtPolarItemList& itmList = itemList();
1096  for ( QwtPolarItemIterator it = itmList.begin();
1097  it != itmList.end(); ++it )
1098  {
1099  QwtPolarItem *item = *it;
1100  if ( item && item->isVisible() )
1101  {
1102  const int hint = item->marginHint();
1103  if ( hint > margin )
1104  margin = hint;
1105  }
1106  }
1107  return margin;
1108 }
1109 
1118 {
1119  return plotRect( canvas()->contentsRect() );
1120 }
1121 
1130 QRectF QwtPolarPlot::plotRect( const QRectF &canvasRect ) const
1131 {
1132  const QwtScaleDiv *sd = scaleDiv( QwtPolar::Radius );
1134 
1135  const int margin = plotMarginHint();
1136  const QRectF cr = canvasRect;
1137  const int radius = qMin( cr.width(), cr.height() ) / 2 - margin;
1138 
1139  QwtScaleMap map;
1140  map.setTransformation( se->transformation() );
1141  map.setPaintInterval( 0.0, radius / d_data->zoomFactor );
1142  map.setScaleInterval( sd->lowerBound(), sd->upperBound() );
1143 
1144  double v = map.s1();
1145  if ( map.s1() <= map.s2() )
1146  v += d_data->zoomPos.radius();
1147  else
1148  v -= d_data->zoomPos.radius();
1149  v = map.transform( v );
1150 
1151  const QPointF off =
1152  QwtPointPolar( d_data->zoomPos.azimuth(), v ).toPoint();
1153 
1154  QPointF center( cr.center().x(), cr.top() + margin + radius );
1155  center -= QPointF( off.x(), -off.y() );
1156 
1157  QRectF rect( 0, 0, 2 * map.p2(), 2 * map.p2() );
1158  rect.moveCenter( center );
1159 
1160  return rect;
1161 }
1162 
1168 {
1169  const QwtScaleDiv *sd = scaleDiv( QwtPolar::Radius );
1170 
1171  const QRectF cRect = canvas()->contentsRect();
1172  const QRectF pRect = plotRect( cRect );
1173  if ( cRect.contains( pRect ) || !cRect.intersects( pRect ) )
1174  {
1175  return QwtInterval( sd->lowerBound(), sd->upperBound() );
1176  }
1177 
1178  const QPointF pole = pRect.center();
1179  const QRectF scaleRect = pRect & cRect;
1180 
1181  const QwtScaleMap map = scaleMap( QwtPolar::Radius );
1182 
1183  double dmin = 0.0;
1184  double dmax = 0.0;
1185  if ( scaleRect.contains( pole ) )
1186  {
1187  dmin = 0.0;
1188 
1189  QPointF corners[4];
1190  corners[0] = scaleRect.bottomRight();
1191  corners[1] = scaleRect.topRight();
1192  corners[2] = scaleRect.topLeft();
1193  corners[3] = scaleRect.bottomLeft();
1194 
1195  dmax = 0.0;
1196  for ( int i = 0; i < 4; i++ )
1197  {
1198  const double dist = qwtDistance( pole, corners[i] );
1199  if ( dist > dmax )
1200  dmax = dist;
1201  }
1202  }
1203  else
1204  {
1205  if ( pole.x() < scaleRect.left() )
1206  {
1207  if ( pole.y() < scaleRect.top() )
1208  {
1209  dmin = qwtDistance( pole, scaleRect.topLeft() );
1210  dmax = qwtDistance( pole, scaleRect.bottomRight() );
1211  }
1212  else if ( pole.y() > scaleRect.bottom() )
1213  {
1214  dmin = qwtDistance( pole, scaleRect.bottomLeft() );
1215  dmax = qwtDistance( pole, scaleRect.topRight() );
1216  }
1217  else
1218  {
1219  dmin = scaleRect.left() - pole.x();
1220  dmax = qMax( qwtDistance( pole, scaleRect.bottomRight() ),
1221  qwtDistance( pole, scaleRect.topRight() ) );
1222  }
1223  }
1224  else if ( pole.x() > scaleRect.right() )
1225  {
1226  if ( pole.y() < scaleRect.top() )
1227  {
1228  dmin = qwtDistance( pole, scaleRect.topRight() );
1229  dmax = qwtDistance( pole, scaleRect.bottomLeft() );
1230  }
1231  else if ( pole.y() > scaleRect.bottom() )
1232  {
1233  dmin = qwtDistance( pole, scaleRect.bottomRight() );
1234  dmax = qwtDistance( pole, scaleRect.topLeft() );
1235  }
1236  else
1237  {
1238  dmin = pole.x() - scaleRect.right();
1239  dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ),
1240  qwtDistance( pole, scaleRect.topLeft() ) );
1241  }
1242  }
1243  else if ( pole.y() < scaleRect.top() )
1244  {
1245  dmin = scaleRect.top() - pole.y();
1246  dmax = qMax( qwtDistance( pole, scaleRect.bottomLeft() ),
1247  qwtDistance( pole, scaleRect.bottomRight() ) );
1248  }
1249  else if ( pole.y() > scaleRect.bottom() )
1250  {
1251  dmin = pole.y() - scaleRect.bottom();
1252  dmax = qMax( qwtDistance( pole, scaleRect.topLeft() ),
1253  qwtDistance( pole, scaleRect.topRight() ) );
1254  }
1255  }
1256 
1257  const double radius = pRect.width() / 2.0;
1258  if ( dmax > radius )
1259  dmax = radius;
1260 
1261  QwtInterval interval;
1262  interval.setMinValue( map.invTransform( dmin ) );
1263  interval.setMaxValue( map.invTransform( dmax ) );
1264 
1265  return interval;
1266 }
1267 
1272 {
1273  return d_data->layout;
1274 }
1275 
1280 {
1281  return d_data->layout;
1282 }
1283 
1290 void QwtPolarPlot::attachItem( QwtPolarItem *plotItem, bool on )
1291 {
1292  if ( on )
1293  insertItem( plotItem );
1294  else
1295  removeItem( plotItem );
1296 
1297  Q_EMIT itemAttached( plotItem, on );
1298 
1299  if ( plotItem->testItemAttribute( QwtPolarItem::Legend ) )
1300  {
1301  // the item wants to be represented on the legend
1302 
1303  if ( on )
1304  {
1305  updateLegend( plotItem );
1306  }
1307  else
1308  {
1309  const QVariant itemInfo = itemToInfo( plotItem );
1310  Q_EMIT legendDataChanged( itemInfo, QList<QwtLegendData>() );
1311  }
1312  }
1313 
1314  if ( autoReplot() )
1315  update();
1316 }
1317 
1334 QVariant QwtPolarPlot::itemToInfo( QwtPolarItem *plotItem ) const
1335 {
1336  return QVariant::fromValue( plotItem );
1337 }
1338 
1354 QwtPolarItem *QwtPolarPlot::infoToItem( const QVariant &itemInfo ) const
1355 {
1356  if ( itemInfo.canConvert<QwtPolarItem *>() )
1357  return qvariant_cast<QwtPolarItem *>( itemInfo );
1358 
1359  return NULL;
1360 }
1361 
1362 #if QWT_MOC_INCLUDE
1363 #include "moc_qwt_polar_plot.cpp"
1364 #endif
const QRectF & legendRect() const
bool isVisible() const
PrivateData * d_data
virtual bool event(QEvent *) QWT_OVERRIDE
Qt event handler.
void setScaleMaxMajor(int scaleId, int maxMajor)
const QRectF & canvasRect() const
The legend will be between canvas and title.
double zoomFactor() const
QPointer< QwtAbstractLegend > legend
virtual QwtInterval boundingInterval(int scaleId) const
A point in polar coordinates.
bool testItemAttribute(ItemAttribute) const
Unspecific value, that can be used, when it doesn&#39;t matter.
static double qwtDistance(const QPointF &p1, const QPointF &p2)
double s1() const
Definition: qwt_scale_map.h:83
void updateScale(int scaleId)
QwtPolarLayout * plotLayout()
A Widget which displays a QwtText.
A class representing an interval.
Definition: qwt_interval.h:22
virtual QVariant itemToInfo(QwtPolarItem *) const
Build an information, that can be used to identify a plot item on the legend.
void setRenderFlags(int)
Change the render flags.
Definition: qwt_text.cpp:281
MQTTClient d
Definition: test10.c:1656
QRectF plotRect() const
double minValue() const
Definition: qwt_interval.h:190
QwtPolarCanvas * canvas()
The legend will be below the canvas.
virtual void updateLayout()
Rebuild the layout.
Azimuth.
Definition: qwt_polar.h:36
QwtText title() const
const QRectF & titleRect() const
double radius() const
Returns the radius.
void removeItem(QwtPolarItem *)
virtual void drawCanvas(QPainter *, const QRectF &) 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 void activate(const QwtPolarPlot *, const QRectF &rect, Options options=Options())
Recalculate the geometry of all components.
ScaleData scaleData[QwtPolar::ScaleCount]
A class representing a scale division.
Definition: qwt_scale_div.h:33
virtual void drawItems(QPainter *painter, const QwtScaleMap &radialMap, const QwtScaleMap &azimuthMap, const QPointF &pole, double radius, const QRectF &canvasRect) const
bool hasAutoScale(int scaleId) const
void layoutChanged()
void setScaleInterval(double s1, double s2)
Specify the borders of the scale interval.
QwtPointPolar zoomPos() const
QwtTransform * transformation() const
double azimuth() const
Returns the azimuth.
QwtScaleMap scaleMap(int scaleId, double radius) const
virtual void updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &, const QwtInterval &)
Update the item to changes of the axes scale division.
double maxValue() const
Definition: qwt_interval.h:196
void detachItems(int rtti=QwtPolarItem::Rtti_PolarItem, bool autoDelete=true)
void setScaleEngine(int scaleId, QwtScaleEngine *)
void legendDataChanged(const QVariant &itemInfo, const QList< QwtLegendData > &data)
double upperBound() const
double s2() const
Definition: qwt_scale_map.h:91
QwtScaleEngine * scaleEngine(int scaleId)
The legend will be right from the canvas.
void setAutoReplot(bool tf=true)
Set or reset the autoReplot option.
QwtPolarPlot::LegendPosition legendPosition() const
Base class for items on a polar plot.
void insertItem(QwtPolarItem *)
int plotMarginHint() const
uint maxColumns() const
Definition: qwt_legend.cpp:310
Radius.
Definition: qwt_polar.h:39
#define min(A, B)
Definition: Log.c:64
#define max(A, B)
Definition: Socket.h:88
void zoom(const QwtPointPolar &, double factor)
Translate and in/decrease the zoom factor.
bool testRenderHint(RenderHint) const
QwtPolarPlot(QWidget *parent=NULL)
virtual QList< QwtLegendData > legendData() const
Return all information, that is needed to represent the item on the legend.
double lowerBound() const
void setTransformation(QwtTransform *)
bool isEmpty() const
Definition: qwt_text.cpp:716
bool autoReplot() const
bool isValid() const
Definition: qwt_interval.h:208
void setPaintInterval(double p1, double p2)
Specify the borders of the paint device interval.
const QwtScaleDiv * scaleDiv(int scaleId) const
Return the scale division of a specified scale.
QPointer< QwtPolarCanvas > canvas
QwtTextLabel * titleLabel()
A class representing a text.
Definition: qwt_text.h:51
QPointer< QwtTextLabel > titleLabel
void autoRefresh()
Replots the plot if QwtPlot::autoReplot() is true.
virtual void resizeEvent(QResizeEvent *) QWT_OVERRIDE
Resize and update internal layout.
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.
QList< QwtPolarItem * >::ConstIterator QwtPolarItemIterator
void attachItem(QwtPolarItem *, bool)
Attach/Detach a plot item.
Canvas of a QwtPolarPlot.
virtual QwtPolarItem * infoToItem(const QVariant &) const
Identify the plot item according to an item info object, that has bee generated from itemToInfo()...
void insertLegend(QwtAbstractLegend *, LegendPosition=RightLegend, double ratio=-1.0)
Insert a legend.
A scale map.
Definition: qwt_scale_map.h:26
double invTransform(double p) const
bool isValid() const
Returns true if radius() >= 0.0.
virtual int marginHint() const
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)
double azimuthOrigin() const
virtual int rtti() const
void setAutoScale(int scaleId)
Enable autoscaling.
QwtAbstractLegend * legend()
QwtScaleEngine * scaleEngine
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
void setMinValue(double)
Definition: qwt_interval.h:174
#define M_PI
Definition: qwt_math.h:56
Abstract base class for legend widgets.
void setTitle(const QString &)
virtual ~QwtPolarPlot()
Destructor.
int scaleMaxMajor(int scaleId) const
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:1726
The legend will be left from the canvas.
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const =0
void setLegendPosition(QwtPolarPlot::LegendPosition pos, double ratio)
Specify the position of the legend.
The item is represented on the legend.
void setMaxColumns(uint numColums)
Set the maximum number of entries in a row.
Definition: qwt_legend.cpp:296
A scale engine for linear scales.
void setPlotBackground(const QBrush &c)
Set the background of the plot area.
QwtInterval visibleInterval() const
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const =0
Calculate a scale division.
const QBrush & plotBackground() const
void initPlot(const QwtText &)
Layout class for QwtPolarPlot.
void setMaxValue(double)
Definition: qwt_interval.h:184
virtual void replot()
Redraw the plot.
const QwtPolarItemList & itemList() const
A QwtPolarItemList of all attached plot items.
void setScaleMaxMinor(int scaleId, int maxMinor)
bool autoDelete() const
Base class for scale engines.
int scaleMaxMinor(int scaleId) const


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10