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.
389 lines
12 KiB
389 lines
12 KiB
/***************************************************************************
|
|
qsplot.h
|
|
-------------------
|
|
version : 0.1
|
|
begin : 01-January-2000
|
|
copyright : (C) 2000 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 QSPLOT_H
|
|
#define QSPLOT_H
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include"qsaxes.h"
|
|
#include"qsaxis.h"
|
|
#include"qsdrv.h"
|
|
#include<qstring.h>
|
|
#include<math.h>
|
|
|
|
|
|
|
|
/**
|
|
* \brief Dataset, which can be diplayed using QSAxes
|
|
*
|
|
* Dataset, which can be diplayed using QSAxes, see QSAxes::plotAdd(). You can bind this dataset to some axes
|
|
* in the parent object using setDefaultAxis(). You can map coordinates from data to world coordinates using
|
|
* worldToData(). QSPlot contains support for drawing legends, see drawLegendItem(), legendItemSize(). QSCLegend
|
|
* uses them extensively. There is also support for 'Data picker' tool implemented, see posInfo().
|
|
* For implementing your own dataset types you will have to reimplement : getAxisRange(), start(), step(), end(),
|
|
* and also drawLegendItem(), legendItemSize(), posInfo(), and optionaly allocRuntimeData(), freeRuntimeData().
|
|
* @author Kamil Dobkowski
|
|
*/
|
|
class QSPlot : public QSAxesChild
|
|
{
|
|
Q_OBJECT
|
|
friend class QSAxes;
|
|
Q_PROPERTY( int defaultXAxis READ defaultXAxis WRITE setDefaultXAxis )
|
|
Q_PROPERTY( int defaultYAxis READ defaultYAxis WRITE setDefaultYAxis )
|
|
Q_PROPERTY( int defaultZAxis READ defaultZAxis WRITE setDefaultZAxis )
|
|
Q_PROPERTY( int defaultVAxis READ defaultVAxis WRITE setDefaultVAxis )
|
|
Q_PROPERTY( bool legendItemVisible READ legendItemVisible WRITE setLegendItemVisible )
|
|
Q_PROPERTY( QString gradient READ gradientProperty WRITE setGradientProperty )
|
|
public:
|
|
/**
|
|
* Constructor. You must add the plot immedialtely to the parent child list
|
|
* ( see QSAxes::plotAdd() )
|
|
*/
|
|
QSPlot( QSAxes *parentAxes=0, const char *name=0 );
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~QSPlot();
|
|
/**
|
|
* Sets an axis to which to bind to. Type of this axis is taken from QSAxis::type() .
|
|
*/
|
|
void setDefaultAxis( QSAxis *axis );
|
|
/**
|
|
* Sets the default axis.
|
|
*/
|
|
void setDefaultXAxis( int axisIndex );
|
|
/**
|
|
* Sets the default axis.
|
|
*/
|
|
void setDefaultYAxis( int axisIndex );
|
|
/**
|
|
* Sets the default axis.
|
|
*/
|
|
void setDefaultZAxis( int axisIndex );
|
|
/**
|
|
* Sets the default axis.
|
|
*/
|
|
void setDefaultVAxis( int axisIndex );
|
|
/**
|
|
* Returns an index of the default axis
|
|
*/
|
|
int defaultXAxis() const { return m_axes->axisIndex(m_daxes[QSAxis::XAxisType]); }
|
|
/**
|
|
* Returns an index of the default axis
|
|
*/
|
|
int defaultYAxis() const { return m_axes->axisIndex(m_daxes[QSAxis::YAxisType]); }
|
|
/**
|
|
* Returns an index of the default axis
|
|
*/
|
|
int defaultZAxis() const { return m_axes->axisIndex(m_daxes[QSAxis::ZAxisType]); }
|
|
/**
|
|
* Returns an index of the default axis
|
|
*/
|
|
int defaultVAxis() const { return m_axes->axisIndex(m_daxes[QSAxis::VAxisType]); }
|
|
/**
|
|
* Returns default axis. 'axisType' must be one of
|
|
* QSAxes::AxisType' !
|
|
*/
|
|
QSAxis *defaultAxis( int axisType ) const { return m_daxes[axisType]; }
|
|
/**
|
|
* Sets a gradient object
|
|
*/
|
|
void setGradient( const QSGGradient& gradient );
|
|
/**
|
|
* Returns a gradient
|
|
*/
|
|
const QSGGradient gradient() const { return m_gradient; }
|
|
/**
|
|
* Show legend item corresponding to this plot in legend object
|
|
*/
|
|
void setLegendItemVisible( bool visible );
|
|
/**
|
|
* Returns legend setting.
|
|
*/
|
|
bool legendItemVisible() const { return m_is_legend; }
|
|
/**
|
|
* Returns info or QString::null
|
|
*/
|
|
virtual QString posInfo( QSPt2f& pos );
|
|
/**
|
|
* Returns item size
|
|
*/
|
|
virtual QSPt2f legendItemSize( QSDrv *drv );
|
|
/**
|
|
* Draw legend item at position 'pos'
|
|
*/
|
|
virtual void drawLegendItem( const QSPt2f& pos, QSDrv *drv );
|
|
/**
|
|
* Maps a point from an visible axis range to <0,1>
|
|
*/
|
|
QSPt2f dataToWorld( const QSPt2f& p ) const;
|
|
/**
|
|
* Maps a point from an visible axis range to <0,1>
|
|
*/
|
|
QSPt3f dataToWorld( const QSPt3f& p ) const;
|
|
/**
|
|
* Maps a point from an visible axis range to <0,1>
|
|
*/
|
|
QSPt3f dataToWorldV( const QSPt3f& p ) const;
|
|
/**
|
|
* Maps a point from <0,1> to an visible axis range.
|
|
*/
|
|
QSPt2f worldToData( const QSPt2f& p ) const;
|
|
/**
|
|
* Maps a point from <0,1> to an visible axis range
|
|
*/
|
|
QSPt3f worldToData( const QSPt3f& p ) const;
|
|
/**
|
|
* Maps a point from <0,1> to an visible axis range
|
|
*/
|
|
QSPt3f worldToDataV( const QSPt3f& p ) const;
|
|
/**
|
|
* Sets a new gradient.
|
|
*/
|
|
void setGradientProperty( const QString& string );
|
|
/**
|
|
* Returns gradient as QString
|
|
*/
|
|
QString gradientProperty() const { return toQString(m_gradient); }
|
|
|
|
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
|
|
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
|
|
|
|
protected slots:
|
|
/**
|
|
* Check if this plot is not bound to a removed axis.
|
|
* if it is, find another axis of the same type - there
|
|
* always should be at least one such axis..
|
|
*/
|
|
virtual void axisRemoved( QSData *object );
|
|
|
|
protected:
|
|
/**
|
|
* Must be reimplemented and return data range on each axis or
|
|
* false when no data is set. This functions is always called
|
|
* outside 'start()' and 'end()' !
|
|
*/
|
|
virtual bool getAxisRange( QSAxis *axis, double& min, double& max );
|
|
/**
|
|
* Start drawing. Called by parent axes.
|
|
* Time-expensive operations should be
|
|
* performed in little parts during 'step()'
|
|
* call. If returns false - 'end()' is called
|
|
* immediately, if returns true - 'step()' is
|
|
* called next.
|
|
*/
|
|
virtual bool start();
|
|
/**
|
|
* This function will be called to make drawing
|
|
* until it returns false. Notice that drawing
|
|
* should be stopped at any time. Even if this
|
|
* function returns true parent axes object may
|
|
* decide to call end().
|
|
*/
|
|
virtual bool step();
|
|
/**
|
|
* This can be called by parent axes to stop drawing.
|
|
* Normally called after 'step()' returned false;
|
|
*/
|
|
virtual void end();
|
|
/**
|
|
* Called from start(). Everyting which goes to start() may be put here.
|
|
* inits m_curr_driver, m_curr_dpi, m_csize, m_cpos fields with values
|
|
* taken from parent axes
|
|
*/
|
|
virtual void allocRuntimeData();
|
|
/**
|
|
* Called from end().Everyting which goes to end() may be put here.
|
|
*/
|
|
virtual void freeRuntimeData();
|
|
|
|
static const int work_steps = 30;
|
|
|
|
bool m_busy;
|
|
bool m_is_legend;
|
|
int m_bkg_handler;
|
|
double m_curr_dpi;
|
|
QSDrv *m_drv;
|
|
QSPt2f m_csize;
|
|
QSPt2f m_cpos;
|
|
QSAxis *m_daxes[5];
|
|
QSAxes *m_axes;
|
|
QSGGradient m_gradient;
|
|
const QSProjection *m_proj;
|
|
};
|
|
|
|
//--------------------------------------------------------------------------------------//
|
|
|
|
/**
|
|
* \brief 2D Dataset
|
|
*
|
|
* Ups ,,, There is no new functionality added to this class, yet. It is the same as QSPlot..
|
|
* @author Kamil Dobkowski
|
|
*/
|
|
class QSPlot2D : public QSPlot
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
QSPlot2D( QSAxes *parentAxes, const char *name=0 );
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~QSPlot2D();
|
|
};
|
|
|
|
//--------------------------------------------------------------------------------------//
|
|
|
|
|
|
|
|
/**
|
|
* \brief 3D Dataset
|
|
*
|
|
* Base class for all 3d datasets ( which draw 3d mesh ). Allows setting
|
|
* mesh parameters, which are used to initialize QSDrv and to draw 3d polygons
|
|
* with drawPolygon().
|
|
* @author Kamil Dobkowski
|
|
*/
|
|
class QSPlot3D : public QSPlot
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY( bool colored READ colored WRITE setColored )
|
|
Q_PROPERTY( bool topBottom READ topBottom WRITE setTopBottom )
|
|
Q_PROPERTY( bool autoDivide READ autoDivide WRITE setAutoDivide )
|
|
Q_PROPERTY( int edgeAutoColor READ edgeAutoColor WRITE setEdgeAutoColor )
|
|
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
QSPlot3D( QSAxes *parentAxes, const char *name=0 );
|
|
/**
|
|
* Destructor.
|
|
*/
|
|
virtual ~QSPlot3D();
|
|
/**
|
|
* Enables/disables coloring of the 3d mesh.
|
|
*/
|
|
void setColored( bool enabled );
|
|
/**
|
|
*
|
|
*/
|
|
void setTopBottom( bool enabled );
|
|
/**
|
|
*
|
|
*/
|
|
void setAutoDivide( bool enabled );
|
|
/**
|
|
*
|
|
*/
|
|
void setEdgeAutoColor( int value );
|
|
/**
|
|
*
|
|
*/
|
|
void setClipping( bool clipping );
|
|
/**
|
|
*
|
|
*/
|
|
bool topBottom() const { return m_topbottom; }
|
|
/**
|
|
*
|
|
*/
|
|
bool autoDivide() const { return m_divide; }
|
|
/**
|
|
*
|
|
*/
|
|
int edgeAutoColor() const { return m_edge_auto_color; }
|
|
/**
|
|
*
|
|
*/
|
|
bool clipping() { return m_clipping; }
|
|
/**
|
|
* Returns the current color setting.
|
|
*/
|
|
bool colored() const { return m_colored; }
|
|
|
|
virtual void loadStateFromStream( QDataStream& stream, QSObjectFactory *factory );
|
|
virtual void saveStateToStream( QDataStream& stream, QSObjectFactory *factory );
|
|
/**
|
|
* See QSGraphicalData::setFill()
|
|
*/
|
|
enum FillElement {
|
|
TMeshFill,
|
|
BMeshFill
|
|
};
|
|
/**
|
|
* See QSGraphicalData::setLine()
|
|
*/
|
|
enum LineElement {
|
|
MeshLine
|
|
};
|
|
/**
|
|
* See QSGraphicalData::setPoint()
|
|
*/
|
|
enum PointElement {
|
|
PointMark
|
|
};
|
|
|
|
protected:
|
|
|
|
bool m_clipping;
|
|
bool m_colored;
|
|
int m_edge_auto_color;
|
|
bool m_divide;
|
|
bool m_topbottom;
|
|
QSDrv::CNormals m_cnormals;
|
|
QSDrv::CColors m_ccolors;
|
|
QSDrv::COrdering m_corder;
|
|
/**
|
|
* Draws a surface mesh. It is almost the same as QSDrv::drawPoly3(), but draws using a nice colored gradient ( divides polygon into levels ).
|
|
* If 'values' is not NULL draws 4D data, 'values' must be table with npoints elements int this case.
|
|
*/
|
|
void drawPolygon( const QSPt3f pts[], int npoints, QSPt3f *norm, const double *values=NULL, const bool *edges=NULL );
|
|
/**
|
|
* Reimplemented. Inits m_ccolors, m_cnormals, m_corder
|
|
*/
|
|
virtual void allocRuntimeData();
|
|
/**
|
|
* Called from end().Everyting which goes to end() may be put here.
|
|
*/
|
|
virtual void freeRuntimeData();
|
|
/**
|
|
* Draws gradient legend
|
|
*/
|
|
virtual QSPt2f standardLegendItemSize( QSDrv *drv, QSAxis *axis, const QString& title );
|
|
/**
|
|
* Draws gradient legend
|
|
*/
|
|
virtual void drawStandardLegendItem( const QSPt2f& pos, QSDrv *drv, QSAxis *axis, const QString& title, const QSGGradient *gradient );
|
|
|
|
private:
|
|
struct plot3d_runtime_data;
|
|
struct plot3d_runtime_data *d;
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|