qwt_plot_axis.cpp
/******************************************************************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_plot.h"
#include "qwt_scale_widget.h"
#include "qwt_scale_map.h"
#include "qwt_scale_div.h"
#include "qwt_scale_engine.h"
#include "qwt_interval.h"
namespace
{
class AxisData
{
public:
AxisData()
: isVisible( true )
, doAutoScale( true )
, minValue( 0.0 )
, maxValue( 1000.0 )
, stepSize( 0.0 )
, maxMajor( 8 )
, maxMinor( 5 )
, isValid( false )
, scaleEngine( new QwtLinearScaleEngine() )
, scaleWidget( NULL )
{
}
~AxisData()
{
delete scaleEngine;
}
void initWidget( QwtScaleDraw::Alignment align, const QString& name, QwtPlot* plot )
{
scaleWidget = new QwtScaleWidget( align, plot );
scaleWidget->setObjectName( name );
#if 1
// better find the font sizes from the application font
const QFont fscl( plot->fontInfo().family(), 10 );
const QFont fttl( plot->fontInfo().family(), 12, QFont::Bold );
#endif
scaleWidget->setTransformation( scaleEngine->transformation() );
scaleWidget->setFont( fscl );
scaleWidget->setMargin( 2 );
QwtText text = scaleWidget->title();
text.setFont( fttl );
scaleWidget->setTitle( text );
}
bool isVisible;
bool doAutoScale;
double minValue;
double maxValue;
double stepSize;
int maxMajor;
int maxMinor;
bool isValid;
QwtScaleDiv scaleDiv;
QwtScaleEngine* scaleEngine;
QwtScaleWidget* scaleWidget;
};
}
class QwtPlot::ScaleData
{
public:
ScaleData( QwtPlot* plot )
{
using namespace QwtAxis;
m_axisData[YLeft].initWidget( QwtScaleDraw::LeftScale, "QwtPlotAxisYLeft", plot );
m_axisData[YRight].initWidget( QwtScaleDraw::RightScale, "QwtPlotAxisYRight", plot );
m_axisData[XTop].initWidget( QwtScaleDraw::TopScale, "QwtPlotAxisXTop", plot );
m_axisData[XBottom].initWidget( QwtScaleDraw::BottomScale, "QwtPlotAxisXBottom", plot );
}
inline AxisData& axisData( QwtAxisId axisId )
{
return m_axisData[ axisId ];
}
inline const AxisData& axisData( QwtAxisId axisId ) const
{
return m_axisData[ axisId ];
}
private:
AxisData m_axisData[ QwtAxis::AxisPositions ];
};
void QwtPlot::initAxesData()
{
m_scaleData = new ScaleData( this );
m_scaleData->axisData( QwtAxis::YRight ).isVisible = false;
m_scaleData->axisData( QwtAxis::XTop ).isVisible = false;
}
void QwtPlot::deleteAxesData()
{
delete m_scaleData;
m_scaleData = NULL;
}
bool QwtPlot::isAxisValid( QwtAxisId axisId ) const
{
return QwtAxis::isValid( axisId );
}
const QwtScaleWidget* QwtPlot::axisWidget( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).scaleWidget;
return NULL;
}
QwtScaleWidget* QwtPlot::axisWidget( QwtAxisId axisId )
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).scaleWidget;
return NULL;
}
void QwtPlot::setAxisScaleEngine( QwtAxisId axisId, QwtScaleEngine* scaleEngine )
{
if ( isAxisValid( axisId ) && scaleEngine != NULL )
{
AxisData& d = m_scaleData->axisData( axisId );
delete d.scaleEngine;
d.scaleEngine = scaleEngine;
d.scaleWidget->setTransformation( scaleEngine->transformation() );
d.isValid = false;
autoRefresh();
}
}
QwtScaleEngine* QwtPlot::axisScaleEngine( QwtAxisId axisId )
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).scaleEngine;
else
return NULL;
}
const QwtScaleEngine* QwtPlot::axisScaleEngine( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).scaleEngine;
else
return NULL;
}
bool QwtPlot::axisAutoScale( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).doAutoScale;
else
return false;
}
bool QwtPlot::isAxisVisible( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).isVisible;
else
return false;
}
QFont QwtPlot::axisFont( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return axisWidget( axisId )->font();
else
return QFont();
}
int QwtPlot::axisMaxMajor( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).maxMajor;
else
return 0;
}
int QwtPlot::axisMaxMinor( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return m_scaleData->axisData( axisId ).maxMinor;
else
return 0;
}
const QwtScaleDiv& QwtPlot::axisScaleDiv( QwtAxisId axisId ) const
{
return m_scaleData->axisData( axisId ).scaleDiv;
}
const QwtScaleDraw* QwtPlot::axisScaleDraw( QwtAxisId axisId ) const
{
if ( !isAxisValid( axisId ) )
return NULL;
return axisWidget( axisId )->scaleDraw();
}
QwtScaleDraw* QwtPlot::axisScaleDraw( QwtAxisId axisId )
{
if ( !isAxisValid( axisId ) )
return NULL;
return axisWidget( axisId )->scaleDraw();
}
double QwtPlot::axisStepSize( QwtAxisId axisId ) const
{
if ( !isAxisValid( axisId ) )
return 0;
return m_scaleData->axisData( axisId ).stepSize;
}
QwtInterval QwtPlot::axisInterval( QwtAxisId axisId ) const
{
if ( !isAxisValid( axisId ) )
return QwtInterval();
return m_scaleData->axisData( axisId ).scaleDiv.interval();
}
QwtText QwtPlot::axisTitle( QwtAxisId axisId ) const
{
if ( isAxisValid( axisId ) )
return axisWidget( axisId )->title();
else
return QwtText();
}
void QwtPlot::setAxisVisible( QwtAxisId axisId, bool on )
{
if ( isAxisValid( axisId ) && on != m_scaleData->axisData( axisId ).isVisible )
{
m_scaleData->axisData( axisId ).isVisible = on;
updateLayout();
}
}
double QwtPlot::invTransform( QwtAxisId axisId, double pos ) const
{
if ( isAxisValid( axisId ) )
return( canvasMap( axisId ).invTransform( pos ) );
else
return 0.0;
}
double QwtPlot::transform( QwtAxisId axisId, double value ) const
{
if ( isAxisValid( axisId ) )
return( canvasMap( axisId ).transform( value ) );
else
return 0.0;
}
void QwtPlot::setAxisFont( QwtAxisId axisId, const QFont& font )
{
if ( isAxisValid( axisId ) )
axisWidget( axisId )->setFont( font );
}
void QwtPlot::setAxisAutoScale( QwtAxisId axisId, bool on )
{
if ( isAxisValid( axisId ) && ( m_scaleData->axisData( axisId ).doAutoScale != on ) )
{
m_scaleData->axisData( axisId ).doAutoScale = on;
autoRefresh();
}
}
void QwtPlot::setAxisScale( QwtAxisId axisId, double min, double max, double stepSize )
{
if ( isAxisValid( axisId ) )
{
AxisData& d = m_scaleData->axisData( axisId );
d.doAutoScale = false;
d.isValid = false;
d.minValue = min;
d.maxValue = max;
d.stepSize = stepSize;
autoRefresh();
}
}
void QwtPlot::setAxisScaleDiv( QwtAxisId axisId, const QwtScaleDiv& scaleDiv )
{
if ( isAxisValid( axisId ) )
{
AxisData& d = m_scaleData->axisData( axisId );
d.doAutoScale = false;
d.scaleDiv = scaleDiv;
d.isValid = true;
autoRefresh();
}
}
void QwtPlot::setAxisScaleDraw( QwtAxisId axisId, QwtScaleDraw* scaleDraw )
{
if ( isAxisValid( axisId ) )
{
axisWidget( axisId )->setScaleDraw( scaleDraw );
autoRefresh();
}
}
void QwtPlot::setAxisLabelAlignment( QwtAxisId axisId, Qt::Alignment alignment )
{
if ( isAxisValid( axisId ) )
axisWidget( axisId )->setLabelAlignment( alignment );
}
void QwtPlot::setAxisLabelRotation( QwtAxisId axisId, double rotation )
{
if ( isAxisValid( axisId ) )
axisWidget( axisId )->setLabelRotation( rotation );
}
void QwtPlot::setAxisMaxMinor( QwtAxisId axisId, int maxMinor )
{
if ( isAxisValid( axisId ) )
{
maxMinor = qBound( 0, maxMinor, 100 );
AxisData& d = m_scaleData->axisData( axisId );
if ( maxMinor != d.maxMinor )
{
d.maxMinor = maxMinor;
d.isValid = false;
autoRefresh();
}
}
}
void QwtPlot::setAxisMaxMajor( QwtAxisId axisId, int maxMajor )
{
if ( isAxisValid( axisId ) )
{
maxMajor = qBound( 1, maxMajor, 10000 );
AxisData& d = m_scaleData->axisData( axisId );
if ( maxMajor != d.maxMajor )
{
d.maxMajor = maxMajor;
d.isValid = false;
autoRefresh();
}
}
}
void QwtPlot::setAxisTitle( QwtAxisId axisId, const QString& title )
{
if ( isAxisValid( axisId ) )
axisWidget( axisId )->setTitle( title );
}
void QwtPlot::setAxisTitle( QwtAxisId axisId, const QwtText& title )
{
if ( isAxisValid( axisId ) )
axisWidget( axisId )->setTitle( title );
}
void QwtPlot::updateAxes()
{
// Find bounding interval of the item data
// for all axes, where autoscaling is enabled
QwtInterval boundingIntervals[QwtAxis::AxisPositions];
const QwtPlotItemList& itmList = itemList();
QwtPlotItemIterator it;
for ( it = itmList.begin(); it != itmList.end(); ++it )
{
const QwtPlotItem* item = *it;
if ( !item->testItemAttribute( QwtPlotItem::AutoScale ) )
continue;
if ( !item->isVisible() )
continue;
if ( axisAutoScale( item->xAxis() ) || axisAutoScale( item->yAxis() ) )
{
const QRectF rect = item->boundingRect();
if ( rect.width() >= 0.0 )
boundingIntervals[item->xAxis()] |= QwtInterval( rect.left(), rect.right() );
if ( rect.height() >= 0.0 )
boundingIntervals[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() );
}
}
// Adjust scales
for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
{
{
const QwtAxisId axisId( axisPos );
AxisData& d = m_scaleData->axisData( axisId );
double minValue = d.minValue;
double maxValue = d.maxValue;
double stepSize = d.stepSize;
const QwtInterval& interval = boundingIntervals[axisId];
if ( d.doAutoScale && interval.isValid() )
{
d.isValid = false;
minValue = interval.minValue();
maxValue = interval.maxValue();
d.scaleEngine->autoScale( d.maxMajor,
minValue, maxValue, stepSize );
}
if ( !d.isValid )
{
d.scaleDiv = d.scaleEngine->divideScale(
minValue, maxValue, d.maxMajor, d.maxMinor, stepSize );
d.isValid = true;
}
QwtScaleWidget* scaleWidget = axisWidget( axisId );
scaleWidget->setScaleDiv( d.scaleDiv );
int startDist, endDist;
scaleWidget->getBorderDistHint( startDist, endDist );
scaleWidget->setBorderDist( startDist, endDist );
}
}
for ( it = itmList.begin(); it != itmList.end(); ++it )
{
QwtPlotItem* item = *it;
if ( item->testItemInterest( QwtPlotItem::ScaleInterest ) )
{
item->updateScaleDiv( axisScaleDiv( item->xAxis() ),
axisScaleDiv( item->yAxis() ) );
}
}
}
QList< QwtPlotItem * >
QwtInterval
A class representing an interval.
Definition: qwt_interval.h:23
QwtInterval::minValue
double minValue() const
Definition: qwt_interval.h:192
QwtInterval::maxValue
double maxValue() const
Definition: qwt_interval.h:198
QwtInterval::isValid
bool isValid() const
Definition: qwt_interval.h:210
QwtLinearScaleEngine
A scale engine for linear scales.
Definition: qwt_scale_engine.h:152
QwtPlotDict::itemList
const QwtPlotItemList & itemList() const
A QwtPlotItemList of all attached plot items.
Definition: qwt_plot_dict.cpp:166
QwtPlot
A 2-D plotting widget.
Definition: qwt_plot.h:79
QwtPlot::transform
double transform(QwtAxisId, double value) const
Transform a value into a coordinate in the plotting region.
Definition: qwt_plot_axis.cpp:414
QwtPlot::setAxisVisible
void setAxisVisible(QwtAxisId, bool on=true)
Hide or show a specified axis.
Definition: qwt_plot_axis.cpp:376
QwtPlot::axisFont
QFont axisFont(QwtAxisId) const
Definition: qwt_plot_axis.cpp:237
QwtPlot::updateAxes
void updateAxes()
Rebuild the axes scales.
Definition: qwt_plot_axis.cpp:666
QwtPlot::setAxisLabelAlignment
void setAxisLabelAlignment(QwtAxisId, Qt::Alignment)
Definition: qwt_plot_axis.cpp:549
QwtPlot::setAxisScale
void setAxisScale(QwtAxisId, double min, double max, double stepSize=0)
Disable autoscaling and specify a fixed scale for a selected axis.
Definition: qwt_plot_axis.cpp:473
QwtPlot::axisScaleEngine
QwtScaleEngine * axisScaleEngine(QwtAxisId)
Definition: qwt_plot_axis.cpp:190
QwtPlot::axisStepSize
double axisStepSize(QwtAxisId) const
Return the step size parameter that has been set in setAxisScale.
Definition: qwt_plot_axis.cpp:326
QwtPlot::setAxisScaleDraw
void setAxisScaleDraw(QwtAxisId, QwtScaleDraw *)
Set a scale draw.
Definition: qwt_plot_axis.cpp:532
QwtPlot::setAxisLabelRotation
void setAxisLabelRotation(QwtAxisId, double rotation)
Definition: qwt_plot_axis.cpp:564
QwtPlot::setAxisFont
void setAxisFont(QwtAxisId, const QFont &)
Change the font of an axis.
Definition: qwt_plot_axis.cpp:430
QwtPlot::setAxisTitle
void setAxisTitle(QwtAxisId, const QString &)
Change the title of a specified axis.
Definition: qwt_plot_axis.cpp:624
QwtPlot::setAxisAutoScale
void setAxisAutoScale(QwtAxisId, bool on=true)
Enable autoscaling for a specified axis.
Definition: qwt_plot_axis.cpp:449
QwtPlot::setAxisScaleEngine
void setAxisScaleEngine(QwtAxisId, QwtScaleEngine *)
Definition: qwt_plot_axis.cpp:169
QwtPlot::setAxisMaxMajor
void setAxisMaxMajor(QwtAxisId, int maxMajor)
Definition: qwt_plot_axis.cpp:602
QwtPlot::isAxisVisible
bool isAxisVisible(QwtAxisId) const
Definition: qwt_plot_axis.cpp:225
QwtPlot::axisAutoScale
bool axisAutoScale(QwtAxisId) const
Definition: qwt_plot_axis.cpp:213
QwtPlot::axisInterval
QwtInterval axisInterval(QwtAxisId) const
Return the current interval of the specified axis.
Definition: qwt_plot_axis.cpp:344
QwtPlot::invTransform
double invTransform(QwtAxisId, double pos) const
Definition: qwt_plot_axis.cpp:397
QwtPlot::axisTitle
QwtText axisTitle(QwtAxisId) const
Definition: qwt_plot_axis.cpp:356
QwtPlot::isAxisValid
bool isAxisValid(QwtAxisId) const
Definition: qwt_plot_axis.cpp:132
QwtPlot::setAxisMaxMinor
void setAxisMaxMinor(QwtAxisId, int maxMinor)
Definition: qwt_plot_axis.cpp:578
QwtPlot::axisWidget
const QwtScaleWidget * axisWidget(QwtAxisId) const
Definition: qwt_plot_axis.cpp:141
QwtPlot::canvasMap
virtual QwtScaleMap canvasMap(QwtAxisId) const
Definition: qwt_plot.cpp:800
QwtPlot::axisMaxMinor
int axisMaxMinor(QwtAxisId) const
Definition: qwt_plot_axis.cpp:264
QwtPlot::updateLayout
virtual void updateLayout()
Adjust plot content to its current size.
Definition: qwt_plot.cpp:577
QwtPlot::autoRefresh
void autoRefresh()
Replots the plot if autoReplot() is true.
Definition: qwt_plot.cpp:289
QwtPlot::axisScaleDiv
const QwtScaleDiv & axisScaleDiv(QwtAxisId) const
Return the scale division of a specified axis.
Definition: qwt_plot_axis.cpp:283
QwtPlot::setAxisScaleDiv
void setAxisScaleDiv(QwtAxisId, const QwtScaleDiv &)
Disable autoscaling and specify a fixed scale for a selected axis.
Definition: qwt_plot_axis.cpp:502
QwtPlot::axisScaleDraw
const QwtScaleDraw * axisScaleDraw(QwtAxisId) const
Return the scale draw of a specified axis.
Definition: qwt_plot_axis.cpp:294
QwtPlot::title
QwtText title() const
Definition: qwt_plot.cpp:351
QwtPlot::axisMaxMajor
int axisMaxMajor(QwtAxisId) const
Definition: qwt_plot_axis.cpp:251
QwtPlotItem
Base class for items on the plot canvas.
Definition: qwt_plot_item.h:67
QwtPlotItem::yAxis
QwtAxisId yAxis() const
Return yAxis.
Definition: qwt_plot_item.cpp:559
QwtPlotItem::isVisible
bool isVisible() const
Definition: qwt_plot_item.cpp:470
QwtPlotItem::xAxis
QwtAxisId xAxis() const
Return xAxis.
Definition: qwt_plot_item.cpp:553
QwtPlotItem::testItemInterest
bool testItemInterest(ItemInterest) const
Definition: qwt_plot_item.cpp:299
QwtPlotItem::updateScaleDiv
virtual void updateScaleDiv(const QwtScaleDiv &, const QwtScaleDiv &)
Update the item to changes of the axes scale division.
Definition: qwt_plot_item.cpp:665
QwtPlotItem::testItemAttribute
bool testItemAttribute(ItemAttribute) const
Definition: qwt_plot_item.cpp:266
QwtPlotItem::AutoScale
@ AutoScale
Definition: qwt_plot_item.h:157
QwtPlotItem::boundingRect
virtual QRectF boundingRect() const
Definition: qwt_plot_item.cpp:568
QwtPlotItem::ScaleInterest
@ ScaleInterest
Definition: qwt_plot_item.h:185
QwtScaleDiv
A class representing a scale division.
Definition: qwt_scale_div.h:34
QwtScaleDraw
A class for drawing scales.
Definition: qwt_scale_draw.h:36
QwtScaleDraw::Alignment
Alignment
Definition: qwt_scale_draw.h:43
QwtScaleDraw::BottomScale
@ BottomScale
The scale is below.
Definition: qwt_scale_draw.h:45
QwtScaleDraw::TopScale
@ TopScale
The scale is above.
Definition: qwt_scale_draw.h:48
QwtScaleDraw::RightScale
@ RightScale
The scale is right.
Definition: qwt_scale_draw.h:54
QwtScaleDraw::LeftScale
@ LeftScale
The scale is left.
Definition: qwt_scale_draw.h:51
QwtScaleEngine
Base class for scale engines.
Definition: qwt_scale_engine.h:46
QwtScaleEngine::transformation
QwtTransform * transformation() const
Definition: qwt_scale_engine.cpp:265
QwtScaleEngine::setTransformation
void setTransformation(QwtTransform *)
Definition: qwt_scale_engine.cpp:248
QwtScaleWidget
A Widget which contains a scale.
Definition: qwt_scale_widget.h:35
QwtScaleWidget::title
QwtText title() const
Definition: qwt_scale_widget.cpp:371
QwtScaleWidget::setTitle
void setTitle(const QString &title)
Definition: qwt_scale_widget.cpp:172
QwtScaleWidget::scaleDraw
const QwtScaleDraw * scaleDraw() const
Definition: qwt_scale_widget.cpp:353
QwtScaleWidget::setLabelAlignment
void setLabelAlignment(Qt::Alignment)
Change the alignment for the labels.
Definition: qwt_scale_widget.cpp:295
QwtScaleWidget::getBorderDistHint
void getBorderDistHint(int &start, int &end) const
Calculate a hint for the border distances.
Definition: qwt_scale_widget.cpp:814
QwtScaleWidget::setBorderDist
void setBorderDist(int dist1, int dist2)
Definition: qwt_scale_widget.cpp:250
QwtScaleWidget::setLabelRotation
void setLabelRotation(double rotation)
Change the rotation for the labels. See QwtScaleDraw::setLabelRotation().
Definition: qwt_scale_widget.cpp:308
QwtScaleWidget::setScaleDiv
void setScaleDiv(const QwtScaleDiv &)
Assign a scale division.
Definition: qwt_scale_widget.cpp:866
QwtScaleWidget::setScaleDraw
void setScaleDraw(QwtScaleDraw *)
Definition: qwt_scale_widget.cpp:325
QwtText
A class representing a text.
Definition: qwt_text.h:52
QwtText::setFont
void setFont(const QFont &)
Definition: qwt_text.cpp:329
QwtAxis
Definition: qwt_axis.h:19
QwtAxis::YRight
@ YRight
Y axis right of the canvas.
Definition: qwt_axis.h:27
QwtAxis::XTop
@ XTop
X axis above the canvas.
Definition: qwt_axis.h:33
QwtAxis::XBottom
@ XBottom
X axis below the canvas.
Definition: qwt_axis.h:30
QwtAxis::YLeft
@ YLeft
Y axis left of the canvas.
Definition: qwt_axis.h:24
QwtAxis::isValid
bool isValid(int axisPos)
Definition: qwt_axis.h:45