summaryrefslogtreecommitdiff
path: root/src/libpcp_qwt/src/qwt_plot_axis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpcp_qwt/src/qwt_plot_axis.cpp')
-rw-r--r--src/libpcp_qwt/src/qwt_plot_axis.cpp670
1 files changed, 670 insertions, 0 deletions
diff --git a/src/libpcp_qwt/src/qwt_plot_axis.cpp b/src/libpcp_qwt/src/qwt_plot_axis.cpp
new file mode 100644
index 0000000..66f2fa1
--- /dev/null
+++ b/src/libpcp_qwt/src/qwt_plot_axis.cpp
@@ -0,0 +1,670 @@
+/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
+ * 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_math.h"
+#include "qwt_scale_widget.h"
+#include "qwt_scale_div.h"
+#include "qwt_scale_engine.h"
+
+class QwtPlot::AxisData
+{
+public:
+ bool isEnabled;
+ bool doAutoScale;
+
+ double minValue;
+ double maxValue;
+ double stepSize;
+
+ int maxMajor;
+ int maxMinor;
+
+ QwtScaleDiv scaleDiv;
+ QwtScaleEngine *scaleEngine;
+ QwtScaleWidget *scaleWidget;
+};
+
+//! Initialize axes
+void QwtPlot::initAxesData()
+{
+ int axisId;
+
+ for ( axisId = 0; axisId < axisCnt; axisId++ )
+ d_axisData[axisId] = new AxisData;
+
+ d_axisData[yLeft]->scaleWidget =
+ new QwtScaleWidget( QwtScaleDraw::LeftScale, this );
+ d_axisData[yRight]->scaleWidget =
+ new QwtScaleWidget( QwtScaleDraw::RightScale, this );
+ d_axisData[xTop]->scaleWidget =
+ new QwtScaleWidget( QwtScaleDraw::TopScale, this );
+ d_axisData[xBottom]->scaleWidget =
+ new QwtScaleWidget( QwtScaleDraw::BottomScale, this );
+
+ d_axisData[yLeft]->scaleWidget->setObjectName( "QwtPlotAxisYLeft" );
+ d_axisData[yRight]->scaleWidget->setObjectName( "QwtPlotAxisYRight" );
+ d_axisData[xTop]->scaleWidget->setObjectName( "QwtPlotAxisXTop" );
+ d_axisData[xBottom]->scaleWidget->setObjectName( "QwtPlotAxisXBottom" );
+
+ QFont fscl( fontInfo().family(), 10 );
+ QFont fttl( fontInfo().family(), 12, QFont::Bold );
+
+ for ( axisId = 0; axisId < axisCnt; axisId++ )
+ {
+ AxisData &d = *d_axisData[axisId];
+
+ d.scaleWidget->setFont( fscl );
+ d.scaleWidget->setMargin( 2 );
+
+ QwtText text = d.scaleWidget->title();
+ text.setFont( fttl );
+ d.scaleWidget->setTitle( text );
+
+ d.doAutoScale = true;
+
+ d.minValue = 0.0;
+ d.maxValue = 1000.0;
+ d.stepSize = 0.0;
+
+ d.maxMinor = 5;
+ d.maxMajor = 8;
+
+ d.scaleEngine = new QwtLinearScaleEngine;
+
+ d.scaleDiv.invalidate();
+ }
+
+ d_axisData[yLeft]->isEnabled = true;
+ d_axisData[yRight]->isEnabled = false;
+ d_axisData[xBottom]->isEnabled = true;
+ d_axisData[xTop]->isEnabled = false;
+}
+
+void QwtPlot::deleteAxesData()
+{
+ for ( int axisId = 0; axisId < axisCnt; axisId++ )
+ {
+ delete d_axisData[axisId]->scaleEngine;
+ delete d_axisData[axisId];
+ d_axisData[axisId] = NULL;
+ }
+}
+
+/*!
+ \return specified axis, or NULL if axisId is invalid.
+ \param axisId axis index
+*/
+const QwtScaleWidget *QwtPlot::axisWidget( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->scaleWidget;
+
+ return NULL;
+}
+
+/*!
+ \return specified axis, or NULL if axisId is invalid.
+ \param axisId axis index
+*/
+QwtScaleWidget *QwtPlot::axisWidget( int axisId )
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->scaleWidget;
+
+ return NULL;
+}
+
+/*!
+ Change the scale engine for an axis
+
+ \param axisId axis index
+ \param scaleEngine Scale engine
+
+ \sa axisScaleEngine()
+*/
+void QwtPlot::setAxisScaleEngine( int axisId, QwtScaleEngine *scaleEngine )
+{
+ if ( axisValid( axisId ) && scaleEngine != NULL )
+ {
+ AxisData &d = *d_axisData[axisId];
+
+ delete d.scaleEngine;
+ d.scaleEngine = scaleEngine;
+
+ d.scaleDiv.invalidate();
+
+ autoRefresh();
+ }
+}
+
+/*!
+ \param axisId axis index
+ \return Scale engine for a specific axis
+*/
+QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId )
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->scaleEngine;
+ else
+ return NULL;
+}
+
+/*!
+ \param axisId axis index
+ \return Scale engine for a specific axis
+*/
+const QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->scaleEngine;
+ else
+ return NULL;
+}
+/*!
+ \return \c true if autoscaling is enabled
+ \param axisId axis index
+*/
+bool QwtPlot::axisAutoScale( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->doAutoScale;
+ else
+ return false;
+
+}
+
+/*!
+ \return \c true if a specified axis is enabled
+ \param axisId axis index
+*/
+bool QwtPlot::axisEnabled( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->isEnabled;
+ else
+ return false;
+}
+
+/*!
+ \return the font of the scale labels for a specified axis
+ \param axisId axis index
+*/
+QFont QwtPlot::axisFont( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return axisWidget( axisId )->font();
+ else
+ return QFont();
+
+}
+
+/*!
+ \return the maximum number of major ticks for a specified axis
+ \param axisId axis index
+ \sa setAxisMaxMajor()
+*/
+int QwtPlot::axisMaxMajor( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->maxMajor;
+ else
+ return 0;
+}
+
+/*!
+ \return the maximum number of minor ticks for a specified axis
+ \param axisId axis index
+ \sa setAxisMaxMinor()
+*/
+int QwtPlot::axisMaxMinor( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return d_axisData[axisId]->maxMinor;
+ else
+ return 0;
+}
+
+/*!
+ \brief Return the scale division of a specified axis
+
+ axisScaleDiv(axisId)->lowerBound(), axisScaleDiv(axisId)->upperBound()
+ are the current limits of the axis scale.
+
+ \param axisId axis index
+ \return Scale division
+
+ \sa QwtScaleDiv, setAxisScaleDiv()
+*/
+const QwtScaleDiv *QwtPlot::axisScaleDiv( int axisId ) const
+{
+ if ( !axisValid( axisId ) )
+ return NULL;
+
+ return &d_axisData[axisId]->scaleDiv;
+}
+
+/*!
+ \brief Return the scale division of a specified axis
+
+ axisScaleDiv(axisId)->lowerBound(), axisScaleDiv(axisId)->upperBound()
+ are the current limits of the axis scale.
+
+ \param axisId axis index
+ \return Scale division
+
+ \sa QwtScaleDiv, setAxisScaleDiv()
+*/
+QwtScaleDiv *QwtPlot::axisScaleDiv( int axisId )
+{
+ if ( !axisValid( axisId ) )
+ return NULL;
+
+ return &d_axisData[axisId]->scaleDiv;
+}
+
+/*!
+ \returns the scale draw of a specified axis
+ \param axisId axis index
+ \return specified scaleDraw for axis, or NULL if axis is invalid.
+ \sa QwtScaleDraw
+*/
+const QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId ) const
+{
+ if ( !axisValid( axisId ) )
+ return NULL;
+
+ return axisWidget( axisId )->scaleDraw();
+}
+
+/*!
+ \returns the scale draw of a specified axis
+ \param axisId axis index
+ \return specified scaleDraw for axis, or NULL if axis is invalid.
+ \sa QwtScaleDraw
+*/
+QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId )
+{
+ if ( !axisValid( axisId ) )
+ return NULL;
+
+ return axisWidget( axisId )->scaleDraw();
+}
+
+/*!
+ Return the step size parameter, that has been set
+ in setAxisScale. This doesn't need to be the step size
+ of the current scale.
+
+ \param axisId axis index
+ \return step size parameter value
+
+ \sa setAxisScale()
+*/
+double QwtPlot::axisStepSize( int axisId ) const
+{
+ if ( !axisValid( axisId ) )
+ return 0;
+
+ return d_axisData[axisId]->stepSize;
+}
+
+/*!
+ \brief Return the current interval of the specified axis
+
+ This is only a convenience function for axisScaleDiv( axisId )->interval();
+
+ \param axisId axis index
+ \return Scale interval
+
+ \sa QwtScaleDiv, axisScaleDiv()
+*/
+QwtInterval QwtPlot::axisInterval( int axisId ) const
+{
+ if ( !axisValid( axisId ) )
+ return QwtInterval();
+
+ return d_axisData[axisId]->scaleDiv.interval();
+}
+
+/*!
+ \return the title of a specified axis
+ \param axisId axis index
+*/
+QwtText QwtPlot::axisTitle( int axisId ) const
+{
+ if ( axisValid( axisId ) )
+ return axisWidget( axisId )->title();
+ else
+ return QwtText();
+}
+
+/*!
+ \brief Enable or disable a specified axis
+
+ When an axis is disabled, this only means that it is not
+ visible on the screen. Curves, markers and can be attached
+ to disabled axes, and transformation of screen coordinates
+ into values works as normal.
+
+ Only xBottom and yLeft are enabled by default.
+ \param axisId axis index
+ \param tf \c true (enabled) or \c false (disabled)
+*/
+void QwtPlot::enableAxis( int axisId, bool tf )
+{
+ if ( axisValid( axisId ) && tf != d_axisData[axisId]->isEnabled )
+ {
+ d_axisData[axisId]->isEnabled = tf;
+ updateLayout();
+ }
+}
+
+/*!
+ Transform the x or y coordinate of a position in the
+ drawing region into a value.
+ \param axisId axis index
+ \param pos position
+ \warning The position can be an x or a y coordinate,
+ depending on the specified axis.
+*/
+double QwtPlot::invTransform( int axisId, int pos ) const
+{
+ if ( axisValid( axisId ) )
+ return( canvasMap( axisId ).invTransform( pos ) );
+ else
+ return 0.0;
+}
+
+
+/*!
+ \brief Transform a value into a coordinate in the plotting region
+ \param axisId axis index
+ \param value value
+ \return X or y coordinate in the plotting region corresponding
+ to the value.
+*/
+double QwtPlot::transform( int axisId, double value ) const
+{
+ if ( axisValid( axisId ) )
+ return( canvasMap( axisId ).transform( value ) );
+ else
+ return 0.0;
+}
+
+/*!
+ \brief Change the font of an axis
+ \param axisId axis index
+ \param f font
+ \warning This function changes the font of the tick labels,
+ not of the axis title.
+*/
+void QwtPlot::setAxisFont( int axisId, const QFont &f )
+{
+ if ( axisValid( axisId ) )
+ axisWidget( axisId )->setFont( f );
+}
+
+/*!
+ \brief Enable autoscaling for a specified axis
+
+ This member function is used to switch back to autoscaling mode
+ after a fixed scale has been set. Autoscaling is enabled by default.
+
+ \param axisId axis index
+ \param on On/Off
+ \sa setAxisScale(), setAxisScaleDiv(), updateAxes()
+
+ \note The autoscaling flag has no effect until updateAxes() is executed
+ ( called by replot() ).
+*/
+void QwtPlot::setAxisAutoScale( int axisId, bool on )
+{
+ if ( axisValid( axisId ) && ( d_axisData[axisId]->doAutoScale != on ) )
+ {
+ d_axisData[axisId]->doAutoScale = on;
+ autoRefresh();
+ }
+}
+
+/*!
+ \brief Disable autoscaling and specify a fixed scale for a selected axis.
+ \param axisId axis index
+ \param min
+ \param max minimum and maximum of the scale
+ \param stepSize Major step size. If <code>step == 0</code>, the step size is
+ calculated automatically using the maxMajor setting.
+ \sa setAxisMaxMajor(), setAxisAutoScale(), axisStepSize()
+*/
+void QwtPlot::setAxisScale( int axisId, double min, double max, double stepSize )
+{
+ if ( axisValid( axisId ) )
+ {
+ AxisData &d = *d_axisData[axisId];
+
+ d.doAutoScale = false;
+ d.scaleDiv.invalidate();
+
+ d.minValue = min;
+ d.maxValue = max;
+ d.stepSize = stepSize;
+
+ autoRefresh();
+ }
+}
+
+/*!
+ \brief Disable autoscaling and specify a fixed scale for a selected axis.
+ \param axisId axis index
+ \param scaleDiv Scale division
+ \sa setAxisScale(), setAxisAutoScale()
+*/
+void QwtPlot::setAxisScaleDiv( int axisId, const QwtScaleDiv &scaleDiv )
+{
+ if ( axisValid( axisId ) )
+ {
+ AxisData &d = *d_axisData[axisId];
+
+ d.doAutoScale = false;
+ d.scaleDiv = scaleDiv;
+
+ autoRefresh();
+ }
+}
+
+/*!
+ \brief Set a scale draw
+ \param axisId axis index
+ \param scaleDraw object responsible for drawing scales.
+
+ By passing scaleDraw it is possible to extend QwtScaleDraw
+ functionality and let it take place in QwtPlot. Please note
+ that scaleDraw has to be created with new and will be deleted
+ by the corresponding QwtScale member ( like a child object ).
+
+ \sa QwtScaleDraw, QwtScaleWidget
+ \warning The attributes of scaleDraw will be overwritten by those of the
+ previous QwtScaleDraw.
+*/
+
+void QwtPlot::setAxisScaleDraw( int axisId, QwtScaleDraw *scaleDraw )
+{
+ if ( axisValid( axisId ) )
+ {
+ axisWidget( axisId )->setScaleDraw( scaleDraw );
+ autoRefresh();
+ }
+}
+
+/*!
+ Change the alignment of the tick labels
+ \param axisId axis index
+ \param alignment Or'd Qt::AlignmentFlags see <qnamespace.h>
+ \sa QwtScaleDraw::setLabelAlignment()
+*/
+void QwtPlot::setAxisLabelAlignment( int axisId, Qt::Alignment alignment )
+{
+ if ( axisValid( axisId ) )
+ axisWidget( axisId )->setLabelAlignment( alignment );
+}
+
+/*!
+ Rotate all tick labels
+ \param axisId axis index
+ \param rotation Angle in degrees. When changing the label rotation,
+ the label alignment might be adjusted too.
+ \sa QwtScaleDraw::setLabelRotation(), setAxisLabelAlignment()
+*/
+void QwtPlot::setAxisLabelRotation( int axisId, double rotation )
+{
+ if ( axisValid( axisId ) )
+ axisWidget( axisId )->setLabelRotation( rotation );
+}
+
+/*!
+ Set the maximum number of minor scale intervals for a specified axis
+
+ \param axisId axis index
+ \param maxMinor maximum number of minor steps
+ \sa axisMaxMinor()
+*/
+void QwtPlot::setAxisMaxMinor( int axisId, int maxMinor )
+{
+ if ( axisValid( axisId ) )
+ {
+ maxMinor = qBound( 0, maxMinor, 100 );
+
+ AxisData &d = *d_axisData[axisId];
+ if ( maxMinor != d.maxMinor )
+ {
+ d.maxMinor = maxMinor;
+ d.scaleDiv.invalidate();
+ autoRefresh();
+ }
+ }
+}
+
+/*!
+ Set the maximum number of major scale intervals for a specified axis
+
+ \param axisId axis index
+ \param maxMajor maximum number of major steps
+ \sa axisMaxMajor()
+*/
+void QwtPlot::setAxisMaxMajor( int axisId, int maxMajor )
+{
+ if ( axisValid( axisId ) )
+ {
+ maxMajor = qBound( 1, maxMajor, 10000 );
+
+ AxisData &d = *d_axisData[axisId];
+ if ( maxMajor != d.maxMajor )
+ {
+ d.maxMajor = maxMajor;
+ d.scaleDiv.invalidate();
+ autoRefresh();
+ }
+ }
+}
+
+/*!
+ \brief Change the title of a specified axis
+ \param axisId axis index
+ \param title axis title
+*/
+void QwtPlot::setAxisTitle( int axisId, const QString &title )
+{
+ if ( axisValid( axisId ) )
+ axisWidget( axisId )->setTitle( title );
+}
+
+/*!
+ \brief Change the title of a specified axis
+ \param axisId axis index
+ \param title axis title
+*/
+void QwtPlot::setAxisTitle( int axisId, const QwtText &title )
+{
+ if ( axisValid( axisId ) )
+ axisWidget( axisId )->setTitle( title );
+}
+
+//! Rebuild the scales
+void QwtPlot::updateAxes()
+{
+ // Find bounding interval of the item data
+ // for all axes, where autoscaling is enabled
+
+ QwtInterval intv[axisCnt];
+
+ 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();
+ intv[item->xAxis()] |= QwtInterval( rect.left(), rect.right() );
+ intv[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() );
+ }
+ }
+
+ // Adjust scales
+
+ for ( int axisId = 0; axisId < axisCnt; axisId++ )
+ {
+ AxisData &d = *d_axisData[axisId];
+
+ double minValue = d.minValue;
+ double maxValue = d.maxValue;
+ double stepSize = d.stepSize;
+
+ if ( d.doAutoScale && intv[axisId].isValid() )
+ {
+ d.scaleDiv.invalidate();
+
+ minValue = intv[axisId].minValue();
+ maxValue = intv[axisId].maxValue();
+
+ d.scaleEngine->autoScale( d.maxMajor,
+ minValue, maxValue, stepSize );
+ }
+ if ( !d.scaleDiv.isValid() )
+ {
+ d.scaleDiv = d.scaleEngine->divideScale(
+ minValue, maxValue,
+ d.maxMajor, d.maxMinor, stepSize );
+ }
+
+ QwtScaleWidget *scaleWidget = axisWidget( axisId );
+ scaleWidget->setScaleDiv(
+ d.scaleEngine->transformation(), d.scaleDiv );
+
+ int startDist, endDist;
+ scaleWidget->getBorderDistHint( startDist, endDist );
+ scaleWidget->setBorderDist( startDist, endDist );
+ }
+
+ for ( it = itmList.begin(); it != itmList.end(); ++it )
+ {
+ QwtPlotItem *item = *it;
+ item->updateScaleDiv( *axisScaleDiv( item->xAxis() ),
+ *axisScaleDiv( item->yAxis() ) );
+ }
+}
+