Skip to content
qwt_plot_axis.cpp 17.7 KiB
Newer Older
pixhawk's avatar
pixhawk committed
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
pixhawk's avatar
pixhawk committed
 * 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;

Bryant's avatar
Bryant committed
    bool isValid;

pixhawk's avatar
pixhawk committed
    QwtScaleDiv scaleDiv;
    QwtScaleEngine *scaleEngine;
    QwtScaleWidget *scaleWidget;
};

//! Initialize axes
void QwtPlot::initAxesData()
{
    int axisId;

Bryant's avatar
Bryant committed
    for ( axisId = 0; axisId < axisCnt; axisId++ )
pixhawk's avatar
pixhawk committed
        d_axisData[axisId] = new AxisData;

    d_axisData[yLeft]->scaleWidget =
Bryant's avatar
Bryant committed
        new QwtScaleWidget( QwtScaleDraw::LeftScale, this );
    d_axisData[yRight]->scaleWidget =
Bryant's avatar
Bryant committed
        new QwtScaleWidget( QwtScaleDraw::RightScale, this );
    d_axisData[xTop]->scaleWidget =
Bryant's avatar
Bryant committed
        new QwtScaleWidget( QwtScaleDraw::TopScale, this );
    d_axisData[xBottom]->scaleWidget =
Bryant's avatar
Bryant committed
        new QwtScaleWidget( QwtScaleDraw::BottomScale, this );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    d_axisData[yLeft]->scaleWidget->setObjectName( "QwtPlotAxisYLeft" );
    d_axisData[yRight]->scaleWidget->setObjectName( "QwtPlotAxisYRight" );
    d_axisData[xTop]->scaleWidget->setObjectName( "QwtPlotAxisXTop" );
    d_axisData[xBottom]->scaleWidget->setObjectName( "QwtPlotAxisXBottom" );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
#if 1
    // better find the font sizes from the application font
    QFont fscl( fontInfo().family(), 10 );
    QFont fttl( fontInfo().family(), 12, QFont::Bold );
#endif
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    for ( axisId = 0; axisId < axisCnt; axisId++ )
    {
pixhawk's avatar
pixhawk committed
        AxisData &d = *d_axisData[axisId];

Bryant's avatar
Bryant committed
        d.scaleEngine = new QwtLinearScaleEngine;

        d.scaleWidget->setTransformation( 
            d.scaleEngine->transformation() );

        d.scaleWidget->setFont( fscl );
        d.scaleWidget->setMargin( 2 );
pixhawk's avatar
pixhawk committed

        QwtText text = d.scaleWidget->title();
Bryant's avatar
Bryant committed
        text.setFont( fttl );
        d.scaleWidget->setTitle( text );
pixhawk's avatar
pixhawk committed

        d.doAutoScale = true;

        d.minValue = 0.0;
        d.maxValue = 1000.0;
        d.stepSize = 0.0;

        d.maxMinor = 5;
        d.maxMajor = 8;


Bryant's avatar
Bryant committed
        d.isValid = false;
pixhawk's avatar
pixhawk committed
    }

    d_axisData[yLeft]->isEnabled = true;
    d_axisData[yRight]->isEnabled = false;
    d_axisData[xBottom]->isEnabled = true;
    d_axisData[xTop]->isEnabled = false;
}

void QwtPlot::deleteAxesData()
{
Bryant's avatar
Bryant committed
    for ( int axisId = 0; axisId < axisCnt; axisId++ )
    {
pixhawk's avatar
pixhawk committed
        delete d_axisData[axisId]->scaleEngine;
        delete d_axisData[axisId];
        d_axisData[axisId] = NULL;
    }
}

/*!
Bryant's avatar
Bryant committed
  \return Scale widget of the specified axis, or NULL if axisId is invalid.
  \param axisId Axis index
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
const QwtScaleWidget *QwtPlot::axisWidget( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->scaleWidget;

    return NULL;
}

/*!
Bryant's avatar
Bryant committed
  \return Scale widget of the specified axis, or NULL if axisId is invalid.
  \param axisId Axis index
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
QwtScaleWidget *QwtPlot::axisWidget( int axisId )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->scaleWidget;

    return NULL;
}

/*!
Bryant's avatar
Bryant committed
  Change the scale engine for an axis
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \param axisId Axis index
pixhawk's avatar
pixhawk committed
  \param scaleEngine Scale engine

  \sa axisScaleEngine()
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisScaleEngine( int axisId, QwtScaleEngine *scaleEngine )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) && scaleEngine != NULL )
    {
pixhawk's avatar
pixhawk committed
        AxisData &d = *d_axisData[axisId];

        delete d.scaleEngine;
        d.scaleEngine = scaleEngine;

Bryant's avatar
Bryant committed
        d_axisData[axisId]->scaleWidget->setTransformation( 
            scaleEngine->transformation() );

        d.isValid = false;
pixhawk's avatar
pixhawk committed

        autoRefresh();
    }
}

Bryant's avatar
Bryant committed
/*!
  \param axisId Axis index
  \return Scale engine for a specific axis
*/
QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->scaleEngine;
    else
        return NULL;
}

