Qwt User's Guide 6.3.0
Loading...
Searching...
No Matches
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
17namespace
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
80class 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
107void 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
115void QwtPlot::deleteAxesData()
116{
117 delete m_scaleData;
118 m_scaleData = NULL;
119}
120
132bool QwtPlot::isAxisValid( QwtAxisId axisId ) const
133{
134 return QwtAxis::isValid( axisId );
135}
136
141const 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
169void 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
202const QwtScaleEngine* QwtPlot::axisScaleEngine( QwtAxisId axisId ) const
203{
204 if ( isAxisValid( axisId ) )
205 return m_scaleData->axisData( axisId ).scaleEngine;
206 else
207 return NULL;
208}
213bool QwtPlot::axisAutoScale( QwtAxisId axisId ) const
214{
215 if ( isAxisValid( axisId ) )
216 return m_scaleData->axisData( axisId ).doAutoScale;
217 else
218 return false;
219}
220
225bool QwtPlot::isAxisVisible( QwtAxisId axisId ) const
226{
227 if ( isAxisValid( axisId ) )
228 return m_scaleData->axisData( axisId ).isVisible;
229 else
230 return false;
231}
232
237QFont QwtPlot::axisFont( QwtAxisId axisId ) const
238{
239 if ( isAxisValid( axisId ) )
240 return axisWidget( axisId )->font();
241 else
242 return QFont();
243
244}
245
251int QwtPlot::axisMaxMajor( QwtAxisId axisId ) const
252{
253 if ( isAxisValid( axisId ) )
254 return m_scaleData->axisData( axisId ).maxMajor;
255 else
256 return 0;
257}
258
264int QwtPlot::axisMaxMinor( QwtAxisId axisId ) const
265{
266 if ( isAxisValid( axisId ) )
267 return m_scaleData->axisData( axisId ).maxMinor;
268 else
269 return 0;
270}
271
283const QwtScaleDiv& QwtPlot::axisScaleDiv( QwtAxisId axisId ) const
284{
285 if ( isAxisValid( axisId ) )
286 return m_scaleData->axisData( axisId ).scaleDiv;
287
288 static QwtScaleDiv dummyScaleDiv;
289 return dummyScaleDiv;
290}
291
298const QwtScaleDraw* QwtPlot::axisScaleDraw( QwtAxisId axisId ) const
299{
300 if ( !isAxisValid( axisId ) )
301 return NULL;
302
303 return axisWidget( axisId )->scaleDraw();
304}
305
313{
314 if ( !isAxisValid( axisId ) )
315 return NULL;
316
317 return axisWidget( axisId )->scaleDraw();
318}
319
330double QwtPlot::axisStepSize( QwtAxisId axisId ) const
331{
332 if ( !isAxisValid( axisId ) )
333 return 0;
334
335 return m_scaleData->axisData( axisId ).stepSize;
336}
337
348QwtInterval QwtPlot::axisInterval( QwtAxisId axisId ) const
349{
350 if ( !isAxisValid( axisId ) )
351 return QwtInterval();
352
353 return m_scaleData->axisData( axisId ).scaleDiv.interval();
354}
355
360QwtText QwtPlot::axisTitle( QwtAxisId axisId ) const
361{
362 if ( isAxisValid( axisId ) )
363 return axisWidget( axisId )->title();
364 else
365 return QwtText();
366}
367
380void QwtPlot::setAxisVisible( QwtAxisId axisId, bool on )
381{
382 if ( isAxisValid( axisId ) && on != m_scaleData->axisData( axisId ).isVisible )
383 {
384 m_scaleData->axisData( axisId ).isVisible = on;
385 updateLayout();
386 }
387}
388
401double QwtPlot::invTransform( QwtAxisId axisId, double pos ) const
402{
403 if ( isAxisValid( axisId ) )
404 return( canvasMap( axisId ).invTransform( pos ) );
405 else
406 return 0.0;
407}
408
409
418double QwtPlot::transform( QwtAxisId axisId, double value ) const
419{
420 if ( isAxisValid( axisId ) )
421 return( canvasMap( axisId ).transform( value ) );
422 else
423 return 0.0;
424}
425
434void QwtPlot::setAxisFont( QwtAxisId axisId, const QFont& font )
435{
436 if ( isAxisValid( axisId ) )
437 axisWidget( axisId )->setFont( font );
438}
439
453void QwtPlot::setAxisAutoScale( QwtAxisId axisId, bool on )
454{
455 if ( isAxisValid( axisId ) && ( m_scaleData->axisData( axisId ).doAutoScale != on ) )
456 {
457 m_scaleData->axisData( axisId ).doAutoScale = on;
458 autoRefresh();
459 }
460}
461
477void QwtPlot::setAxisScale( QwtAxisId axisId, double min, double max, double stepSize )
478{
479 if ( isAxisValid( axisId ) )
480 {
481 AxisData& d = m_scaleData->axisData( axisId );
482
483 d.doAutoScale = false;
484 d.isValid = false;
485
486 d.minValue = min;
487 d.maxValue = max;
488 d.stepSize = stepSize;
489
490 autoRefresh();
491 }
492}
493
506void QwtPlot::setAxisScaleDiv( QwtAxisId axisId, const QwtScaleDiv& scaleDiv )
507{
508 if ( isAxisValid( axisId ) )
509 {
510 AxisData& d = m_scaleData->axisData( axisId );
511
512 d.doAutoScale = false;
513 d.scaleDiv = scaleDiv;
514 d.isValid = true;
515
516 autoRefresh();
517 }
518}
519
536void QwtPlot::setAxisScaleDraw( QwtAxisId axisId, QwtScaleDraw* scaleDraw )
537{
538 if ( isAxisValid( axisId ) )
539 {
540 axisWidget( axisId )->setScaleDraw( scaleDraw );
541 autoRefresh();
542 }
543}
544
553void QwtPlot::setAxisLabelAlignment( QwtAxisId axisId, Qt::Alignment alignment )
554{
555 if ( isAxisValid( axisId ) )
556 axisWidget( axisId )->setLabelAlignment( alignment );
557}
558
568void QwtPlot::setAxisLabelRotation( QwtAxisId axisId, double rotation )
569{
570 if ( isAxisValid( axisId ) )
571 axisWidget( axisId )->setLabelRotation( rotation );
572}
573
582void QwtPlot::setAxisMaxMinor( QwtAxisId axisId, int maxMinor )
583{
584 if ( isAxisValid( axisId ) )
585 {
586 maxMinor = qBound( 0, maxMinor, 100 );
587
588 AxisData& d = m_scaleData->axisData( axisId );
589 if ( maxMinor != d.maxMinor )
590 {
591 d.maxMinor = maxMinor;
592 d.isValid = false;
593 autoRefresh();
594 }
595 }
596}
597
606void QwtPlot::setAxisMaxMajor( QwtAxisId axisId, int maxMajor )
607{
608 if ( isAxisValid( axisId ) )
609 {
610 maxMajor = qBound( 1, maxMajor, 10000 );
611
612 AxisData& d = m_scaleData->axisData( axisId );
613 if ( maxMajor != d.maxMajor )
614 {
615 d.maxMajor = maxMajor;
616 d.isValid = false;
617 autoRefresh();
618 }
619 }
620}
621
628void QwtPlot::setAxisTitle( QwtAxisId axisId, const QString& title )
629{
630 if ( isAxisValid( axisId ) )
631 axisWidget( axisId )->setTitle( title );
632}
633
640void QwtPlot::setAxisTitle( QwtAxisId axisId, const QwtText& title )
641{
642 if ( isAxisValid( axisId ) )
643 axisWidget( axisId )->setTitle( title );
644}
645
671{
672 // Find bounding interval of the item data
673 // for all axes, where autoscaling is enabled
674
675 QwtInterval boundingIntervals[QwtAxis::AxisPositions];
676
677 const QwtPlotItemList& itmList = itemList();
678
679 QwtPlotItemIterator it;
680 for ( it = itmList.begin(); it != itmList.end(); ++it )
681 {
682 const QwtPlotItem* item = *it;
683
685 continue;
686
687 if ( !item->isVisible() )
688 continue;
689
690 const QwtAxisId xAxis = item->xAxis();
691 const QwtAxisId yAxis = item->yAxis();
692
693 if ( axisAutoScale( xAxis ) || axisAutoScale( yAxis ) )
694 {
695 const QRectF rect = item->boundingRect();
696
697 if ( axisAutoScale( xAxis ) && rect.width() >= 0.0 )
698 boundingIntervals[xAxis] |= QwtInterval( rect.left(), rect.right() );
699
700 if ( axisAutoScale( yAxis ) && rect.height() >= 0.0 )
701 boundingIntervals[yAxis] |= QwtInterval( rect.top(), rect.bottom() );
702 }
703 }
704
705 // Adjust scales
706
707 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
708 {
709 {
710 const QwtAxisId axisId( axisPos );
711
712 AxisData& d = m_scaleData->axisData( axisId );
713
714 double minValue = d.minValue;
715 double maxValue = d.maxValue;
716 double stepSize = d.stepSize;
717
718 const QwtInterval& interval = boundingIntervals[axisId];
719
720 if ( d.doAutoScale && interval.isValid() )
721 {
722 d.isValid = false;
723
724 minValue = interval.minValue();
725 maxValue = interval.maxValue();
726
727 d.scaleEngine->autoScale( d.maxMajor,
728 minValue, maxValue, stepSize );
729 }
730 if ( !d.isValid )
731 {
732 d.scaleDiv = d.scaleEngine->divideScale(
733 minValue, maxValue, d.maxMajor, d.maxMinor, stepSize );
734 d.isValid = true;
735 }
736
737 QwtScaleWidget* scaleWidget = axisWidget( axisId );
738 scaleWidget->setScaleDiv( d.scaleDiv );
739
740 int startDist, endDist;
741 scaleWidget->getBorderDistHint( startDist, endDist );
742 scaleWidget->setBorderDist( startDist, endDist );
743 }
744 }
745
746 for ( it = itmList.begin(); it != itmList.end(); ++it )
747 {
748 QwtPlotItem* item = *it;
750 {
751 item->updateScaleDiv( axisScaleDiv( item->xAxis() ),
752 axisScaleDiv( item->yAxis() ) );
753 }
754 }
755}
A class representing an interval.
double minValue() const
double maxValue() const
bool isValid() const
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.
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.
QwtInterval interval() const
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
virtual void autoScale(int maxNumSteps, double &x1, double &x2, double &stepSize) const =0
virtual QwtScaleDiv divideScale(double x1, double x2, int maxMajorSteps, int maxMinorSteps, double stepSize=0.0) const =0
Calculate a scale division.
A Widget which contains a scale.
QwtText title() const
void setTitle(const QString &title)
const QwtScaleDraw * scaleDraw() const
void setTransformation(QwtTransform *)
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