You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
511 lines
16 KiB
511 lines
16 KiB
13 years ago
|
/***************************************************************************
|
||
|
qsaxis.h
|
||
|
-------------------
|
||
|
version : 0.1
|
||
|
begin :
|
||
|
copyright : (C) 2001 by Kamil Dobkowski
|
||
|
email : kamildobk@poczta.onet.pl
|
||
|
***************************************************************************/
|
||
|
|
||
|
/***************************************************************************
|
||
|
* *
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
***************************************************************************/
|
||
|
|
||
|
|
||
|
#ifndef QSAXIS_H
|
||
|
#define QSAXIS_H
|
||
|
|
||
|
#ifdef HAVE_CONFIG_H
|
||
|
#include <config.h>
|
||
|
#endif
|
||
|
|
||
|
#include"qsaxes.h"
|
||
|
#include<qstring.h>
|
||
|
#include<math.h>
|
||
|
#include<list.h>
|
||
|
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------------//
|
||
|
|
||
|
/**
|
||
|
* \brief Tic mark on the axis
|
||
|
*
|
||
|
* Tic mark on the axis.
|
||
|
* @author Kamil Dobkowski
|
||
|
*/
|
||
|
class QSAxisTic;
|
||
|
class QSAxisTic {
|
||
|
|
||
|
public:
|
||
|
double m_value; // value of the tic
|
||
|
bool m_major; // major or minor tics
|
||
|
double m_pos; // tic position on axis in world coordnates
|
||
|
int m_angle; // label angle
|
||
|
QString m_label;
|
||
|
QSGFont m_font;
|
||
|
QSGLine m_line;
|
||
|
QSGFill m_fill; // used to fill area below the tic
|
||
|
bool m_is_fill_defined;
|
||
|
QSAxisTic( double value = 0.0, bool major = true );
|
||
|
~QSAxisTic();
|
||
|
bool operator<( const QSAxisTic& t ) { return m_pos < t.m_pos; }
|
||
|
};
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------------//
|
||
|
|
||
|
/**
|
||
|
* MOC have problems if it is internal QSAxis class !.
|
||
|
*/
|
||
|
typedef struct {
|
||
|
double min;
|
||
|
double max;
|
||
|
double base;
|
||
|
int scale;
|
||
|
bool round;
|
||
|
bool reversed;
|
||
|
} axis_remembered_view_t;
|
||
|
|
||
|
//---------------------------------------------------------------------------------------------------//
|
||
|
|
||
|
/**
|
||
|
* \brief Single axis which can be added to QSAxes
|
||
|
*
|
||
|
* Axis. Its main funtion is to map values from data coordinates to world coordinates ( visible range on the axis
|
||
|
* is mapped to <0,1> ) - see dataToWorld() and from world coordinates to data - see worldToData().
|
||
|
* It can also calculate its auto range and tic mark positions, see tics(). initAxis() forces to recalculate all
|
||
|
* parameters. QSAxes object holds a list of QSAxis child objects. See also QSAxes::CoordinateSystem
|
||
|
* @author Kamil Dobkowski
|
||
|
*/
|
||
|
class QSAxis : public QSAxesChild
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
friend class QSAxes;
|
||
|
Q_PROPERTY( bool visible READ visible WRITE setVisible )
|
||
|
Q_PROPERTY( bool oppositePosition READ oppositePosition WRITE setOppositePosition )
|
||
|
Q_PROPERTY( bool defaultPosition READ defaultPosition WRITE setDefaultPosition )
|
||
|
Q_PROPERTY( bool reversed READ reversed WRITE setReversed )
|
||
|
Q_PROPERTY( bool scrollable READ scrollable WRITE setScrollable )
|
||
|
|
||
|
Q_PROPERTY( QString arrow1 READ arrow1_property WRITE set_arrow1_property )
|
||
|
Q_PROPERTY( QString arrow2 READ arrow2_property WRITE set_arrow2_property )
|
||
|
Q_PROPERTY( double min READ rangeMin WRITE setRangeMin )
|
||
|
Q_PROPERTY( double max READ rangeMax WRITE setRangeMax )
|
||
|
Q_PROPERTY( int scaleType READ scaleType WRITE setScaleType )
|
||
|
Q_PROPERTY( double scaleBase READ scaleBase WRITE setScaleBase )
|
||
|
Q_PROPERTY( double majorGridStep READ majorGridStep WRITE setMajorGridStep )
|
||
|
Q_PROPERTY( double minorGridStep READ minorGridStep WRITE setMinorGridStep )
|
||
|
|
||
|
Q_PROPERTY( double position READ position WRITE setPosition )
|
||
|
Q_PROPERTY( bool ticsVisible READ ticsVisible WRITE setTicsVisible )
|
||
|
Q_PROPERTY( bool ticsOuter READ ticsOuter WRITE setTicsOuter )
|
||
|
Q_PROPERTY( QString ticsFormat READ ticsFormat WRITE setTicsFormat )
|
||
|
Q_PROPERTY( int ticsAngle READ ticsAngle WRITE setTicsAngle )
|
||
|
Q_PROPERTY( bool roundRangeToTicStep READ roundRangeToTicStep WRITE setRoundRangeToTicStep )
|
||
|
|
||
|
Q_PROPERTY( double ticLabelPos1 READ ticLabelPos1 WRITE setTicLabelPos1 )
|
||
|
Q_PROPERTY( double ticLabelPos2 READ ticLabelPos2 WRITE setTicLabelPos2 )
|
||
|
Q_PROPERTY( double titlePosition READ titlePosition WRITE setTitlePosition )
|
||
|
Q_PROPERTY( double titleDistance READ titleDistance WRITE setTitleDistance )
|
||
|
|
||
|
public:
|
||
|
/**
|
||
|
* Minimum logarithm value. Default is 1e-200
|
||
|
*/
|
||
|
static const double minLogValue;
|
||
|
/**
|
||
|
* Minimum value of the logarithm base. Default is 1.001
|
||
|
*/
|
||
|
static const double minScaleBase;
|
||
|
/**
|
||
|
* Minimum value shown on the axis. Default is -1e200
|
||
|
*/
|
||
|
static const double minRangeValue;
|
||
|
/**
|
||
|
* Maximum value shown on the axis. Default is 1e200
|
||
|
*/
|
||
|
static const double maxRangeValue;
|
||
|
/**
|
||
|
* Minimum rangeMax-rangeMin Default 1e-200
|
||
|
*/
|
||
|
static const double minRange;
|
||
|
|
||
|
/**
|
||
|
* The axis scale.
|
||
|
*/
|
||
|
enum AxisScale { LinearScale, LogScale };
|
||
|
/**
|
||
|
* Requested axis range. See min()
|
||
|
*/
|
||
|
enum AxisRange { RangeSet, RangeVisible, RangeData };
|
||
|
/**
|
||
|
* Type of the axis.
|
||
|
*/
|
||
|
enum AxisType { XAxisType, YAxisType, ZAxisType, VAxisType, UnknownAxisType };
|
||
|
/**
|
||
|
* Constructor. You have to add the axis to the parent child list immediately -
|
||
|
* see QSAxes::axisAdd()
|
||
|
*/
|
||
|
QSAxis( AxisType type, QSAxes *parentAxes, const char *name=0 );
|
||
|
/**
|
||
|
* Destructor
|
||
|
*/
|
||
|
virtual ~QSAxis();
|
||
|
/**
|
||
|
* Maps value from an visible axis range to <0,1>. See QSAxes::CoordinateSystem
|
||
|
*/
|
||
|
double dataToWorld( double value ) const;
|
||
|
/**
|
||
|
* Maps a value from <0,1> to visible axis range. See QSAxes::CoordinateSystem
|
||
|
*/
|
||
|
double worldToData( double value ) const;
|
||
|
/**
|
||
|
* Returns the axis type.
|
||
|
*/
|
||
|
AxisType type() const { return m_type; }
|
||
|
/**
|
||
|
* Hides/shows an axis
|
||
|
*/
|
||
|
void setVisible( bool enabled );
|
||
|
/**
|
||
|
* Places an axis on the opposite side.
|
||
|
*/
|
||
|
void setOppositePosition( bool enabled );
|
||
|
/**
|
||
|
* Places an axis at a default position ( opposite or not ).
|
||
|
*/
|
||
|
void setDefaultPosition( bool enabled );
|
||
|
/**
|
||
|
* Reverse direction of an axis.
|
||
|
*/
|
||
|
void setReversed( bool reversed );
|
||
|
/**
|
||
|
* Sets if this axis should be scrolled when scrollbars are moved in a plot view..
|
||
|
*/
|
||
|
void setScrollable( bool enabled );
|
||
|
/**
|
||
|
* Returns if the axis is visible
|
||
|
*/
|
||
|
bool visible() const { return m_visible; }
|
||
|
/**
|
||
|
* Returns whether the axis is placed on the opposite side.
|
||
|
*/
|
||
|
bool oppositePosition() const { return m_opposite; }
|
||
|
/**
|
||
|
* Returns if axis is placed at a default position.
|
||
|
*/
|
||
|
bool defaultPosition() const { return m_default; }
|
||
|
/**
|
||
|
* Turns on a reversed direction on a given axis.
|
||
|
*/
|
||
|
bool reversed() const { return m_reversed; }
|
||
|
/**
|
||
|
* Returns a scrollable state
|
||
|
*/
|
||
|
bool scrollable() const { return m_scrollable; }
|
||
|
/**
|
||
|
* Sets a beginng arrow style.
|
||
|
*/
|
||
|
void setArrow1( const QSGArrow& arrow );
|
||
|
/**
|
||
|
* Sets an ending arrow style
|
||
|
*/
|
||
|
void setArrow2( const QSGArrow& arrow );
|
||
|
/**
|
||
|
* Returns a begging arrow style
|
||
|
*/
|
||
|
QSGArrow arrow1() const { return m_arrow1; }
|
||
|
/**
|
||
|
* Sets an ending arrow style.
|
||
|
*/
|
||
|
QSGArrow arrow2() const { return m_arrow2; }
|
||
|
/**
|
||
|
* Sets the range of the given axis to '< min, max >'.
|
||
|
* If 'min' == 'max', auto range is turned on.
|
||
|
*/
|
||
|
void setRange( double min, double max );
|
||
|
/**
|
||
|
* Sets the range of the given axis to '< min, max >'.
|
||
|
* If 'min' == 'max', auto range is turned on.
|
||
|
*/
|
||
|
void setRangeMin( double min );
|
||
|
/**
|
||
|
* Sets the range of the given axis to '< min, max >'.
|
||
|
* If 'min' == 'max', auto range is turned on.
|
||
|
*/
|
||
|
void setRangeMax( double max );
|
||
|
/**
|
||
|
* Sets the axis scale type.
|
||
|
*/
|
||
|
void setScale( AxisScale scale, double base = 10.0 );
|
||
|
/**
|
||
|
* Sets the axis scale type.
|
||
|
*/
|
||
|
void setScaleType( int scale );
|
||
|
/**
|
||
|
* Sets the axis scale type.
|
||
|
*/
|
||
|
void setScaleBase( double base );
|
||
|
/**
|
||
|
* Sets a position of the given axis in world coordinates.
|
||
|
*/
|
||
|
void setPosition( double pos );
|
||
|
/**
|
||
|
* Returns the axis range . Notice that 'RangeSet' may be
|
||
|
* different from 'RangeVisible'. If you set range to
|
||
|
* <-10, 10> and turn on 'LogScale' the visible range will
|
||
|
* be <minLogValue,10>. 'RangeVisible' and
|
||
|
* 'RangeData' are calculated when plot is redrawn the first
|
||
|
* time ( parent axes object calls initAxis() ), so returned values may be invalid
|
||
|
* sometimes. You can call parentAxes()->initMappings() to force recalculation of ranges
|
||
|
* immediately.
|
||
|
*/
|
||
|
double min( AxisRange type = RangeSet ) const;
|
||
|
/**
|
||
|
* Returns the axis range . See min()
|
||
|
*/
|
||
|
double max( AxisRange type = RangeSet ) const;
|
||
|
/**
|
||
|
* Returns the axis range . See min()
|
||
|
*/
|
||
|
double rangeMin() const { return min(); }
|
||
|
/**
|
||
|
* Returns the axis range . See min()
|
||
|
*/
|
||
|
double rangeMax() const { return max(); }
|
||
|
/**
|
||
|
* Returns the current scale base.
|
||
|
*/
|
||
|
double scaleBase() const { return m_base; }
|
||
|
/**
|
||
|
* Returns the current scale type.
|
||
|
*/
|
||
|
int scaleType() const { return m_scale; }
|
||
|
/**
|
||
|
* Returns the current position.
|
||
|
*/
|
||
|
double position() const { return m_pos; }
|
||
|
/**
|
||
|
* Sets a new grid density.
|
||
|
*/
|
||
|
void setGridStep( double major = -4.0, double minor = -20.0 );
|
||
|
/**
|
||
|
* Sets a new grid step/density.
|
||
|
*/
|
||
|
void setMajorGridStep( double step );
|
||
|
/**
|
||
|
* Sets a new grid step/density.
|
||
|
*/
|
||
|
void setMinorGridStep( double step );
|
||
|
/**
|
||
|
* Returns a major grid step/density.
|
||
|
*/
|
||
|
double majorGridStep() const { return m_majd; }
|
||
|
/**
|
||
|
* Returns a minor grid step/density.
|
||
|
*/
|
||
|
double minorGridStep() const { return m_mind; }
|
||
|
/**
|
||
|
* Tics are generated each time 'initAxis' is called.
|
||
|
*/
|
||
|
const list<QSAxisTic> *tics() const { return &m_tics; }
|
||
|
/**
|
||
|
* For internal use. Only
|
||
|
*/
|
||
|
const QSAxisTic &lastTic() const { return m_last_tic; }
|
||
|
/**
|
||
|
* Sets lengths of tics.
|
||
|
*/
|
||
|
void setTicsVisible( bool visible );
|
||
|
/**
|
||
|
* Outer or inner tic marks..
|
||
|
*/
|
||
|
void setTicsOuter( bool enabled );
|
||
|
/**
|
||
|
* Sets the tics print format for the given axis.
|
||
|
*/
|
||
|
void setTicsFormat( const QString& format );
|
||
|
/**
|
||
|
* Sets the angle of the tic label.
|
||
|
*/
|
||
|
void setTicsAngle( int angle );
|
||
|
/**
|
||
|
* Adjust range for the given axis to contain an whole number of tic marks.
|
||
|
*/
|
||
|
void setRoundRangeToTicStep( bool enabled );
|
||
|
/**
|
||
|
* Returns the label format.
|
||
|
*/
|
||
|
QString ticsFormat() const { return m_tics_format; }
|
||
|
/**
|
||
|
* Returns the tic label angle
|
||
|
*/
|
||
|
int ticsAngle() const { return m_tics_angle; }
|
||
|
/**
|
||
|
* Returns a major tic's length.
|
||
|
*/
|
||
|
bool ticsVisible() const { return m_tics_visible; }
|
||
|
/**
|
||
|
* Outer or inner tic marks
|
||
|
*/
|
||
|
bool ticsOuter() const { return m_tics_outer; }
|
||
|
/**
|
||
|
* Returns the adjust setting.
|
||
|
*/
|
||
|
bool roundRangeToTicStep() const { return m_round; }
|
||
|
/**
|
||
|
* Sets the distance from the axis of the odd tic labels.
|
||
|
*/
|
||
|
void setTicLabelPos1( double pos );
|
||
|
/**
|
||
|
* Sets the distance from the axis of the even tic labels.
|
||
|
*/
|
||
|
void setTicLabelPos2( double pos );
|
||
|
/**
|
||
|
* Returns the distance from the axis of the odd tic labels.
|
||
|
*/
|
||
|
double ticLabelPos1() const { return m_tic_label_pos1; }
|
||
|
/**
|
||
|
* Returns the distance from the axis of the even tic labels.
|
||
|
*/
|
||
|
double ticLabelPos2() const { return m_tic_label_pos2; }
|
||
|
/**
|
||
|
* Sets the position of the title ( parallel to the axis )
|
||
|
*/
|
||
|
void setTitlePosition( double value );
|
||
|
/**
|
||
|
* Sets the distance of the title from the axis
|
||
|
*/
|
||
|
void setTitleDistance( double value );
|
||
|
/**
|
||
|
* Returns the position of the title ( parallel to the axis )
|
||
|
*/
|
||
|
double titlePosition() const { return m_title_position; }
|
||
|
/**
|
||
|
* Returns the distance of the title from the axis
|
||
|
*/
|
||
|
double titleDistance() const { return m_title_distance; }
|
||
|
|
||
|
/**
|
||
|
* Makes a text of the tic with value 'value' on axis 'axis' and
|
||
|
* writes it to 'buffer'.
|
||
|
*/
|
||
|
void sprintfTic( QString& buffer, double value, const QString& format = QString::null );
|
||
|
/**
|
||
|
* Remembered view contains such parameters as axis min ,axis max, axis scale, axis reversed.
|
||
|
* Up to four different views can be remembered ( index must be in 0-3 ).
|
||
|
*/
|
||
|
virtual void rememberCurrentView( int index );
|
||
|
|
||
|
/**
|
||
|
* Sets the view properties
|
||
|
*/
|
||
|
virtual void setRememberedView( int index );
|
||
|
|
||
|
void set_arrow1_property( const QString& data );
|
||
|
void set_arrow2_property( const QString& data );
|
||
|
QString arrow1_property() const;
|
||
|
QString arrow2_property() const;
|
||
|
virtual ColumnType columnType( int channel, int column ) const;
|
||
|
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
|
||
|
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
|
||
|
|
||
|
/**
|
||
|
* Channels.
|
||
|
*/
|
||
|
enum Channels {
|
||
|
TicsChannel = 0,
|
||
|
LineStyles = 1,
|
||
|
FontStyles = 2,
|
||
|
FillStyles = 3
|
||
|
};
|
||
|
/**
|
||
|
* Line elements.
|
||
|
*/
|
||
|
enum LineElement {
|
||
|
AxisLine = 0,
|
||
|
MajorGridLine,
|
||
|
MinorGridLine
|
||
|
};
|
||
|
/**
|
||
|
* Font elements.
|
||
|
*/
|
||
|
enum FontElement {
|
||
|
TitleFont = 0,
|
||
|
TicsFont
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
* Makes a text of the tic with value 'value' with
|
||
|
* format 'format' and writes it to 'buffer'.
|
||
|
*/
|
||
|
static void sprintfTic( QString& buffer, const QString& format, double value, double factor, double base, double exponent );
|
||
|
|
||
|
axis_remembered_view_t rememberedViews[3];
|
||
|
|
||
|
protected:
|
||
|
/**
|
||
|
* This function is called by parent axes each time plot is repainted.
|
||
|
* It should calculate range, coordinate mappings and tic positions.
|
||
|
*/
|
||
|
virtual void initAxis( double dataMin, double dataMax, bool isData = true );
|
||
|
|
||
|
private:
|
||
|
bool m_visible;
|
||
|
AxisType m_type; // type of the axis
|
||
|
bool m_opposite;
|
||
|
bool m_default; // default position
|
||
|
QSGArrow m_arrow1;
|
||
|
QSGArrow m_arrow2;
|
||
|
double m_min; // min set by user
|
||
|
double m_max; // max set by user
|
||
|
double m_vmin; // visible axis min
|
||
|
double m_vmax; // visible axis max
|
||
|
double m_dmax; // data min
|
||
|
double m_dmin; // data max
|
||
|
double m_base; // axis scale base
|
||
|
AxisScale m_scale; // scale type
|
||
|
double m_pos; // length proportional to other axes lengths
|
||
|
bool m_round; // adjust range to contain an integer number of tics.
|
||
|
bool m_reversed; // reversed axis direction
|
||
|
bool m_scrollable;
|
||
|
|
||
|
double m_majd; // major density
|
||
|
double m_mind; // minor density
|
||
|
|
||
|
QString m_tics_format; // format of tics values
|
||
|
bool m_tics_outer; // outer tics
|
||
|
bool m_tics_visible; // show tics
|
||
|
int m_tics_angle;
|
||
|
|
||
|
double m_wscale; // see axisToWorld
|
||
|
double m_wmin; // see axisToWorld
|
||
|
|
||
|
double m_tic_label_pos1;
|
||
|
double m_tic_label_pos2;
|
||
|
|
||
|
double m_title_position;
|
||
|
double m_title_distance;
|
||
|
|
||
|
|
||
|
list<QSAxisTic> m_tics; // QList ?!
|
||
|
QSAxisTic m_last_tic;
|
||
|
|
||
|
void init_axis_mappings();
|
||
|
void init_ranges( bool is_data );
|
||
|
void find_closest( double *valM, int *valE, const double MSD[], int MSD_number );
|
||
|
void to_float_point( double value, double *mantissa, int *exponent );
|
||
|
void init_tics();
|
||
|
void init_auto_tics_values();
|
||
|
double round_tic( double v );
|
||
|
};
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|