Bryant's avatar
Bryant committed
/*!
  \param axisId Axis index
  \return Scale engine for a specific axis
*/
const QwtScaleEngine *QwtPlot::axisScaleEngine( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->scaleEngine;
    else
        return NULL;
}
/*!
Bryant's avatar
Bryant committed
  \return \c True, if autoscaling is enabled
  \param axisId Axis index
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
bool QwtPlot::axisAutoScale( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->doAutoScale;
    else
        return false;
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \return \c True, if a specified axis is enabled
  \param axisId Axis index
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
bool QwtPlot::axisEnabled( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->isEnabled;
    else
        return false;
}

/*!
Bryant's avatar
Bryant committed
  \return The font of the scale labels for a specified axis
  \param axisId Axis index
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
QFont QwtPlot::axisFont( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        return axisWidget( axisId )->font();
pixhawk's avatar
pixhawk committed
    else
        return QFont();
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \return The maximum number of major ticks for a specified axis
  \param axisId Axis index
  \sa setAxisMaxMajor(), QwtScaleEngine::divideScale()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
int QwtPlot::axisMaxMajor( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->maxMajor;
    else
        return 0;
}

/*!
  \return the maximum number of minor ticks for a specified axis
Bryant's avatar
Bryant committed
  \param axisId Axis index
  \sa setAxisMaxMinor(), QwtScaleEngine::divideScale()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
int QwtPlot::axisMaxMinor( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return d_axisData[axisId]->maxMinor;
    else
        return 0;
}

/*!
  \brief Return the scale division of a specified axis

Bryant's avatar
Bryant committed
  axisScaleDiv(axisId).lowerBound(), axisScaleDiv(axisId).upperBound()
pixhawk's avatar
pixhawk committed
  are the current limits of the axis scale.

Bryant's avatar
Bryant committed
  \param axisId Axis index
  \return Scale division
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \sa QwtScaleDiv, setAxisScaleDiv(), QwtScaleEngine::divideScale()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
const QwtScaleDiv &QwtPlot::axisScaleDiv( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    return d_axisData[axisId]->scaleDiv;
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \brief Return the scale draw of a specified axis
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \param axisId Axis index
  \return Specified scaleDraw for axis, or NULL if axis is invalid.
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
const QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( !axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return NULL;

Bryant's avatar
Bryant committed
    return axisWidget( axisId )->scaleDraw();
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \brief Return the scale draw of a specified axis

  \param axisId Axis index
  \return Specified scaleDraw for axis, or NULL if axis is invalid.
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
QwtScaleDraw *QwtPlot::axisScaleDraw( int axisId )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( !axisValid( axisId ) )
pixhawk's avatar
pixhawk committed
        return NULL;

Bryant's avatar
Bryant committed
    return axisWidget( axisId )->scaleDraw();
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \brief 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(), QwtScaleEngine::divideScale()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
double QwtPlot::axisStepSize( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( !axisValid( axisId ) )
        return 0;
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    return d_axisData[axisId]->stepSize;
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \brief Return the current interval of the specified axis
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  This is only a convenience function for axisScaleDiv( axisId )->interval();
  
  \param axisId Axis index
  \return Scale interval
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
  \sa QwtScaleDiv, axisScaleDiv()
Bryant's avatar
Bryant committed
QwtInterval QwtPlot::axisInterval( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( !axisValid( axisId ) )
        return QwtInterval();
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    return d_axisData[axisId]->scaleDiv.interval();
pixhawk's avatar
pixhawk committed
}

/*!
Bryant's avatar
Bryant committed
  \return Title of a specified axis
  \param axisId Axis index
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
QwtText QwtPlot::axisTitle( int axisId ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        return axisWidget( axisId )->title();
pixhawk's avatar
pixhawk committed
    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.
Bryant's avatar
Bryant committed

  \param axisId Axis index
pixhawk's avatar
pixhawk committed
  \param tf \c true (enabled) or \c false (disabled)
*/
Bryant's avatar
Bryant committed
void QwtPlot::enableAxis( int axisId, bool tf )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) && tf != d_axisData[axisId]->isEnabled )
    {
pixhawk's avatar
pixhawk committed
        d_axisData[axisId]->isEnabled = tf;
        updateLayout();
    }
}

