mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-27 03:00:55 +08:00
f2004a6f66
IMPROVED/REWORKED: legend/key positioning as combination of 3 values, e.g. \c JKQTPKeyOutsideTop|JKQTPKeyTop|JKQTPKeyRight or \c JKQTPKeyInside|JKQTPKeyTopJKQTPKeyRight
396 lines
18 KiB
C++
396 lines
18 KiB
C++
/*
|
|
Copyright (c) 2008-2022 Jan W. Krieger (<jan@jkrieger.de>)
|
|
|
|
|
|
|
|
This software is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
|
the Free Software Foundation, either version 2.1 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License (LGPL) for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef jkqtpgraphsevaluatedfunction_H
|
|
#define jkqtpgraphsevaluatedfunction_H
|
|
|
|
|
|
|
|
#include <QString>
|
|
#include <QPainter>
|
|
#include <QPair>
|
|
#include "jkqtplotter/graphs/jkqtpscatter.h"
|
|
#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
|
|
#include "jkqtplotter/jkqtplotter_imexport.h"
|
|
#include "jkqtcommon/jkqtpgeometrytools.h"
|
|
#include "jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h"
|
|
#include <functional>
|
|
|
|
|
|
/** \brief This class extends JKQTPEvaluatedFunctionWithErrorsGraphBase with functions to draw the graphs and
|
|
* set the drawing style
|
|
* \ingroup jkqtplotter_functiongraphs
|
|
*
|
|
* \note Since this class is meant as a base for both f(x)- and f(y)-functions, it cannot
|
|
* implememt JKQTPGraph::draw(). Therefore it provides two implementations drawXGraph()
|
|
* and drawYGraph() and the user has to decide in the concrete graph class, which one to call
|
|
* (or whether to do the drawing completely different).
|
|
*
|
|
* \see e.g. JKQTPXFunctionLineGraph for a concrete implementation
|
|
*/
|
|
class JKQTPLOTTER_LIB_EXPORT JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase: public JKQTPEvaluatedFunctionWithErrorsGraphBase, public JKQTPGraphLineAndFillStyleMixin {
|
|
Q_OBJECT
|
|
public:
|
|
|
|
/** \brief class constructor */
|
|
JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase(JKQTBasePlotter* parent=nullptr);
|
|
|
|
/** \brief class constructor */
|
|
JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase(JKQTPlotter* parent);
|
|
|
|
/** \brief class destructor */
|
|
virtual ~JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase() override;
|
|
|
|
/** \brief plots a key marker inside the specified rectangle \a rect */
|
|
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, const QRectF& rect) override;
|
|
/** \brief returns the color to be used for the key label */
|
|
virtual QColor getKeyLabelColor() const override;
|
|
|
|
|
|
|
|
/** \copydoc drawErrorPolygons */
|
|
bool getDrawErrorPolygons() const;
|
|
/** \copydoc drawErrorLines */
|
|
bool getDrawErrorLines() const;
|
|
/** \copydoc errorColor */
|
|
virtual QColor getErrorLineColor() const;
|
|
/** \copydoc errorFillColor */
|
|
virtual QColor getErrorFillColor() const;
|
|
/** \copydoc errorFillStyle */
|
|
virtual Qt::BrushStyle getErrorFillStyle() const;
|
|
/** \copydoc errorStyle */
|
|
virtual Qt::PenStyle getErrorLineStyle() const;
|
|
/** \copydoc errorLineWidth */
|
|
virtual double getErrorLineWidth() const;
|
|
|
|
|
|
|
|
|
|
|
|
public Q_SLOTS:
|
|
/** \brief set color, fill color and error color at the same time */
|
|
void setColor(QColor c);
|
|
|
|
|
|
/** \copydoc drawErrorPolygons */
|
|
void setDrawErrorPolygons(bool __value);
|
|
/** \copydoc drawErrorLines */
|
|
void setDrawErrorLines(bool __value);
|
|
/** \copydoc errorColor */
|
|
virtual void setErrorLineColor(const QColor & __value);
|
|
/** \copydoc errorFillColor */
|
|
virtual void setErrorFillColor(const QColor & __value);
|
|
/** \copydoc errorFillStyle */
|
|
virtual void setErrorFillStyle(Qt::BrushStyle __value);
|
|
/** \copydoc errorStyle */
|
|
virtual void setErrorLineStyle(Qt::PenStyle __value);
|
|
/** \copydoc errorLineWidth */
|
|
virtual void setErrorLineWidth(double __value);
|
|
|
|
protected:
|
|
/** \brief plots the graph to the plotter object specified as parent */
|
|
void drawXGraph(JKQTPEnhancedPainter& painter);
|
|
/** \brief plots the graph to the plotter object specified as parent */
|
|
void drawYGraph(JKQTPEnhancedPainter& painter);
|
|
|
|
|
|
|
|
|
|
/** \brief indicates whether an error polygon should be drawn */
|
|
bool drawErrorPolygons;
|
|
/** \brief indicates whether error lines should be drawn */
|
|
bool drawErrorLines;
|
|
|
|
|
|
|
|
/** \brief color of the error graph */
|
|
QColor errorColor;
|
|
/** \brief color of the error graph fill */
|
|
QColor errorFillColor;
|
|
/** \brief linestyle of the error graph lines */
|
|
Qt::PenStyle errorStyle;
|
|
/** \brief width (pixels) of the error graph */
|
|
double errorLineWidth;
|
|
/** \brief fill style, if the error curve should be filled */
|
|
Qt::BrushStyle errorFillStyle;
|
|
|
|
|
|
QBrush getErrorBrush(JKQTPEnhancedPainter& painter) const;
|
|
QPen getErrorLinePen(JKQTPEnhancedPainter &painter) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*! \brief type of functions that may be plotted by JKQTPXFunctionLineGraph and JKQTPYFunctionLineGraph
|
|
\ingroup jkqtplotter_functiongraphs
|
|
|
|
This is the type of functions \f$ y=f(x, \vec{p}) \f$ that may be plottet by JKQTPXFunctionLineGraph
|
|
and JKQTPYFunctionLineGraph. It is possible to supply parameters \f$ \vec{p} \f$ to the function that
|
|
influence its result. Parameters are given as a pointer to some memory location. The function has to
|
|
know on its own how to interpret these.
|
|
*/
|
|
typedef std::function<double(double, const QVector<double>&)> jkqtpPlotFunctionType;
|
|
|
|
/*! \brief simplified type of functions (without parameters) that may be plotted by JKQTPXFunctionLineGraph and JKQTPYFunctionLineGraph
|
|
\ingroup jkqtplotter_functiongraphs
|
|
|
|
This is the type of functions \f$ y=f(x) \f$ that may be plottet by JKQTPXFunctionLineGraph
|
|
and JKQTPYFunctionLineGraph.
|
|
*/
|
|
typedef std::function<double(double)> jkqtpSimplePlotFunctionType;
|
|
|
|
|
|
|
|
/** \brief extends JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase with the capabilities to define functions from C++-functors
|
|
* of type jkqtpSimplePlotFunctionType or jkqtpPlotFunctionType
|
|
* \ingroup jkqtplotter_functiongraphs
|
|
*
|
|
* \see JKQTPXFunctionLineGraph and JKQTPYFunctionLineGraph for a concrete implementation
|
|
*/
|
|
class JKQTPLOTTER_LIB_EXPORT JKQTPFunctorLineGraphBase: public JKQTPEvaluatedFunctionWithErrorsGraphDrawingBase {
|
|
Q_OBJECT
|
|
public:
|
|
enum SpecialFunction {
|
|
Polynomial, /*!< \brief a polynomial \f$ f(x)=p_0+p_1x+p_2x^2+p_3x^3+... \f$ The parameters \a params have to be point to a QVector<double> and contain the parameters \f$ p_0, p_1, ... \f$ */
|
|
Line=Polynomial, /*!< \brief a polynomial \f$ f(x)=p_0+p_1x \f$ The parameters \a params have to be point to a QVector<double> and contain the parameters \f$ p_0, p_1, ... \f$ */
|
|
Exponential, /*!< \brief an exponential function \f$ f(x)=p_0+p_1\cdot\exp(x/p_2) \f$ or \f$ f(x)=p_0\cdot\exp(x/p_1) \f$ (depending on the number of parameters). The parameters \a params have to be point to a QVector<double> and contain the parameters \f$ p_0, p_1, ... \f$ */
|
|
PowerLaw, /*!< \brief an exponential function \f$ f(x)=p_0+p_1\cdot x^{p_3} \f$ or \f$ f(x)=p_0\cdot x^{p_1} \f$ or \f$ f(x)= x^{p_0} \f$ (depending on the number of parameters) The parameters \a params have to be point to a QVector<double> and contain the parameters \f$ p_0, p_1, ... \f$ */
|
|
};
|
|
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(JKQTBasePlotter* parent=nullptr);
|
|
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(SpecialFunction type, const QVector<double>& params, const QString& title, JKQTBasePlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPFunctorLineGraphBase(SpecialFunction type, const QVector<double>& params, const QString& title, JKQTPlotter* parent);
|
|
|
|
/** \brief class destructor */
|
|
virtual ~JKQTPFunctorLineGraphBase() override;
|
|
|
|
/** \brief sets a functor to be plotted
|
|
*
|
|
* \see plotFunction
|
|
*/
|
|
virtual void setPlotFunctionFunctor (jkqtpPlotFunctionType && __value);
|
|
/** \brief sets a functor to be plotted
|
|
*
|
|
* \see plotFunction
|
|
*/
|
|
virtual void setPlotFunctionFunctor (const jkqtpPlotFunctionType & __value);
|
|
/** \brief sets a functor to be plotted
|
|
*
|
|
* \see simplePlotFunction
|
|
*/
|
|
virtual void setPlotFunctionFunctor (jkqtpSimplePlotFunctionType && __value);
|
|
/** \brief sets a functor to be plotted
|
|
*
|
|
* \see simplePlotFunction
|
|
*/
|
|
virtual void setPlotFunctionFunctor (const jkqtpSimplePlotFunctionType & __value);
|
|
/*! \copydoc plotFunction
|
|
*
|
|
* \see isSimplePlotFunction() */ \
|
|
virtual jkqtpPlotFunctionType getPlotFunctionFunctor () const;
|
|
/*! \copydoc simplePlotFunction
|
|
*
|
|
* \see isSimplePlotFunction() */ \
|
|
virtual jkqtpSimplePlotFunctionType getSimplePlotFunction () const;
|
|
|
|
/** \brief returns whether the plot function was defined as a jkqtpSimpleParametricCurveFunctionType (\c true ) or
|
|
* a jkqtpParametricCurveFunctionType (\c false ) */
|
|
bool isSimplePlotFunction() const;
|
|
|
|
|
|
/** \brief sets a functor to be used for calculating errors
|
|
*
|
|
* \see errorPlotFunction
|
|
*/
|
|
virtual void setErrorPlotFunction (jkqtpPlotFunctionType && __value);
|
|
/** \brief sets a functor to be used for calculating errors
|
|
*
|
|
* \see errorPlotFunction
|
|
*/
|
|
virtual void setErrorPlotFunction (const jkqtpPlotFunctionType & __value);
|
|
/** \copydoc errorPlotFunction */ \
|
|
virtual jkqtpPlotFunctionType getErrorPlotFunction () const;
|
|
/** \brief sets a functor to be used for calculating errors
|
|
*
|
|
* \see errorSimplePlotFunction
|
|
*/
|
|
virtual void setErrorPlotFunction (jkqtpSimplePlotFunctionType && __value);
|
|
/** \brief sets a functor to be used for calculating errors
|
|
*
|
|
* \see errorSimplePlotFunction
|
|
*/
|
|
virtual void setErrorPlotFunction (const jkqtpSimplePlotFunctionType & __value);
|
|
/** \copydoc errorSimplePlotFunction */ \
|
|
virtual jkqtpSimplePlotFunctionType getErrorSimplePlotFunction () const;
|
|
|
|
|
|
|
|
/** \brief sets function to the given special function */
|
|
void setSpecialFunction(SpecialFunction function);
|
|
protected:
|
|
/** \brief the function to be plotted */
|
|
jkqtpPlotFunctionType plotFunction;
|
|
/** \brief a simple function to be plotted, simplified form without parameters */
|
|
jkqtpSimplePlotFunctionType simplePlotFunction;
|
|
|
|
|
|
/** \brief this function calculates the error at a given position */
|
|
jkqtpPlotFunctionType errorPlotFunction;
|
|
/** \brief this function calculates the error at a given position, simplified form without parameters */
|
|
jkqtpSimplePlotFunctionType errorSimplePlotFunction;
|
|
};
|
|
|
|
|
|
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ y=f(x) \f$
|
|
\ingroup jkqtplotter_functiongraphs
|
|
|
|
This class uses the intelligent plotting algorithm for functions, implemented in JKQTPAdaptiveFunctionGraphEvaluator.
|
|
|
|
The following image shows some example graphs:
|
|
|
|
\image html plot_functionplots.png
|
|
|
|
\note Auto-scaling of the plot is deactivated (by overwriting getXMinMax() and getYMinMax() to return \c false ), as it depends on the axes (hen-egg-problem!)
|
|
Set the plot-ranges by hand!!!
|
|
|
|
\see \ref JKQTPlotterFunctionPlots, JKQTPAdaptiveFunctionGraphEvaluator, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph, jkqtpstatAddPolyFit(), jkqtpstatAddWeightedRegression(), jkqtpstatAddRobustIRLSRegression(), jkqtpstatAddRegression(), jkqtpstatAddLinearWeightedRegression(), jkqtpstatAddRobustIRLSLinearRegression(), jkqtpstatAddLinearRegression()
|
|
*/
|
|
class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPFunctorLineGraphBase {
|
|
Q_OBJECT
|
|
public:
|
|
|
|
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(JKQTBasePlotter* parent=nullptr);
|
|
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(SpecialFunction type, const QVector<double>& params, const QString& title, JKQTBasePlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPXFunctionLineGraph(SpecialFunction type, const QVector<double>& params, const QString& title, JKQTPlotter* parent);
|
|
|
|
/** \brief class destructor */
|
|
virtual ~JKQTPXFunctionLineGraph() override;
|
|
|
|
/** \brief plots the graph to the plotter object specified as parent */
|
|
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
|
|
|
protected:
|
|
|
|
/** \copydoc JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec() */
|
|
virtual PlotFunctorSpec buildPlotFunctorSpec() override;
|
|
|
|
/** \copydoc JKQTPEvaluatedFunctionWithErrorsGraphBase::buildPlotFunctorSpec() */
|
|
virtual std::function<QPointF(double)> buildErrorFunctorSpec() override;
|
|
|
|
/** \brief get the maximum and minimum x-value of the graph
|
|
*
|
|
* This functions returns 0 for both parameters, so that the plotter uses the predefined
|
|
* min and max values.
|
|
*/
|
|
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
|
|
/** \brief get the maximum and minimum y-value of the graph
|
|
*/
|
|
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
|
|
|
|
|
};
|
|
|
|
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ x=f(y) \f$
|
|
\ingroup jkqtplotter_functiongraphs
|
|
|
|
The following image shows some example graphs:
|
|
|
|
\image html functionplot_fy.png
|
|
|
|
\note Auto-scaling of the plot is deactivated (by overwriting getXMinMax() and getYMinMax() to return \c false ), as it depends on the axes (hen-egg-problem!)
|
|
Set the plot-ranges by hand!!!
|
|
|
|
\see \ref JKQTPlotterFunctionPlots , JKQTPXFunctionLineGraph, JKQTPXYFunctionLineGraph
|
|
*/
|
|
class JKQTPLOTTER_LIB_EXPORT JKQTPYFunctionLineGraph: public JKQTPFunctorLineGraphBase {
|
|
Q_OBJECT
|
|
public:
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(JKQTBasePlotter* parent=nullptr);
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(const jkqtpSimplePlotFunctionType & f, const QString& title, JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTBasePlotter* parent=nullptr);
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(jkqtpSimplePlotFunctionType && f, const QString& title, JKQTPlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(SpecialFunction type, const QVector<double>& params, const QString& title, JKQTBasePlotter* parent);
|
|
/** \brief class constructor */
|
|
JKQTPYFunctionLineGraph(SpecialFunction type, const QVector<double>& params, const QString& title, JKQTPlotter* parent);
|
|
|
|
/** \brief plots the graph to the plotter object specified as parent */
|
|
virtual void draw(JKQTPEnhancedPainter& painter) override;
|
|
protected:
|
|
|
|
/** \copydoc JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec() */
|
|
virtual PlotFunctorSpec buildPlotFunctorSpec() override;
|
|
|
|
/** \copydoc JKQTPEvaluatedFunctionWithErrorsGraphBase::buildPlotFunctorSpec() */
|
|
virtual std::function<QPointF(double)> buildErrorFunctorSpec() override;
|
|
|
|
|
|
/** \brief get the maximum and minimum x-value of the graph
|
|
*/
|
|
virtual bool getXMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
|
/** \brief get the maximum and minimum y-value of the graph
|
|
*/
|
|
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif // jkqtpgraphsevaluatedfunction_H
|