Qwt User's Guide  6.2.0
qwt_plot_axis.cpp
1 /******************************************************************************
2  * Qwt Widget Library
3  * Copyright (C) 1997 Josef Wilgen
4  * Copyright (C) 2002 Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #include "qwt_plot.h"
11 #include "qwt_scale_widget.h"
12 #include "qwt_scale_map.h"
13 #include "qwt_scale_div.h"
14 #include "qwt_scale_engine.h"
15 #include "qwt_interval.h"
16 
17 namespace
18 {
19  class AxisData
20  {
21  public:
22  AxisData()
23  : isVisible( true )
24  , doAutoScale( true )
25  , minValue( 0.0 )
26  , maxValue( 1000.0 )
27  , stepSize( 0.0 )
28  , maxMajor( 8 )
29  , maxMinor( 5 )
30  , isValid( false )
31  , scaleEngine( new QwtLinearScaleEngine() )
32  , scaleWidget( NULL )
33  {
34  }
35 
36  ~AxisData()
37  {
38  delete scaleEngine;
39  }
40 
41  void initWidget( QwtScaleDraw::Alignment align, const QString& name, QwtPlot* plot )
42  {
43  scaleWidget = new QwtScaleWidget( align, plot );
44  scaleWidget->setObjectName( name );
45 
46  #if 1
47  // better find the font sizes from the application font
48  const QFont fscl( plot->fontInfo().family(), 10 );
49  const QFont fttl( plot->fontInfo().family(), 12, QFont::Bold );
50  #endif
51 
52  scaleWidget->setTransformation( scaleEngine->transformation() );
53 
54  scaleWidget->setFont( fscl );
55  scaleWidget->setMargin( 2 );
56 
57  QwtText text = scaleWidget->title();
58  text.setFont( fttl );
59  scaleWidget->setTitle( text );
60  }
61 
62  bool isVisible;
63  bool doAutoScale;
64 
65  double minValue;
66  double maxValue;
67  double stepSize;
68 
69  int maxMajor;
70  int maxMinor;
71 
72  bool isValid;
73 
74  QwtScaleDiv scaleDiv;
75  QwtScaleEngine* scaleEngine;
76  QwtScaleWidget* scaleWidget;
77  };
78 }
79 
80 class QwtPlot::ScaleData
81 {
82  public:
83  ScaleData( QwtPlot* plot )
84  {
85  using namespace QwtAxis;
86 
87  m_axisData[YLeft].initWidget( QwtScaleDraw::LeftScale, "QwtPlotAxisYLeft", plot );
88  m_axisData[YRight].initWidget( QwtScaleDraw::RightScale, "QwtPlotAxisYRight", plot );
89  m_axisData[XTop].initWidget( QwtScaleDraw::TopScale, "QwtPlotAxisXTop", plot );
90  m_axisData[XBottom].initWidget( QwtScaleDraw::BottomScale, "QwtPlotAxisXBottom", plot );
91  }
92 
93  inline AxisData& axisData( QwtAxisId axisId )
94  {
95  return m_axisData[ axisId ];
96  }
97 
98  inline const AxisData& axisData( QwtAxisId axisId ) const
99  {
100  return m_axisData[ axisId ];
101  }
102 
103  private:
104  AxisData m_axisData[ QwtAxis::AxisPositions ];
105 };
106 
107 void QwtPlot::initAxesData()
108 {
109  m_scaleData = new ScaleData( this );
110 
111  m_scaleData->axisData( QwtAxis::YRight ).isVisible = false;
112  m_scaleData->axisData( QwtAxis::XTop ).isVisible = false;
113 }
114 
115 void QwtPlot::deleteAxesData()
116 {
117  delete m_scaleData;
118  m_scaleData = NULL;
119 }
120 
132 bool QwtPlot::isAxisValid( QwtAxisId axisId ) const
133 {
134  return QwtAxis::isValid( axisId );
135 }
136 
141 const QwtScaleWidget* QwtPlot::axisWidget( QwtAxisId axisId ) const
142 {
143  if ( isAxisValid( axisId ) )
144  return m_scaleData->axisData( axisId ).scaleWidget;
145 
146  return NULL;
147 }
148 
154 {
155  if ( isAxisValid( axisId ) )
156  return m_scaleData->axisData( axisId ).scaleWidget;
157 
158  return NULL;
159 }
160 
169 void QwtPlot::setAxisScaleEngine( QwtAxisId axisId, QwtScaleEngine* scaleEngine )
170 {
171  if ( isAxisValid( axisId ) && scaleEngine != NULL )
172  {
173  AxisData& d = m_scaleData->axisData( axisId );
174 
175  delete d.scaleEngine;
176  d.scaleEngine = scaleEngine;
177 
178  d.scaleWidget->setTransformation( scaleEngine->transformation() );
179 
180  d.isValid = false;
181 
182  autoRefresh();
183  }
184 }
185 
191 {
192  if ( isAxisValid( axisId ) )
193  return m_scaleData->axisData( axisId ).scaleEngine;
194  else
195  return NULL;
196 }
197 
202 const QwtScaleEngine* QwtPlot::axisScaleEngine( QwtAxisId axisId ) const
203 {
204  if ( isAxisValid( axisId ) )
205  return m_scaleData->axisData( axisId ).scaleEngine;
206  else
207  return NULL;
208 }
213 bool QwtPlot::axisAutoScale( QwtAxisId axisId ) const
214 {
215  if ( isAxisValid( axisId ) )
216  return m_scaleData->axisData( axisId ).doAutoScale;
217  else
218  return false;
219 }
220 
225 bool QwtPlot::isAxisVisible( QwtAxisId axisId ) const
226 {
227  if ( isAxisValid( axisId ) )
228  return m_scaleData->axisData( axisId ).isVisible;
229  else
230  return false;
231 }
232 
237 QFont QwtPlot::axisFont( QwtAxisId axisId ) const
238 {
239  if ( isAxisValid( axisId ) )
240  return axisWidget( axisId )->font();
241  else
242  return QFont();
243 
244 }
245 
251 int QwtPlot::axisMaxMajor( QwtAxisId axisId ) const
252 {
253  if ( isAxisValid( axisId ) )
254  return m_scaleData->axisData( axisId ).maxMajor;
255  else
256  return 0;
257 }
258 
264 int QwtPlot::axisMaxMinor( QwtAxisId axisId ) const
265 {
266  if ( isAxisValid( axisId ) )
267  return m_scaleData->axisData( axisId ).maxMinor;
268  else
269  return 0;
270 }
271 
283 const QwtScaleDiv& QwtPlot::axisScaleDiv( QwtAxisId axisId ) const
284 {
285  return m_scaleData->axisData( axisId ).scaleDiv;
286 }
287 
294 const QwtScaleDraw* QwtPlot::axisScaleDraw( QwtAxisId axisId ) const
295 {
296  if ( !isAxisValid( axisId ) )
297  return NULL;
298 
299  return axisWidget( axisId )->scaleDraw();
300 }
301 
309 {
310  if ( !isAxisValid( axisId ) )
311  return NULL;
312 
313  return axisWidget( axisId )->scaleDraw();
314 }
315 
326 double QwtPlot::axisStepSize( QwtAxisId axisId ) const
327 {
328  if ( !isAxisValid( axisId ) )
329  return 0;
330 
331  return m_scaleData->axisData( axisId ).stepSize;
332 }
333 
344 QwtInterval QwtPlot::axisInterval( QwtAxisId axisId ) const
345 {
346  if ( !isAxisValid( axisId ) )
347  return QwtInterval();
348 
349  return m_scaleData->axisData( axisId ).scaleDiv.interval();
350 }
351 
356 QwtText QwtPlot::axisTitle( QwtAxisId axisId ) const
357 {
358  if ( isAxisValid( axisId ) )
359  return axisWidget( axisId )->title();
360  else
361  return QwtText();
362 }
363 
376 void QwtPlot::setAxisVisible( QwtAxisId axisId, bool on )
377 {
378  if ( isAxisValid( axisId ) && on != m_scaleData->axisData( axisId ).isVisible )
379  {
380  m_scaleData->axisData( axisId ).isVisible = on;
381  updateLayout();
382  }
383 }
384 
397 double QwtPlot::invTransform( QwtAxisId axisId, double pos ) const
398 {
399  if ( isAxisValid( axisId ) )
400  return( canvasMap( axisId ).invTransform( pos ) );
401  else
402  return 0.0;
403 }
404 
405 
414 double QwtPlot::transform( QwtAxisId axisId, double value ) const
415 {
416  if ( isAxisValid( axisId ) )
417  return( canvasMap( axisId ).transform( value ) );
418  else
419  return 0.0;
420 }
421 
430 void QwtPlot::setAxisFont( QwtAxisId axisId, const QFont& font )
431 {
432  if ( isAxisValid( axisId ) )
433  axisWidget( axisId )->setFont( font );
434 }
435 
449 void QwtPlot::setAxisAutoScale( QwtAxisId axisId, bool on )
450 {
451  if ( isAxisValid( axisId ) && ( m_scaleData->axisData( axisId ).doAutoScale != on ) )
452  {
453  m_scaleData->axisData( axisId ).doAutoScale = on;
454  autoRefresh();
455  }
456 }
457 
473 void QwtPlot::setAxisScale( QwtAxisId axisId, double min, double max, double stepSize )
474 {
475  if ( isAxisValid( axisId ) )
476  {
477  AxisData& d = m_scaleData->axisData( axisId );
478 
479  d.doAutoScale = false;
480  d.isValid = false;
481 
482  d.minValue = min;
483  d.maxValue = max;
484  d.stepSize = stepSize;
485 
486  autoRefresh();
487  }
488 }
489 
502 void QwtPlot::setAxisScaleDiv( QwtAxisId axisId, const QwtScaleDiv& scaleDiv )
503 {
504  if ( isAxisValid( axisId ) )
505  {
506  AxisData& d = m_scaleData->axisData( axisId );
507 
508  d.doAutoScale = false;
509  d.scaleDiv = scaleDiv;
510  d.isValid = true;
511 
512  autoRefresh();
513  }
514 }
515 
532 void QwtPlot::setAxisScaleDraw( QwtAxisId axisId, QwtScaleDraw* scaleDraw )
533 {
534  if ( isAxisValid( axisId ) )
535  {
536  axisWidget( axisId )->setScaleDraw( scaleDraw );
537  autoRefresh();
538  }
539 }
540 
549 void QwtPlot::setAxisLabelAlignment( QwtAxisId axisId, Qt::Alignment alignment )
550 {
551  if ( isAxisValid( axisId ) )
552  axisWidget( axisId )->setLabelAlignment( alignment );
553 }
554 
564 void QwtPlot::setAxisLabelRotation( QwtAxisId axisId, double rotation )
565 {
566  if ( isAxisValid( axisId ) )
567  axisWidget( axisId )->setLabelRotation( rotation );
568 }
569 
578 void QwtPlot::setAxisMaxMinor( QwtAxisId axisId, int maxMinor )
579 {
580  if ( isAxisValid( axisId ) )
581  {
582  maxMinor = qBound( 0, maxMinor, 100 );
583 
584  AxisData& d = m_scaleData->axisData( axisId );
585  if ( maxMinor != d.maxMinor )
586  {
587  d.maxMinor = maxMinor;
588  d.isValid = false;
589  autoRefresh();
590  }
591  }
592 }
593 
602 void QwtPlot::setAxisMaxMajor( QwtAxisId axisId, int maxMajor )
603 {
604  if ( isAxisValid( axisId ) )
605  {
606  maxMajor = qBound( 1, maxMajor, 10000 );
607 
608  AxisData& d = m_scaleData->axisData( axisId );
609  if ( maxMajor != d.maxMajor )
610  {
611  d.maxMajor = maxMajor;
612  d.isValid = false;
613  autoRefresh();
614  }
615  }
616 }
617 
624 void QwtPlot::setAxisTitle( QwtAxisId axisId, const QString& title )
625 {
626  if ( isAxisValid( axisId ) )
627  axisWidget( axisId )->setTitle( title );
628 }
629 
636 void QwtPlot::setAxisTitle( QwtAxisId axisId, const QwtText& title )
637 {
638  if ( isAxisValid( axisId ) )
639  axisWidget( axisId )->setTitle( title );
640 }
641 
667 {
668  // Find bounding interval of the item data
669  // for all axes, where autoscaling is enabled
670 
671  QwtInterval boundingIntervals[QwtAxis::AxisPositions];
672 
673  const QwtPlotItemList& itmList = itemList();
674 
675  QwtPlotItemIterator it;
676  for ( it = itmList.begin(); it != itmList.end(); ++it )
677  {
678  const QwtPlotItem* item = *it;
679 
681  continue;
682 
683  if ( !item->isVisible() )
684  continue;
685 
686  if ( axisAutoScale( item->xAxis() ) || axisAutoScale( item->yAxis() ) )
687  {
688  const QRectF rect = item->boundingRect();
689 
690  if ( rect.width() >= 0.0 )
691  boundingIntervals[item->xAxis()] |= QwtInterval( rect.left(), rect.right() );
692 
693  if ( rect.height() >= 0.0 )
694  boundingIntervals[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() );
695  }
696  }
697 
698  // Adjust scales
699 
700  for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
701  {
702  {
703  const QwtAxisId axisId( axisPos );
704 
705  AxisData& d = m_scaleData->axisData( axisId );
706 
707  double minValue = d.minValue;
708  double maxValue = d.maxValue;
709  double stepSize = d.stepSize;
710 
711  const QwtInterval& interval = boundingIntervals[axisId];
712 
713  if ( d.doAutoScale && interval.isValid() )
714  {
715  d.isValid = false;
716 
717  minValue = interval.minValue();
718  maxValue = interval.maxValue();
719 
720  d.scaleEngine->autoScale( d.maxMajor,
721  minValue, maxValue, stepSize );
722  }
723  if ( !d.isValid )
724  {
725  d.scaleDiv = d.scaleEngine->divideScale(
726  minValue, maxValue, d.maxMajor, d.maxMinor, stepSize );
727  d.isValid = true;
728  }
729 
730  QwtScaleWidget* scaleWidget = axisWidget( axisId );
731  scaleWidget->setScaleDiv( d.scaleDiv );
732 
733  int startDist, endDist;
734  scaleWidget->getBorderDistHint( startDist, endDist );
735  scaleWidget->setBorderDist( startDist, endDist );
736  }
737  }
738 
739  for ( it = itmList.begin(); it != itmList.end(); ++it )
740  {
741  QwtPlotItem* item = *it;
743  {
744  item->updateScaleDiv( axisScaleDiv( item->xAxis() ),
745  axisScaleDiv( item->yAxis() ) );
746  }
747  }
748 }
749 
A class representing an interval.
Definition: qwt_interval.h:23
double minValue() const
Definition: qwt_interval.h:192
double maxValue() const
Definition: qwt_interval.h:198
bool isValid() const
Definition: qwt_interval.h:210
A scale engine for linear scales.
const QwtPlotItemList & itemList() const
A QwtPlotItemList of all attached plot items.
A 2-D plotting widget.
Definition: qwt_plot.h:79
double transform(QwtAxisId, double value) const
Transform a value into a coordinate in the plotting region.
void setAxisVisible(QwtAxisId, bool on=true)
Hide or show a specified axis.
QFont axisFont(QwtAxisId) const
void updateAxes()
Rebuild the axes scales.
void setAxisLabelAlignment(QwtAxisId, Qt::Alignment)
void setAxisScale(QwtAxisId, double min, double max, double stepSize=0)
Disable autoscaling and specify a fixed scale for a selected axis.
QwtScaleEngine * axisScaleEngine(QwtAxisId)
double axisStepSize(QwtAxisId) const
Return the step size parameter that has been set in setAxisScale.
void setAxisScaleDraw(QwtAxisId, QwtScaleDraw *)
Set a scale draw.
void setAxisLabelRotation(QwtAxisId, double rotation)
void setAxisFont(QwtAxisId, const QFont &)
Change the font of an axis.
void setAxisTitle(QwtAxisId, const QString &)
Change the title of a specified axis.
void setAxisAutoScale(QwtAxisId, bool on=true)
Enable autoscaling for a specified axis.
void setAxisScaleEngine(QwtAxisId, QwtScaleEngine *)
void setAxisMaxMajor(QwtAxisId, int maxMajor)
bool isAxisVisible(QwtAxisId) const
bool axisAutoScale(QwtAxisId) const
QwtInterval axisInterval(QwtAxisId) const
Return the current interval of the specified axis.
double invTransform(QwtAxisId, double pos) const
QwtText axisTitle(QwtAxisId) const
bool isAxisValid(QwtAxisId) const
void setAxisMaxMinor(QwtAxisId, int maxMinor)
const QwtScaleWidget * axisWidget(QwtAxisId) const
virtual QwtScaleMap canvasMap(QwtAxisId) const
Definition: qwt_plot.cpp:800
int axisMaxMinor(QwtAxisId) const
virtual void updateLayout()
Adjust plot content to its current size.
Definition: qwt_plot.cpp:577
void autoRefresh()
Replots the plot if autoReplot() is true.
Definition: qwt_plot.cpp:289
const QwtScaleDiv & axisScaleDiv(QwtAxisId) const
Return the scale division of a specified axis.
void setAxisScaleDiv(QwtAxisId, const QwtScaleDiv &)
Disable autoscaling and specify a fixed scale for a selected axis.
const QwtScaleDraw * axisScaleDraw(QwtAxisId) const
Return the scale draw of a specified axis.
QwtText title() const
Definition: qwt_plot.cpp:351
int axisMaxMajor(QwtAxisId) const
Base class for items on the plot canvas.
Definition: qwt_plot_item.h:67
QwtAxisId yAxis() const
Return yAxis.
bool isVisible() const
QwtAxisId xAxis() const
Return xAxis.
bool testItemInterest(ItemInterest) const
virtual void updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)
Update the item to changes of the axes scale division.
bool testItemAttribute(ItemAttribute) const
virtual QRectF boundingRect() const
A class representing a scale division.
Definition: qwt_scale_div.h:34
A class for drawing scales.
@ BottomScale
The scale is below.
@ TopScale
The scale is above.
@ RightScale
The scale is right.
@ LeftScale
The scale is left.
Base class for scale engines.
QwtTransform * transformation() const
void setTransformation(QwtTransform *)
A Widget which contains a scale.
QwtText title() const
void setTitle(const QString &title)
const QwtScaleDraw * scaleDraw() const
void setLabelAlignment(Qt::Alignment)
Change the alignment for the labels.
void getBorderDistHint(int &start, int &end) const
Calculate a hint for the border distances.
void setBorderDist(int dist1, int dist2)
void setLabelRotation(double rotation)
Change the rotation for the labels. See QwtScaleDraw::setLabelRotation().
void setScaleDiv(const QwtScaleDiv &)
Assign a scale division.
void setScaleDraw(QwtScaleDraw *)
A class representing a text.
Definition: qwt_text.h:52
void setFont(const QFont &)
Definition: qwt_text.cpp:329
@ YRight
Y axis right of the canvas.
Definition: qwt_axis.h:27
@ XTop
X axis above the canvas.
Definition: qwt_axis.h:33
@ XBottom
X axis below the canvas.
Definition: qwt_axis.h:30
@ YLeft
Y axis left of the canvas.
Definition: qwt_axis.h:24
bool isValid(int axisPos)
Definition: qwt_axis.h:45