/*!
  Transform the x or y coordinate of a position in the
  drawing region into a value.
Bryant's avatar
Bryant committed

  \param axisId Axis index
pixhawk's avatar
pixhawk committed
  \param pos position
Bryant's avatar
Bryant committed

  \return Position as axis coordinate

pixhawk's avatar
pixhawk committed
  \warning The position can be an x or a y coordinate,
           depending on the specified axis.
*/
Bryant's avatar
Bryant committed
double QwtPlot::invTransform( int axisId, int pos ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        return( canvasMap( axisId ).invTransform( pos ) );
pixhawk's avatar
pixhawk committed
    else
        return 0.0;
pixhawk's avatar
pixhawk committed
}


/*!
  \brief Transform a value into a coordinate in the plotting region
Bryant's avatar
Bryant committed

  \param axisId Axis index
pixhawk's avatar
pixhawk committed
  \param value value
Bryant's avatar
Bryant committed
  \return X or Y coordinate in the plotting region corresponding
pixhawk's avatar
pixhawk committed
          to the value.
*/
Bryant's avatar
Bryant committed
double QwtPlot::transform( int axisId, double value ) const
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        return( canvasMap( axisId ).transform( value ) );
pixhawk's avatar
pixhawk committed
    else
Bryant's avatar
Bryant committed
        return 0.0;
pixhawk's avatar
pixhawk committed
}

/*!
  \brief Change the font of an axis
Bryant's avatar
Bryant committed

  \param axisId Axis index
  \param font Font
pixhawk's avatar
pixhawk committed
  \warning This function changes the font of the tick labels,
           not of the axis title.
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisFont( int axisId, const QFont &font )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        axisWidget( axisId )->setFont( font );
pixhawk's avatar
pixhawk committed
}

/*!
  \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.

Bryant's avatar
Bryant committed
  \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() ).
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisAutoScale( int axisId, bool on )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) && ( d_axisData[axisId]->doAutoScale != on ) )
    {
        d_axisData[axisId]->doAutoScale = on;
pixhawk's avatar
pixhawk committed
        autoRefresh();
    }
}

/*!
  \brief Disable autoscaling and specify a fixed scale for a selected axis.
Bryant's avatar
Bryant committed

  In updateAxes() the scale engine calculates a scale division from the 
  specified parameters, that will be assigned to the scale widget. So 
  updates of the scale widget usually happen delayed with the next replot.

  \param axisId Axis index
  \param min Minimum of the scale
  \param max Maximum of the scale
pixhawk's avatar
pixhawk committed
  \param stepSize Major step size. If <code>step == 0</code>, the step size is
Bryant's avatar
Bryant committed
                  calculated automatically using the maxMajor setting.

  \sa setAxisMaxMajor(), setAxisAutoScale(), axisStepSize(), QwtScaleEngine::divideScale()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisScale( int axisId, double min, double max, double stepSize )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
    {
pixhawk's avatar
pixhawk committed
        AxisData &d = *d_axisData[axisId];

        d.doAutoScale = false;
Bryant's avatar
Bryant committed
        d.isValid = false;
pixhawk's avatar
pixhawk committed

        d.minValue = min;
        d.maxValue = max;
        d.stepSize = stepSize;
pixhawk's avatar
pixhawk committed
        autoRefresh();
    }
}

/*!
  \brief Disable autoscaling and specify a fixed scale for a selected axis.
Bryant's avatar
Bryant committed

  The scale division will be stored locally only until the next call
  of updateAxes(). So updates of the scale widget usually happen delayed with 
  the next replot.

  \param axisId Axis index
pixhawk's avatar
pixhawk committed
  \param scaleDiv Scale division
Bryant's avatar
Bryant committed

pixhawk's avatar
pixhawk committed
  \sa setAxisScale(), setAxisAutoScale()
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisScaleDiv( int axisId, const QwtScaleDiv &scaleDiv )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
    {
pixhawk's avatar
pixhawk committed
        AxisData &d = *d_axisData[axisId];

        d.doAutoScale = false;
        d.scaleDiv = scaleDiv;
Bryant's avatar
Bryant committed
        d.isValid = true;
pixhawk's avatar
pixhawk committed

        autoRefresh();
    }
}

/*!
  \brief Set a scale draw
Bryant's avatar
Bryant committed

  \param axisId Axis index
  \param scaleDraw Object responsible for drawing scales.
pixhawk's avatar
pixhawk committed

  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.
pixhawk's avatar
pixhawk committed
*/

Bryant's avatar
Bryant committed
void QwtPlot::setAxisScaleDraw( int axisId, QwtScaleDraw *scaleDraw )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
    {
        axisWidget( axisId )->setScaleDraw( scaleDraw );
pixhawk's avatar
pixhawk committed
        autoRefresh();
    }
}

/*!
  Change the alignment of the tick labels
Bryant's avatar
Bryant committed

  \param axisId Axis index
  \param alignment Or'd Qt::AlignmentFlags see <qnamespace.h>

pixhawk's avatar
pixhawk committed
  \sa QwtScaleDraw::setLabelAlignment()
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisLabelAlignment( int axisId, Qt::Alignment alignment )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        axisWidget( axisId )->setLabelAlignment( alignment );
pixhawk's avatar
pixhawk committed
}

/*!
  Rotate all tick labels
Bryant's avatar
Bryant committed

  \param axisId Axis index
pixhawk's avatar
pixhawk committed
  \param rotation Angle in degrees. When changing the label rotation,
                  the label alignment might be adjusted too.
Bryant's avatar
Bryant committed

  \sa QwtScaleDraw::setLabelRotation(), setAxisLabelAlignment()
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisLabelRotation( int axisId, double rotation )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        axisWidget( axisId )->setLabelRotation( rotation );
pixhawk's avatar
pixhawk committed
}

/*!
  Set the maximum number of minor scale intervals for a specified axis

Bryant's avatar
Bryant committed
  \param axisId Axis index
  \param maxMinor Maximum number of minor steps

pixhawk's avatar
pixhawk committed
  \sa axisMaxMinor()
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisMaxMinor( int axisId, int maxMinor )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
    {
        maxMinor = qBound( 0, maxMinor, 100 );
pixhawk's avatar
pixhawk committed
        AxisData &d = *d_axisData[axisId];
Bryant's avatar
Bryant committed
        if ( maxMinor != d.maxMinor )
        {
pixhawk's avatar
pixhawk committed
            d.maxMinor = maxMinor;
Bryant's avatar
Bryant committed
            d.isValid = false;
pixhawk's avatar
pixhawk committed
            autoRefresh();
        }
    }
}

/*!
  Set the maximum number of major scale intervals for a specified axis

Bryant's avatar
Bryant committed
  \param axisId Axis index
  \param maxMajor Maximum number of major steps

pixhawk's avatar
pixhawk committed
  \sa axisMaxMajor()
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisMaxMajor( int axisId, int maxMajor )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
    {
        maxMajor = qBound( 1, maxMajor, 10000 );
pixhawk's avatar
pixhawk committed
        AxisData &d = *d_axisData[axisId];
Bryant's avatar
Bryant committed
        if ( maxMajor != d.maxMajor )
        {
pixhawk's avatar
pixhawk committed
            d.maxMajor = maxMajor;
Bryant's avatar
Bryant committed
            d.isValid = false;
pixhawk's avatar
pixhawk committed
            autoRefresh();
        }
    }
}

/*!
  \brief Change the title of a specified axis
Bryant's avatar
Bryant committed

  \param axisId Axis index
pixhawk's avatar
pixhawk committed
  \param title axis title
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisTitle( int axisId, const QString &title )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        axisWidget( axisId )->setTitle( title );
pixhawk's avatar
pixhawk committed
}

/*!
  \brief Change the title of a specified axis
Bryant's avatar
Bryant committed

  \param axisId Axis index
  \param title Axis title
pixhawk's avatar
pixhawk committed
*/
Bryant's avatar
Bryant committed
void QwtPlot::setAxisTitle( int axisId, const QwtText &title )
pixhawk's avatar
pixhawk committed
{
Bryant's avatar
Bryant committed
    if ( axisValid( axisId ) )
        axisWidget( axisId )->setTitle( title );
pixhawk's avatar
pixhawk committed
}

Bryant's avatar
Bryant committed
/*! 
  \brief Rebuild the axes scales

  In case of autoscaling the boundaries of a scale are calculated 
  from the bounding rectangles of all plot items, having the 
  QwtPlotItem::AutoScale flag enabled ( QwtScaleEngine::autoScale() ). 
  Then a scale division is calculated ( QwtScaleEngine::didvideScale() ) 
  and assigned to scale widget.

  When the scale boundaries have been assigned with setAxisScale() a 
  scale division is calculated ( QwtScaleEngine::didvideScale() )
  for this interval and assigned to the scale widget.

  When the scale has been set explicitly by setAxisScaleDiv() the 
  locally stored scale division gets assigned to the scale widget.

  The scale widget indicates modifications by emitting a 
  QwtScaleWidget::scaleDivChanged() signal.

  updateAxes() is usually called by replot(). 

  \sa setAxisAutoScale(), setAxisScale(), setAxisScaleDiv(), replot()
      QwtPlotItem::boundingRect()
 */
void QwtPlot::updateAxes()
pixhawk's avatar
pixhawk committed
{
    // Find bounding interval of the item data
    // for all axes, where autoscaling is enabled
Bryant's avatar
Bryant committed
    QwtInterval intv[axisCnt];
pixhawk's avatar
pixhawk committed

    const QwtPlotItemList& itmList = itemList();

    QwtPlotItemIterator it;
Bryant's avatar
Bryant committed
    for ( it = itmList.begin(); it != itmList.end(); ++it )
    {
pixhawk's avatar
pixhawk committed
        const QwtPlotItem *item = *it;

Bryant's avatar
Bryant committed
        if ( !item->testItemAttribute( QwtPlotItem::AutoScale ) )
            continue;

        if ( !item->isVisible() )
pixhawk's avatar
pixhawk committed
            continue;

Bryant's avatar
Bryant committed
        if ( axisAutoScale( item->xAxis() ) || axisAutoScale( item->yAxis() ) )
        {
            const QRectF rect = item->boundingRect();

            if ( rect.width() >= 0.0 )
                intv[item->xAxis()] |= QwtInterval( rect.left(), rect.right() );

            if ( rect.height() >= 0.0 )
                intv[item->yAxis()] |= QwtInterval( rect.top(), rect.bottom() );
pixhawk's avatar
pixhawk committed
        }
    }

    // Adjust scales

Bryant's avatar
Bryant committed
    for ( int axisId = 0; axisId < axisCnt; axisId++ )
    {
pixhawk's avatar
pixhawk committed
        AxisData &d = *d_axisData[axisId];

        double minValue = d.minValue;
        double maxValue = d.maxValue;
        double stepSize = d.stepSize;

Bryant's avatar
Bryant committed
        if ( d.doAutoScale && intv[axisId].isValid() )
        {
            d.isValid = false;
pixhawk's avatar
pixhawk committed

            minValue = intv[axisId].minValue();
            maxValue = intv[axisId].maxValue();

Bryant's avatar
Bryant committed
            d.scaleEngine->autoScale( d.maxMajor,
                minValue, maxValue, stepSize );
pixhawk's avatar
pixhawk committed
        }
Bryant's avatar
Bryant committed
        if ( !d.isValid )
        {
pixhawk's avatar
pixhawk committed
            d.scaleDiv = d.scaleEngine->divideScale(
Bryant's avatar
Bryant committed
                minValue, maxValue,
                d.maxMajor, d.maxMinor, stepSize );
            d.isValid = true;
pixhawk's avatar
pixhawk committed
        }

Bryant's avatar
Bryant committed
        QwtScaleWidget *scaleWidget = axisWidget( axisId );
        scaleWidget->setScaleDiv( d.scaleDiv );
pixhawk's avatar
pixhawk committed

        int startDist, endDist;
Bryant's avatar
Bryant committed
        scaleWidget->getBorderDistHint( startDist, endDist );
        scaleWidget->setBorderDist( startDist, endDist );
pixhawk's avatar
pixhawk committed
    }

Bryant's avatar
Bryant committed
    for ( it = itmList.begin(); it != itmList.end(); ++it )
    {
pixhawk's avatar
pixhawk committed
        QwtPlotItem *item = *it;
Bryant's avatar
Bryant committed
        if ( item->testItemInterest( QwtPlotItem::ScaleInterest ) )
        {
            item->updateScaleDiv( axisScaleDiv( item->xAxis() ),
                axisScaleDiv( item->yAxis() ) );
        }
pixhawk's avatar
pixhawk committed
    }
}