mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-11-15 10:05:47 +08:00
improved parsed/evaluated function classes (made C++11-ready) and added examples for them
This commit is contained in:
parent
4e64a493ef
commit
4ac14ed871
@ -52,6 +52,8 @@ addSimpleTest(rgbimageplot_qt)
|
|||||||
addSimpleTest(impulsesplot)
|
addSimpleTest(impulsesplot)
|
||||||
addSimpleTest(paramscatterplot)
|
addSimpleTest(paramscatterplot)
|
||||||
addSimpleTest(parametriccurve)
|
addSimpleTest(parametriccurve)
|
||||||
|
addSimpleTest(parsedfunctionplot)
|
||||||
|
addSimpleTest(functionplot)
|
||||||
#addSimpleTest(imageplot_nodatastore)
|
#addSimpleTest(imageplot_nodatastore)
|
||||||
#addSimpleTest(rgbimageplot_opencv)
|
#addSimpleTest(rgbimageplot_opencv)
|
||||||
#addSimpleTest(imageplot_opencv)
|
#addSimpleTest(imageplot_opencv)
|
||||||
|
@ -33,6 +33,8 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
|
|||||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_impulsesplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | [Impulse Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | `JKQTPimpulsesVerticalGraph` and `JKQTPimpulsesHorizontalGraph`<br/>C++-style QVector as plot data |
|
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_impulsesplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | [Impulse Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_impulsesplot) | `JKQTPimpulsesVerticalGraph` and `JKQTPimpulsesHorizontalGraph`<br/>C++-style QVector as plot data |
|
||||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | [Scatter Graph with Parametrized Symbols/Colors](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>modify scatter/points/line-graph properties by data |
|
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_paramscatterplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | [Scatter Graph with Parametrized Symbols/Colors](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_paramscatterplot) | `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>modify scatter/points/line-graph properties by data |
|
||||||
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parametriccurve_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | [Plotting Parametric Curves](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | `JKQTPxyLineGraph` and `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>parametric curve plotting |
|
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parametriccurve_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | [Plotting Parametric Curves](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parametriccurve) | `JKQTPxyLineGraph` and `JKQTPxyParametrizedScatterGraph`<br/>C++-style QVector as plot data<br/>parametric curve plotting |
|
||||||
|
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_functionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_functionplot) | [Plotting Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_functionplot) | `JKQTPxFunctionLineGraph` <br/>diretly plotting C/C++-functions |
|
||||||
|
[![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parsedfunctionplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parsedfunctionplot) | [Plotting Parsed Mathematical Functions as Line Graphs](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parsedfunctionplot) | `JKQTPxParsedFunctionLineGraph` <br/>plotting functions with the internal math equation parser/evaluator |
|
||||||
|
|
||||||
### Styling the Plot, Keys, Axes, ...
|
### Styling the Plot, Keys, Axes, ...
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ HEADERS += $$PWD/jkqtplotter/jkqtpbaseplotter.h \
|
|||||||
$$PWD/jkqtplottertools/jkqtpimagetools.h \
|
$$PWD/jkqtplottertools/jkqtpimagetools.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbarchart.h \
|
$$PWD/jkqtplotter/jkqtpgraphsbarchart.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsboxplot.h \
|
$$PWD/jkqtplotter/jkqtpgraphsboxplot.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsvaluatedfunction.h \
|
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.h \
|
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimpulses.h \
|
$$PWD/jkqtplotter/jkqtpgraphsimpulses.h \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.h \
|
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.h \
|
||||||
@ -54,7 +54,7 @@ SOURCES += $$PWD/jkqtplotter/jkqtpbaseplotter.cpp \
|
|||||||
$$PWD/jkqtplottertools/jkqtpimagetools.cpp \
|
$$PWD/jkqtplottertools/jkqtpimagetools.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsbarchart.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsbarchart.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsboxplot.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsboxplot.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsvaluatedfunction.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsevaluatedfunction.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsfilledcurve.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsimpulses.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsimpulses.cpp \
|
||||||
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.cpp \
|
$$PWD/jkqtplotter/jkqtpgraphsparsedfunction.cpp \
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,290 +1,317 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2008-2018 Jan W. Krieger (<jan@jkrieger.de>)
|
Copyright (c) 2008-2018 Jan W. Krieger (<jan@jkrieger.de>)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
This software is free software: you can redistribute it and/or modify
|
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
|
it under the terms of the GNU Lesser General Public License (LGPL) as published by
|
||||||
the Free Software Foundation, either version 2 of the License, or
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Lesser General Public License (LGPL) for more details.
|
GNU Lesser General Public License (LGPL) for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public License (LGPL)
|
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/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup jkqtplotter_elements Plot Elements
|
* \defgroup jkqtplotter_elements Plot Elements
|
||||||
* \ingroup jkqtplotter
|
* \ingroup jkqtplotter
|
||||||
* \defgroup jkqtplotter_plots Graphs
|
* \defgroup jkqtplotter_plots Graphs
|
||||||
* \ingroup jkqtplotter_elements
|
* \ingroup jkqtplotter_elements
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file jkqtpgraphs.h
|
/** \file jkqtpgraphs.h
|
||||||
* \ingroup jkqtplotter
|
* \ingroup jkqtplotter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPair>
|
#include <QPair>
|
||||||
#include "jkqtplotter/jkqtpgraphs.h"
|
#include "jkqtplotter/jkqtpgraphs.h"
|
||||||
#include "jkqtplottertools/jkqtp_imexport.h"
|
#include "jkqtplottertools/jkqtp_imexport.h"
|
||||||
|
#include <functional>
|
||||||
#ifndef jkqtpgraphsvaluatedfunction_H
|
|
||||||
#define jkqtpgraphsvaluatedfunction_H
|
#ifndef jkqtpgraphsevaluatedfunction_H
|
||||||
|
#define jkqtpgraphsevaluatedfunction_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief type of functions that may be plottet
|
|
||||||
\ingroup jkqtplotter_plots
|
/*! \brief type of functions that may be plottet
|
||||||
|
\ingroup jkqtplotter_plots
|
||||||
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
|
This is the type of functions \f$ y=f(x, \vec{p}) \f$ that may be plottet by JKQTPxFunctionLineGraph
|
||||||
influence its result. Parameters are given as a pointer to some memory location. The function has to
|
and JKQTPyFunctionLineGraph. It is possible to supply parameters \f$ \vec{p} \f$ to the function that
|
||||||
know on its own how to interpret these.
|
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 double(*jkqtpPlotFunctionType)(double, void*);
|
*/
|
||||||
|
typedef std::function<double(double, void*)> jkqtpPlotFunctionType;
|
||||||
|
|
||||||
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ y=f(x) \f$
|
|
||||||
\ingroup jkqtplotter_plots
|
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ y=f(x) \f$
|
||||||
|
\ingroup jkqtplotter_plots
|
||||||
This class implements an intelligent plotting algorithm for functions. It starts by sampling
|
|
||||||
the function at minSamples positions. Then each function interval is bisected recursively if
|
This class implements an intelligent plotting algorithm for functions. It starts by sampling
|
||||||
necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$
|
the function at minSamples positions. Then each function interval is bisected recursively if
|
||||||
and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. the midpoint is added
|
necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$
|
||||||
to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f]
|
and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. the midpoint is added
|
||||||
In addition all sampling points except minimum and maximum are beeing shifted by a random fraction their
|
to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f]
|
||||||
distance to the other points. This helps to prevent beats when sampling periodic functions.
|
In addition all sampling points except minimum and maximum are beeing shifted by a random fraction their
|
||||||
|
distance to the other points. This helps to prevent beats when sampling periodic functions.
|
||||||
the following image
|
|
||||||
\image html plot_functionplots.png
|
the following image
|
||||||
*/
|
\image html plot_functionplots.png
|
||||||
class LIB_EXPORT JKQTPxFunctionLineGraph: public JKQTPgraph {
|
*/
|
||||||
Q_OBJECT
|
class LIB_EXPORT JKQTPxFunctionLineGraph: public JKQTPgraph {
|
||||||
public:
|
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$ */
|
enum SpecialFunction {
|
||||||
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$ */
|
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$ */
|
||||||
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$ */
|
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$ */
|
||||||
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$ */
|
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 */
|
|
||||||
JKQTPxFunctionLineGraph(JKQtBasePlotter* parent=nullptr);
|
/** \brief class constructor */
|
||||||
|
JKQTPxFunctionLineGraph(JKQtBasePlotter* parent=nullptr);
|
||||||
/** \brief class constructor */
|
|
||||||
JKQTPxFunctionLineGraph(JKQtPlotter* parent);
|
/** \brief class constructor */
|
||||||
|
JKQTPxFunctionLineGraph(JKQtPlotter* parent);
|
||||||
/** \brief class destructor */
|
|
||||||
virtual ~JKQTPxFunctionLineGraph();
|
/** \brief class destructor */
|
||||||
|
virtual ~JKQTPxFunctionLineGraph();
|
||||||
/** \brief plots the graph to the plotter object specified as parent */
|
|
||||||
virtual void draw(JKQTPEnhancedPainter& painter);
|
/** \brief plots the graph to the plotter object specified as parent */
|
||||||
/** \brief plots a key marker inside the specified rectangle \a rect */
|
virtual void draw(JKQTPEnhancedPainter& painter);
|
||||||
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect);
|
/** \brief plots a key marker inside the specified rectangle \a rect */
|
||||||
/** \brief returns the color to be used for the key label */
|
virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect);
|
||||||
virtual QColor getKeyLabelColor();
|
/** \brief returns the color to be used for the key label */
|
||||||
|
virtual QColor getKeyLabelColor();
|
||||||
/** \brief get the maximum and minimum x-value of the graph
|
|
||||||
*
|
/** \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.
|
* 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);
|
*/
|
||||||
/** \brief get the maximum and minimum y-value of the graph
|
virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero);
|
||||||
*/
|
/** \brief get the maximum and minimum y-value of the graph
|
||||||
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero);
|
*/
|
||||||
|
virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero);
|
||||||
/** \brief clear the data sampled from the function. */
|
|
||||||
void clearData();
|
/** \brief clear the data sampled from the function. */
|
||||||
|
void clearData();
|
||||||
JKQTPGET_SET_MACRO(QColor, color)
|
|
||||||
JKQTPGET_SET_MACRO(QColor, fillColor)
|
JKQTPGET_SET_MACRO(QColor, color)
|
||||||
JKQTPGET_SET_MACRO(Qt::BrushStyle, fillStyle)
|
JKQTPGET_SET_MACRO(QColor, fillColor)
|
||||||
JKQTPGET_SET_MACRO(Qt::PenStyle, style)
|
JKQTPGET_SET_MACRO(Qt::BrushStyle, fillStyle)
|
||||||
JKQTPGET_SET_MACRO(double, lineWidth)
|
JKQTPGET_SET_MACRO(Qt::PenStyle, style)
|
||||||
JKQTPGET_SET_MACRO(bool, drawLine)
|
JKQTPGET_SET_MACRO(double, lineWidth)
|
||||||
JKQTPGET_SET_MACRO_I(jkqtpPlotFunctionType, plotFunction, clearData())
|
JKQTPGET_SET_MACRO(bool, drawLine)
|
||||||
JKQTPGET_SET_MACRO_I(void*, params, clearData())
|
|
||||||
/** \brief sets the params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
/** \brief sets the property plotFunction to the specified \a __value.
|
||||||
void set_params(const QVector<double>& params);
|
*
|
||||||
/** \brief sets the params from a copy of the given array of length \a N */
|
* \details Description of the parameter varname is: <CENTER>\copybrief plotFunction.</CENTER>
|
||||||
void set_copiedParams(const double* params, int N);
|
* \see plotFunction for more information */
|
||||||
inline void set_paramsV(double p1) {
|
virtual void set_plotFunction (jkqtpPlotFunctionType && __value);
|
||||||
QVector<double> p;
|
/** \brief sets the property plotFunction to the specified \a __value.
|
||||||
p<<p1;
|
*
|
||||||
set_params(p);
|
* \details Description of the parameter varname is: <CENTER>\copybrief plotFunction.</CENTER>
|
||||||
}
|
* \see plotFunction for more information */
|
||||||
inline void set_paramsV(double p1, double p2) {
|
virtual void set_plotFunction (const jkqtpPlotFunctionType & __value);
|
||||||
QVector<double> p;
|
/** \brief returns the property varname. \see varname for more information */ \
|
||||||
p<<p1<<p2;
|
virtual jkqtpPlotFunctionType get_plotFunction () const;
|
||||||
set_params(p);
|
|
||||||
}
|
JKQTPGET_SET_MACRO_I(void*, params, clearData())
|
||||||
inline void set_paramsV(double p1, double p2, double p3) {
|
/** \brief sets the params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
||||||
QVector<double> p;
|
void set_params(const QVector<double>& params);
|
||||||
p<<p1<<p2<<p3;
|
/** \brief sets the params from a copy of the given array of length \a N */
|
||||||
set_params(p);
|
void set_copiedParams(const double* params, int N);
|
||||||
}
|
inline void set_paramsV(double p1) {
|
||||||
inline void set_paramsV(double p1, double p2, double p3, double p4) {
|
QVector<double> p;
|
||||||
QVector<double> p;
|
p<<p1;
|
||||||
p<<p1<<p2<<p3<<p4;
|
set_params(p);
|
||||||
set_params(p);
|
}
|
||||||
}
|
inline void set_paramsV(double p1, double p2) {
|
||||||
inline void set_paramsV(double p1, double p2, double p3, double p4, double p5) {
|
QVector<double> p;
|
||||||
QVector<double> p;
|
p<<p1<<p2;
|
||||||
p<<p1<<p2<<p3<<p4<<p5;
|
set_params(p);
|
||||||
set_params(p);
|
}
|
||||||
}
|
inline void set_paramsV(double p1, double p2, double p3) {
|
||||||
|
QVector<double> p;
|
||||||
QVector<double> get_internalParams() const;
|
p<<p1<<p2<<p3;
|
||||||
QVector<double> get_internalErrorParams() const;
|
set_params(p);
|
||||||
JKQTPGET_SET_MACRO(unsigned int, minSamples)
|
}
|
||||||
JKQTPGET_SET_MACRO(unsigned int, maxRefinementDegree)
|
inline void set_paramsV(double p1, double p2, double p3, double p4) {
|
||||||
JKQTPGET_SET_MACRO(double, slopeTolerance)
|
QVector<double> p;
|
||||||
JKQTPGET_SET_MACRO(double, minPixelPerSample)
|
p<<p1<<p2<<p3<<p4;
|
||||||
JKQTPGET_SET_MACRO(bool, plotRefinement)
|
set_params(p);
|
||||||
JKQTPGET_SET_MACRO(bool, displaySamplePoints)
|
}
|
||||||
JKQTPGET_SET_MACRO(bool, drawErrorPolygons)
|
inline void set_paramsV(double p1, double p2, double p3, double p4, double p5) {
|
||||||
JKQTPGET_SET_MACRO(bool, drawErrorLines)
|
QVector<double> p;
|
||||||
JKQTPGET_SET_MACRO(jkqtpPlotFunctionType, errorPlotFunction)
|
p<<p1<<p2<<p3<<p4<<p5;
|
||||||
JKQTPGET_SET_MACRO(void*, errorParams)
|
set_params(p);
|
||||||
/** \brief sets the error params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
}
|
||||||
void set_errorParams(const QVector<double>& errorParams);
|
|
||||||
|
QVector<double> get_internalParams() const;
|
||||||
JKQTPGET_SET_MACRO(int, parameterColumn)
|
QVector<double> get_internalErrorParams() const;
|
||||||
JKQTPSET_CAST_MACRO(size_t, int, parameterColumn)
|
JKQTPGET_SET_MACRO(unsigned int, minSamples)
|
||||||
JKQTPGET_SET_MACRO(int, errorParameterColumn)
|
JKQTPGET_SET_MACRO(unsigned int, maxRefinementDegree)
|
||||||
JKQTPSET_CAST_MACRO(size_t, int, errorParameterColumn)
|
JKQTPGET_SET_MACRO(double, slopeTolerance)
|
||||||
|
JKQTPGET_SET_MACRO(double, minPixelPerSample)
|
||||||
JKQTPGET_SET_MACRO(QColor, errorColor)
|
JKQTPGET_SET_MACRO(bool, plotRefinement)
|
||||||
JKQTPGET_SET_MACRO(QColor, errorFillColor)
|
JKQTPGET_SET_MACRO(bool, displaySamplePoints)
|
||||||
JKQTPGET_SET_MACRO(Qt::BrushStyle, errorFillStyle)
|
JKQTPGET_SET_MACRO(bool, drawErrorPolygons)
|
||||||
JKQTPGET_SET_MACRO(Qt::PenStyle, errorStyle)
|
JKQTPGET_SET_MACRO(bool, drawErrorLines)
|
||||||
JKQTPGET_SET_MACRO(double, errorLineWidth)
|
/** \brief sets the property errorPlotFunction to the specified \a __value.
|
||||||
|
*
|
||||||
/** \copydoc JKQTPgraph::usesColumn() */
|
* \details Description of the parameter varname is: <CENTER>\copybrief errorPlotFunction.</CENTER>
|
||||||
virtual bool usesColumn(int c);
|
* \see errorPlotFunction for more information */
|
||||||
|
virtual void set_errorPlotFunction (jkqtpPlotFunctionType && __value);
|
||||||
|
/** \brief sets the property errorPlotFunction to the specified \a __value.
|
||||||
/** \brief sets function to the given special function */
|
*
|
||||||
void setSpecialFunction(SpecialFunction function);
|
* \details Description of the parameter varname is: <CENTER>\copybrief errorPlotFunction.</CENTER>
|
||||||
protected:
|
* \see errorPlotFunction for more information */
|
||||||
/** \brief which plot style to use from the parent plotter (via JKQtPlotterBase::getPlotStyle() and JKQtPlotterBase::getNextStyle() ) */
|
virtual void set_errorPlotFunction (const jkqtpPlotFunctionType & __value);
|
||||||
int parentPlotStyle;
|
/** \brief returns the property varname. \see varname for more information */ \
|
||||||
|
virtual jkqtpPlotFunctionType get_errorPlotFunction () const;
|
||||||
struct doublePair {
|
JKQTPGET_SET_MACRO(void*, errorParams)
|
||||||
double x;
|
/** \brief sets the error params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
|
||||||
double f;
|
void set_errorParams(const QVector<double>& errorParams);
|
||||||
doublePair* next;
|
|
||||||
};
|
JKQTPGET_SET_MACRO(int, parameterColumn)
|
||||||
/** \brief a linked list holding the datapoints \f$ \left(x, y=f(x, \vec{p})\right) \f$ to be plotted */
|
JKQTPSET_CAST_MACRO(size_t, int, parameterColumn)
|
||||||
doublePair* data;
|
JKQTPGET_SET_MACRO(int, errorParameterColumn)
|
||||||
|
JKQTPSET_CAST_MACRO(size_t, int, errorParameterColumn)
|
||||||
/** \brief fill the data array with data from the function plotFunction */
|
|
||||||
virtual void createPlotData( bool collectParams=true);
|
JKQTPGET_SET_MACRO(QColor, errorColor)
|
||||||
|
JKQTPGET_SET_MACRO(QColor, errorFillColor)
|
||||||
virtual void collectParameters();
|
JKQTPGET_SET_MACRO(Qt::BrushStyle, errorFillStyle)
|
||||||
|
JKQTPGET_SET_MACRO(Qt::PenStyle, errorStyle)
|
||||||
void refine(doublePair* a, doublePair* b, unsigned int degree=0);
|
JKQTPGET_SET_MACRO(double, errorLineWidth)
|
||||||
|
|
||||||
int parameterColumn;
|
/** \copydoc JKQTPgraph::usesColumn() */
|
||||||
int errorParameterColumn;
|
virtual bool usesColumn(int c);
|
||||||
|
|
||||||
/** \brief color of the graph */
|
|
||||||
QColor color;
|
/** \brief sets function to the given special function */
|
||||||
/** \brief color of the graph fill */
|
void setSpecialFunction(SpecialFunction function);
|
||||||
QColor fillColor;
|
protected:
|
||||||
/** \brief linestyle of the graph lines */
|
/** \brief which plot style to use from the parent plotter (via JKQtPlotterBase::getPlotStyle() and JKQtPlotterBase::getNextStyle() ) */
|
||||||
Qt::PenStyle style;
|
int parentPlotStyle;
|
||||||
/** \brief width (pixels) of the graph */
|
|
||||||
double lineWidth;
|
struct doublePair {
|
||||||
/** \brief fill style, if the curve should be filled */
|
double x;
|
||||||
Qt::BrushStyle fillStyle;
|
double f;
|
||||||
/** \brief indicates whether to draw a line or not */
|
doublePair* next;
|
||||||
bool drawLine;
|
};
|
||||||
/** \brief indicates whether to fill the space between the curve and the x-axis */
|
/** \brief a linked list holding the datapoints \f$ \left(x, y=f(x, \vec{p})\right) \f$ to be plotted */
|
||||||
bool fillCurve;
|
doublePair* data;
|
||||||
/** \brief the function to be plotted */
|
|
||||||
jkqtpPlotFunctionType plotFunction;
|
/** \brief fill the data array with data from the function plotFunction */
|
||||||
/** \brief pointer to the parameters supplied to the plotting funtion */
|
virtual void createPlotData( bool collectParams=true);
|
||||||
void* params;
|
|
||||||
/** \brief the minimum number of points to evaluate the function at */
|
virtual void collectParameters();
|
||||||
unsigned int minSamples;
|
|
||||||
/** \brief the maximum number of recursive refinement steps
|
void refine(doublePair* a, doublePair* b, unsigned int degree=0);
|
||||||
*
|
|
||||||
* each step bisects the interval \f$ [a, b] \f$ into two halfes. So the maximum number
|
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the plot function */
|
||||||
* of points plotted at all are thus:
|
int parameterColumn;
|
||||||
* \f[ \mbox{minSamples} \cdot 2^{\mbox{maxRefinementDegree}} \f]
|
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the error plot function */
|
||||||
*/
|
int errorParameterColumn;
|
||||||
unsigned int maxRefinementDegree;
|
|
||||||
/** \brief the tolerance for the difference of two subsequent slopes */
|
/** \brief color of the graph */
|
||||||
double slopeTolerance;
|
QColor color;
|
||||||
/** \brief create one sample at least every \a minPixelPerSample pixels */
|
/** \brief color of the graph fill */
|
||||||
double minPixelPerSample;
|
QColor fillColor;
|
||||||
/** \brief switch on or off [default: on] the plot refinement algorithm */
|
/** \brief linestyle of the graph lines */
|
||||||
bool plotRefinement;
|
Qt::PenStyle style;
|
||||||
/** \brief if true [default: off] display the points where the function has been sampled */
|
/** \brief width (pixels) of the graph */
|
||||||
bool displaySamplePoints;
|
double lineWidth;
|
||||||
/** \brief indicates whether an error polygon should be drawn */
|
/** \brief fill style, if the curve should be filled */
|
||||||
bool drawErrorPolygons;
|
Qt::BrushStyle fillStyle;
|
||||||
/** \brief indicates whether error lines should be drawn */
|
/** \brief indicates whether to draw a line or not */
|
||||||
bool drawErrorLines;
|
bool drawLine;
|
||||||
/** \brief this function calculates the error at a given position */
|
/** \brief indicates whether to fill the space between the curve and the x-axis */
|
||||||
jkqtpPlotFunctionType errorPlotFunction;
|
bool fillCurve;
|
||||||
/** \brief parameters for errorFunction */
|
/** \brief the function to be plotted */
|
||||||
void* errorParams;
|
jkqtpPlotFunctionType plotFunction;
|
||||||
/** \brief color of the error graph */
|
/** \brief pointer to the parameters supplied to the plotting funtion */
|
||||||
QColor errorColor;
|
void* params;
|
||||||
/** \brief color of the error graph fill */
|
/** \brief the minimum number of points to evaluate the function at */
|
||||||
QColor errorFillColor;
|
unsigned int minSamples;
|
||||||
/** \brief linestyle of the error graph lines */
|
/** \brief the maximum number of recursive refinement steps
|
||||||
Qt::PenStyle errorStyle;
|
*
|
||||||
/** \brief width (pixels) of the error graph */
|
* each step bisects the interval \f$ [a, b] \f$ into two halfes. So the maximum number
|
||||||
double errorLineWidth;
|
* of points plotted at all are thus:
|
||||||
/** \brief fill style, if the error curve should be filled */
|
* \f[ \mbox{minSamples} \cdot 2^{\mbox{maxRefinementDegree}} \f]
|
||||||
Qt::BrushStyle errorFillStyle;
|
*/
|
||||||
|
unsigned int maxRefinementDegree;
|
||||||
|
/** \brief the tolerance for the difference of two subsequent slopes */
|
||||||
QBrush getBrush(JKQTPEnhancedPainter& painter) const;
|
double slopeTolerance;
|
||||||
QPen getLinePen(JKQTPEnhancedPainter& painter) const;
|
/** \brief create one sample at least every \a minPixelPerSample pixels */
|
||||||
|
double minPixelPerSample;
|
||||||
QBrush getErrorBrush(JKQTPEnhancedPainter& painter) const;
|
/** \brief switch on or off [default: on] the plot refinement algorithm */
|
||||||
QPen getErrorLinePen(JKQTPEnhancedPainter &painter) const;
|
bool plotRefinement;
|
||||||
|
/** \brief if true [default: off] display the points where the function has been sampled */
|
||||||
QVector<double> iparams, ierrorparams;
|
bool displaySamplePoints;
|
||||||
};
|
/** \brief indicates whether an error polygon should be drawn */
|
||||||
|
bool drawErrorPolygons;
|
||||||
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ x=f(y) \f$
|
/** \brief indicates whether error lines should be drawn */
|
||||||
\ingroup jkqtplotter_plots
|
bool drawErrorLines;
|
||||||
|
/** \brief this function calculates the error at a given position */
|
||||||
*/
|
jkqtpPlotFunctionType errorPlotFunction;
|
||||||
class LIB_EXPORT JKQTPyFunctionLineGraph: public JKQTPxFunctionLineGraph {
|
/** \brief parameters for errorFunction */
|
||||||
Q_OBJECT
|
void* errorParams;
|
||||||
public:
|
/** \brief color of the error graph */
|
||||||
/** \brief class constructor */
|
QColor errorColor;
|
||||||
inline JKQTPyFunctionLineGraph(JKQtBasePlotter* parent=nullptr):JKQTPxFunctionLineGraph(parent) {}
|
/** \brief color of the error graph fill */
|
||||||
/** \brief class constructor */
|
QColor errorFillColor;
|
||||||
inline JKQTPyFunctionLineGraph(JKQtPlotter* parent):JKQTPxFunctionLineGraph(parent) {}
|
/** \brief linestyle of the error graph lines */
|
||||||
|
Qt::PenStyle errorStyle;
|
||||||
/** \brief plots the graph to the plotter object specified as parent */
|
/** \brief width (pixels) of the error graph */
|
||||||
virtual void draw(JKQTPEnhancedPainter& painter);
|
double errorLineWidth;
|
||||||
protected:
|
/** \brief fill style, if the error curve should be filled */
|
||||||
|
Qt::BrushStyle errorFillStyle;
|
||||||
/** \brief fill the data array with data from the function plotFunction */
|
|
||||||
virtual void createPlotData( bool collectParams=true);
|
|
||||||
|
QBrush getBrush(JKQTPEnhancedPainter& painter) const;
|
||||||
};
|
QPen getLinePen(JKQTPEnhancedPainter& painter) const;
|
||||||
|
|
||||||
|
QBrush getErrorBrush(JKQTPEnhancedPainter& painter) const;
|
||||||
|
QPen getErrorLinePen(JKQTPEnhancedPainter &painter) const;
|
||||||
|
|
||||||
#endif // jkqtpgraphsvaluatedfunction_H
|
QVector<double> iparams, ierrorparams;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ x=f(y) \f$
|
||||||
|
\ingroup jkqtplotter_plots
|
||||||
|
|
||||||
|
*/
|
||||||
|
class LIB_EXPORT JKQTPyFunctionLineGraph: public JKQTPxFunctionLineGraph {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/** \brief class constructor */
|
||||||
|
inline JKQTPyFunctionLineGraph(JKQtBasePlotter* parent=nullptr):JKQTPxFunctionLineGraph(parent) {}
|
||||||
|
/** \brief class constructor */
|
||||||
|
inline JKQTPyFunctionLineGraph(JKQtPlotter* parent):JKQTPxFunctionLineGraph(parent) {}
|
||||||
|
|
||||||
|
/** \brief plots the graph to the plotter object specified as parent */
|
||||||
|
virtual void draw(JKQTPEnhancedPainter& painter);
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/** \brief fill the data array with data from the function plotFunction */
|
||||||
|
virtual void createPlotData( bool collectParams=true);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // jkqtpgraphsevaluatedfunction_H
|
@ -26,11 +26,11 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
|
||||||
double JKQTPxParsedFunctionLineGraphFunction(double x, void* data) {
|
double JKQTPxParsedFunctionLineGraphFunction(double x, void* data) {
|
||||||
JKQTPxParsedFunctionLineGraphFunctionData* d=(JKQTPxParsedFunctionLineGraphFunctionData*)data;
|
JKQTPxParsedFunctionLineGraph::JKQTPxParsedFunctionLineGraphFunctionData* d=(JKQTPxParsedFunctionLineGraph::JKQTPxParsedFunctionLineGraphFunctionData*)data;
|
||||||
if (d && d->parser && d->node) {
|
if (d && d->parser && d->node) {
|
||||||
try {
|
try {
|
||||||
d->parser->addVariableDouble("x", x);
|
d->parser->addVariableDouble("x", x);
|
||||||
@ -102,6 +102,14 @@ JKQTPxParsedFunctionLineGraph::~JKQTPxParsedFunctionLineGraph()
|
|||||||
delete efdata.parser;
|
delete efdata.parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JKQTPxParsedFunctionLineGraph::set_plotFunction(jkqtpPlotFunctionType &&f){
|
||||||
|
JKQTPxFunctionLineGraph::set_plotFunction(std::move(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
void JKQTPxParsedFunctionLineGraph::set_plotFunction(const jkqtpPlotFunctionType &f) {
|
||||||
|
JKQTPxFunctionLineGraph::set_plotFunction(f);
|
||||||
|
}
|
||||||
|
|
||||||
void JKQTPxParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
|
void JKQTPxParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
|
||||||
{
|
{
|
||||||
collectParameters();
|
collectParameters();
|
||||||
|
@ -27,19 +27,13 @@
|
|||||||
#include "jkqtplottertools/jkqtptools.h"
|
#include "jkqtplottertools/jkqtptools.h"
|
||||||
#include "jkqtplottertools/jkqtpmathparser.h"
|
#include "jkqtplottertools/jkqtpmathparser.h"
|
||||||
#include "jkqtplottertools/jkqtp_imexport.h"
|
#include "jkqtplottertools/jkqtp_imexport.h"
|
||||||
#include "jkqtplotter/jkqtpgraphsvaluatedfunction.h"
|
#include "jkqtplotter/jkqtpgraphsevaluatedfunction.h"
|
||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
class JKQtBasePlotter;
|
class JKQtBasePlotter;
|
||||||
class JKQtPlotter;
|
class JKQtPlotter;
|
||||||
|
|
||||||
|
|
||||||
struct JKQTPxParsedFunctionLineGraphFunctionData {
|
|
||||||
JKQTPMathParser* parser;
|
|
||||||
JKQTPMathParser::jkmpNode* node;
|
|
||||||
int varcount;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ y=f(x) \f$ The function is defined as a string and parsed by JKMathParser
|
/*! \brief This implements line plots where the data is taken from a user supplied function \f$ y=f(x) \f$ The function is defined as a string and parsed by JKMathParser
|
||||||
\ingroup jkqtplotter_plots
|
\ingroup jkqtplotter_plots
|
||||||
@ -63,26 +57,34 @@ class LIB_EXPORT JKQTPxParsedFunctionLineGraph: public JKQTPxFunctionLineGraph {
|
|||||||
|
|
||||||
JKQTPGET_SET_MACRO(QList<double>, parameters)
|
JKQTPGET_SET_MACRO(QList<double>, parameters)
|
||||||
JKQTPGET_SET_MACRO(QString, function)
|
JKQTPGET_SET_MACRO(QString, function)
|
||||||
JKQTPGET_SET_MACRO(int, parameterColumn)
|
|
||||||
|
|
||||||
JKQTPGET_SET_MACRO(QList<double>, errorParameters)
|
JKQTPGET_SET_MACRO(QList<double>, errorParameters)
|
||||||
JKQTPGET_SET_MACRO(QString, errorFunction)
|
JKQTPGET_SET_MACRO(QString, errorFunction)
|
||||||
JKQTPGET_SET_MACRO(int, errorParameterColumn)
|
|
||||||
|
/** \brief INTERNAL data structure
|
||||||
|
* \internal
|
||||||
|
*/
|
||||||
|
struct JKQTPxParsedFunctionLineGraphFunctionData {
|
||||||
|
JKQTPMathParser* parser;
|
||||||
|
JKQTPMathParser::jkmpNode* node;
|
||||||
|
int varcount;
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/** \brief the function to be evaluated for the plot. Use \c x as the free variable, e.g. \c "x^2+2" */
|
||||||
|
|
||||||
/** \brief which plot style to use from the parent plotter (via JKQtPlotterBase::getPlotStyle() and JKQtPlotterBase::getNextStyle() ) */
|
|
||||||
QString function;
|
QString function;
|
||||||
|
/** \brief values of the parameters \c p1 , \c p2 , \c p3 , ... */
|
||||||
QList<double> parameters;
|
QList<double> parameters;
|
||||||
JKQTPxParsedFunctionLineGraphFunctionData fdata;
|
JKQTPxParsedFunctionLineGraphFunctionData fdata;
|
||||||
int parameterColumn;
|
|
||||||
|
|
||||||
|
/** \brief the function to be evaluated to add error indicators to the graph. This function is evaluated to an error for every x. Use \c x as the free variable, e.g. \c "x^2+2". */
|
||||||
QString errorFunction;
|
QString errorFunction;
|
||||||
|
/** \brief values of the parameters \c p1 , \c p2 , \c p3 , ... for the error function*/
|
||||||
QList<double> errorParameters;
|
QList<double> errorParameters;
|
||||||
JKQTPxParsedFunctionLineGraphFunctionData efdata;
|
JKQTPxParsedFunctionLineGraphFunctionData efdata;
|
||||||
int errorParameterColumn;
|
|
||||||
|
|
||||||
JKQTPGET_SET_MACRO_I(jkqtpPlotFunctionType, plotFunction, clearData())
|
virtual void set_plotFunction(jkqtpPlotFunctionType&& f);
|
||||||
|
virtual void set_plotFunction(const jkqtpPlotFunctionType& f);
|
||||||
JKQTPGET_SET_MACRO_I(void*, params, clearData())
|
JKQTPGET_SET_MACRO_I(void*, params, clearData())
|
||||||
JKQTPGET_SET_MACRO(jkqtpPlotFunctionType, errorPlotFunction)
|
JKQTPGET_SET_MACRO(jkqtpPlotFunctionType, errorPlotFunction)
|
||||||
JKQTPGET_SET_MACRO(void*, errorParams)
|
JKQTPGET_SET_MACRO(void*, errorParams)
|
||||||
|
@ -1079,6 +1079,7 @@ JKQTPMathParser::jkmpTokenType JKQTPMathParser::getToken(){
|
|||||||
// else
|
// else
|
||||||
program->putback(ch1);
|
program->putback(ch1);
|
||||||
jkmpError("undefined operator '&'; Did you mean LOGICAL_AND ('&&' / 'and')?");
|
jkmpError("undefined operator '&'; Did you mean LOGICAL_AND ('&&' / 'and')?");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case '|':{
|
case '|':{
|
||||||
char ch1=0;
|
char ch1=0;
|
||||||
@ -1087,6 +1088,7 @@ JKQTPMathParser::jkmpTokenType JKQTPMathParser::getToken(){
|
|||||||
// else
|
// else
|
||||||
program->putback(ch1);
|
program->putback(ch1);
|
||||||
jkmpError("undefined operator '|'; Did you mean LOGICAL_OR ('||' / 'or')?");
|
jkmpError("undefined operator '|'; Did you mean LOGICAL_OR ('||' / 'or')?");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case '=':{
|
case '=':{
|
||||||
char ch1=0;
|
char ch1=0;
|
||||||
|
BIN
screenshots/jkqtplotter_simpletest_functionplot.png
Normal file
BIN
screenshots/jkqtplotter_simpletest_functionplot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
BIN
screenshots/jkqtplotter_simpletest_functionplot_small.png
Normal file
BIN
screenshots/jkqtplotter_simpletest_functionplot_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot.png
Normal file
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot_2overx.png
Normal file
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot_2overx.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot_small.cpt
Normal file
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot_small.cpt
Normal file
Binary file not shown.
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot_small.png
Normal file
BIN
screenshots/jkqtplotter_simpletest_parsedfunctionplot_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
96
test/simpletest_functionplot/README.md
Normal file
96
test/simpletest_functionplot/README.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/)
|
||||||
|
|
||||||
|
# JKQtPlotter
|
||||||
|
|
||||||
|
## Plotting Mathematical Functions as Line Graphs
|
||||||
|
This project (see `./test/simpletest_functionplot/`) demonstrates how to plot mathematical functions as line graphs. The functions may be defined as static C functions, C++ functors or c++ inline functions. See [test/simpletest_parsedfunctionplot](https://github.com/jkriege2/JKQtPlotter/tree/master/test/simpletest_parsedfunctionplot) for an example of how to use an internal equation parser provided with JKQtPlotter instead of directly defining functions.
|
||||||
|
|
||||||
|
The first example shows how to plot a C++ inline function:
|
||||||
|
```c++
|
||||||
|
JKQTPxFunctionLineGraph* func1=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func1->set_plotFunction([](double x, void* /*params*/) { return 0.2*x*x-0.015*x*x*x; });
|
||||||
|
func1->set_title("C++-inline function $0.2x^2-0.015x^3$");
|
||||||
|
plot->addGraph(func1);
|
||||||
|
```
|
||||||
|
|
||||||
|
In any such plot function, you can also use parameters, provided via the second parameter. Usually these are "internal parameters", defined by `func2->set_paramsV(p0, p1, ...)`:
|
||||||
|
```c++
|
||||||
|
JKQTPxFunctionLineGraph* func2=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func2->set_plotFunction([](double x, void* params) {
|
||||||
|
QVector<double>* p=static_cast<QVector<double>*>(params);
|
||||||
|
return p->at(0)*sin(2.0*M_PI*x*p->at(1));
|
||||||
|
});
|
||||||
|
// here we set the parameters p0, p1
|
||||||
|
func2->set_paramsV(5, 0.2);
|
||||||
|
func2->set_title("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||||
|
plot->addGraph(func2);
|
||||||
|
```
|
||||||
|
|
||||||
|
... but generally any pointer can be used as parameter (the set by `set_parameter(static_cast<void*>(myDataObject))`):
|
||||||
|
```c++
|
||||||
|
JKQTPxFunctionLineGraph* func3=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func3->set_plotFunction([](double x, void* params) {
|
||||||
|
QMap<QString,double>* p=static_cast<QMap<QString,double>*>(params);
|
||||||
|
return p->value("amplitude")*sin(2.0*M_PI*x*p->value("frequency"));
|
||||||
|
});
|
||||||
|
// here we set the parameters p0, p1
|
||||||
|
QMap<QString,double> params3;
|
||||||
|
params3["amplitude"]=-3;
|
||||||
|
params3["frequency"]=0.3;
|
||||||
|
func3->set_params(¶ms3);
|
||||||
|
func3->set_title("C++-inline function with ext. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||||
|
plot->addGraph(func3);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also use C++ functors (or function objects):
|
||||||
|
```c++
|
||||||
|
struct SincSqr {
|
||||||
|
public:
|
||||||
|
inline SincSqr(double amplitude): a(amplitude) {}
|
||||||
|
inline double operator()(double x, void* /*params*/) {
|
||||||
|
return a*sin(x)*sin(x)/x/x;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
double a;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
JKQTPxFunctionLineGraph* func4=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func4->set_plotFunction(SincSqr(-8));
|
||||||
|
func4->set_title("C++ functor $-8*\\sin^2(x)/x^2$");
|
||||||
|
plot->addGraph(func4);
|
||||||
|
```
|
||||||
|
|
||||||
|
... or simple static C functions:
|
||||||
|
```c++
|
||||||
|
double sinc(double x, void* /*params*/) {
|
||||||
|
return 10.0*sin(x)/x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
JKQTPxFunctionLineGraph* func5=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func5->set_plotFunction(&sinc);
|
||||||
|
func5->set_title("static C function $10*\\sin(x)/x$");
|
||||||
|
plot->addGraph(func5);
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally `JKQTPxFunctionLineGraph` provides a small set of special functions (polynomial, exponential, ...), which draw their parameters from the internal or external parameters:
|
||||||
|
```c++
|
||||||
|
JKQTPxFunctionLineGraph* func6=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func6->setSpecialFunction(JKQTPxFunctionLineGraph::Line);
|
||||||
|
// here we set offset and slope of the line
|
||||||
|
func6->set_paramsV(-1,1.5);
|
||||||
|
func6->set_title("special function: linear");
|
||||||
|
plot->addGraph(func6);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
This code snippets above result in a plot like this:
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_functionplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_functionplot.png)
|
||||||
|
|
||||||
|
|
||||||
|
[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/)
|
@ -0,0 +1,105 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QMap>
|
||||||
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
|
#include "jkqtplotter/jkqtpgraphsevaluatedfunction.h"
|
||||||
|
|
||||||
|
double sinc(double x, void* params) {
|
||||||
|
return 10.0*sin(x)/x;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SincSqr {
|
||||||
|
public:
|
||||||
|
inline SincSqr(double amplitude): a(amplitude) {}
|
||||||
|
inline double operator()(double x, void* params) {
|
||||||
|
return a*sin(x)*sin(x)/x/x;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
double a;
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
// 1. create a window that conatins a line-edit to edit a function
|
||||||
|
// and a JKQtPlotter to display the function, combine everything in a layout
|
||||||
|
QWidget mainWin;
|
||||||
|
JKQtPlotter* plot=new JKQtPlotter(&mainWin);
|
||||||
|
QVBoxLayout* layout=new QVBoxLayout;
|
||||||
|
mainWin.setLayout(layout);
|
||||||
|
layout->addWidget(plot);
|
||||||
|
|
||||||
|
// 2. now we add a JKQTPxFunctionLineGraph object, which will draw a simple function
|
||||||
|
// the function is defined as C++ inline function
|
||||||
|
JKQTPxFunctionLineGraph* func1=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func1->set_plotFunction([](double x, void* /*params*/) { return 0.2*x*x-0.015*x*x*x; });
|
||||||
|
func1->set_title("C++-inline function $0.2x^2-0.015x^3$");
|
||||||
|
plot->addGraph(func1);
|
||||||
|
|
||||||
|
// 3. now we add a JKQTPxFunctionLineGraph object, which will draw a simple function
|
||||||
|
// the function is again defined as C++ inline function, but now uses internal
|
||||||
|
// parameters (handed over to the function as a pointer to QVector<double>
|
||||||
|
JKQTPxFunctionLineGraph* func2=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func2->set_plotFunction([](double x, void* params) {
|
||||||
|
QVector<double>* p=static_cast<QVector<double>*>(params);
|
||||||
|
return p->at(0)*sin(2.0*M_PI*x*p->at(1));
|
||||||
|
});
|
||||||
|
// here we set the parameters p0, p1
|
||||||
|
func2->set_paramsV(5, 0.2);
|
||||||
|
func2->set_title("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||||
|
plot->addGraph(func2);
|
||||||
|
|
||||||
|
// 4. now we add a JKQTPxFunctionLineGraph object, which will draw a simple function
|
||||||
|
// the function is again defined as C++ inline function, but now uses external
|
||||||
|
// parameters, which may have any type (here QMap<QString,double)
|
||||||
|
JKQTPxFunctionLineGraph* func3=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func3->set_plotFunction([](double x, void* params) {
|
||||||
|
QMap<QString,double>* p=static_cast<QMap<QString,double>*>(params);
|
||||||
|
return p->value("amplitude")*sin(2.0*M_PI*x*p->value("frequency"));
|
||||||
|
});
|
||||||
|
// here we set the parameters p0, p1
|
||||||
|
QMap<QString,double> params3;
|
||||||
|
params3["amplitude"]=-3;
|
||||||
|
params3["frequency"]=0.3;
|
||||||
|
func3->set_params(¶ms3);
|
||||||
|
func3->set_title("C++-inline function with ext. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
|
||||||
|
plot->addGraph(func3);
|
||||||
|
|
||||||
|
// 5. of course the function may also be any C+ funtor object:
|
||||||
|
JKQTPxFunctionLineGraph* func4=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func4->set_plotFunction(SincSqr(-8));
|
||||||
|
func4->set_title("C++ functor $-8*\\sin^2(x)/x^2$");
|
||||||
|
plot->addGraph(func4);
|
||||||
|
|
||||||
|
|
||||||
|
// 6. now we use a JKQTPxFunctionLineGraph to draw a static C function
|
||||||
|
JKQTPxFunctionLineGraph* func5=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func5->set_plotFunction(&sinc);
|
||||||
|
func5->set_title("static C function $10*\\sin(x)/x$");
|
||||||
|
plot->addGraph(func5);
|
||||||
|
|
||||||
|
// 6. finally JKQTPxFunctionLineGraph defines a small set of common functions
|
||||||
|
JKQTPxFunctionLineGraph* func6=new JKQTPxFunctionLineGraph(plot);
|
||||||
|
func6->setSpecialFunction(JKQTPxFunctionLineGraph::Line);
|
||||||
|
// here we set offset and slope of the line
|
||||||
|
func6->set_paramsV(-1,1.5);
|
||||||
|
func6->set_title("special function: linear");
|
||||||
|
plot->addGraph(func6);
|
||||||
|
|
||||||
|
|
||||||
|
// 8. set some axis properties (we use LaTeX for nice equation rendering)
|
||||||
|
plot->getXAxis()->set_axisLabel(QObject::tr("x-axis"));
|
||||||
|
plot->getYAxis()->set_axisLabel(QObject::tr("y-axis"));
|
||||||
|
plot->get_plotter()->set_keyPosition(JKQTPkeyOutsideBottomLeft);
|
||||||
|
|
||||||
|
|
||||||
|
// 4. scale the plot so the graph is contained
|
||||||
|
plot->setXY(-10,10,-10,10);
|
||||||
|
|
||||||
|
// show window and make it a decent size
|
||||||
|
mainWin.show();
|
||||||
|
mainWin.resize(800,800);
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
# source code for this simple demo
|
||||||
|
SOURCES = jkqtplotter_simpletest_functionplot.cpp
|
||||||
|
|
||||||
|
# configure Qt
|
||||||
|
CONFIG += qt
|
||||||
|
QT += core gui xml svg
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||||
|
|
||||||
|
# output executable name
|
||||||
|
TARGET = jkqtplotter_simpletest_functionplot
|
||||||
|
|
||||||
|
|
||||||
|
# include JKQtPlotter source code
|
||||||
|
DEPENDPATH += . ../../lib
|
||||||
|
INCLUDEPATH += ../../lib
|
||||||
|
CONFIG (debug, debug|release):LIBS += -L../../lib/debug -ljkqtplotterlib
|
||||||
|
CONFIG (release):LIBS += -L../../lib/release -ljkqtplotterlib
|
||||||
|
|
||||||
|
win32-msvc*: DEFINES += _USE_MATH_DEFINES
|
||||||
|
|
||||||
|
# here you can activate some debug options
|
||||||
|
#DEFINES += SHOW_JKQTPLOTTER_DEBUG
|
||||||
|
#DEFINES += JKQTBP_AUTOTIMER
|
@ -0,0 +1,8 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_functionplot
|
||||||
|
|
||||||
|
jkqtplotterlib.file = ../../lib/jkqtplotterlib.pro
|
||||||
|
|
||||||
|
jkqtplotter_simpletest_functionplot.file=$$PWD/jkqtplotter_simpletest_functionplot.pro
|
||||||
|
jkqtplotter_simpletest_functionplot.depends = jkqtplotterlib
|
53
test/simpletest_parsedfunctionplot/README.md
Normal file
53
test/simpletest_parsedfunctionplot/README.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/)
|
||||||
|
|
||||||
|
# JKQtPlotter
|
||||||
|
|
||||||
|
## Plotting Parsed Mathematical Functions as Line Graphs
|
||||||
|
This project (see `./test/simpletest_parsedfunctionplot/`) demonstrates how to plot mathematical functions as line graphs. The functions are defined as strings that will be evaluated with the equation parser, integrated into JKQtPlotter.
|
||||||
|
|
||||||
|
Adding an evaluated funtion to a graph is very simple:
|
||||||
|
```c++
|
||||||
|
JKQTPxParsedFunctionLineGraph* parsedFunc=new JKQTPxParsedFunctionLineGraph(plot);
|
||||||
|
parsedFunc->set_function("sin(x*8)*exp(-x/4)");
|
||||||
|
parsedFunc->set_title("user function");
|
||||||
|
```
|
||||||
|
As you can see a graph of the type `JKQTPxParsedFunctionLineGraph` is used, which plots a function that depends on the variable `x`. The given function is parsed and evaluated (see [`lib/jkqtplottertools/jkqtpmathparser.h`](https://github.com/jkriege2/JKQtPlotter/blob/master/lib/jkqtplottertools/jkqtpmathparser.h) for details on the features of the math parser). An intelligent drawing algorithm chooses the number of control points for drawing a smooth graph, with sufficient amount of details, by evaluating locally the slope of the function.
|
||||||
|
|
||||||
|
In the example in [`test/simpletest_parsedfunctionplot/simpletest_parsedfunctionplot.cpp`](https://github.com/jkriege2/JKQtPlotter/blob/master/test/simpletest_parsedfunctionplot/simpletest_parsedfunctionplot.cpp) we do not simply set a fixed function, but add a `QLineEdit` which allows to edit the function and redraws it, once ENTER is pressed:
|
||||||
|
```c++
|
||||||
|
JKQtPlotter* plot=new JKQtPlotter(&mainWin);
|
||||||
|
QLineEdit* edit=new QLineEdit(&mainWin);
|
||||||
|
edit->setToolTip("enter a function in dependence of the variable <tt>x</tt> and press ENTER to update the graph");
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
|
||||||
|
// 2. now we add a JKQTPxParsedFunctionLineGraph object, which will draw the function from
|
||||||
|
// the line edit
|
||||||
|
JKQTPxParsedFunctionLineGraph* parsedFunc=new JKQTPxParsedFunctionLineGraph(plot);
|
||||||
|
plot->addGraph(parsedFunc);
|
||||||
|
// finally we connect the line edit with the graph, whenever RETURN is pressed,
|
||||||
|
// the graph is updated:
|
||||||
|
auto updateGraphFunctor=
|
||||||
|
[=]() {
|
||||||
|
parsedFunc->set_title("user function: \\verb{"+edit->text()+"}");
|
||||||
|
parsedFunc->set_function(edit->text());
|
||||||
|
plot->update_plot();
|
||||||
|
};
|
||||||
|
QObject::connect(edit, &QLineEdit::returnPressed, updateGraphFunctor);
|
||||||
|
QObject::connect(edit, &QLineEdit::editingFinished, updateGraphFunctor);
|
||||||
|
edit->setText("sin(x*8)*exp(-x/4)");
|
||||||
|
updateGraphFunctor();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
This code snippet results in a plot like this:
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_parsedfunctionplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parsedfunctionplot.png)
|
||||||
|
|
||||||
|
the adaptive capabilities of the rendering algorithm can be seen, when plotting e.g. `2/x`, which is drawn smoothely, even around the undefined value at `x=0`:
|
||||||
|
|
||||||
|
![jkqtplotter_simpletest_parsedfunctionplot_2overx.png](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_parsedfunctionplot_2overx.png.png)
|
||||||
|
|
||||||
|
|
||||||
|
[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/)
|
@ -0,0 +1,54 @@
|
|||||||
|
#include <QApplication>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include "jkqtplotter/jkqtplotter.h"
|
||||||
|
#include "jkqtplotter/jkqtpgraphsparsedfunction.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
// 1. create a window that conatins a line-edit to edit a function
|
||||||
|
// and a JKQtPlotter to display the function, combine everything in a layout
|
||||||
|
QWidget mainWin;
|
||||||
|
QLineEdit* edit=new QLineEdit(&mainWin);
|
||||||
|
edit->setToolTip("enter a function in dependence of the variable <tt>x</tt> and press ENTER to update the graph");
|
||||||
|
JKQtPlotter* plot=new JKQtPlotter(&mainWin);
|
||||||
|
QVBoxLayout* layout=new QVBoxLayout;
|
||||||
|
mainWin.setLayout(layout);
|
||||||
|
layout->addWidget(edit);
|
||||||
|
layout->addWidget(plot);
|
||||||
|
|
||||||
|
// 2. now we add a JKQTPxParsedFunctionLineGraph object, which will draw the function from
|
||||||
|
// the line edit
|
||||||
|
JKQTPxParsedFunctionLineGraph* parsedFunc=new JKQTPxParsedFunctionLineGraph(plot);
|
||||||
|
plot->addGraph(parsedFunc);
|
||||||
|
// finally we connect the line edit with the graph, whenever RETURN is pressed,
|
||||||
|
// the graph is updated:
|
||||||
|
auto updateGraphFunctor=
|
||||||
|
[=]() {
|
||||||
|
parsedFunc->set_title("user function: \\verb{"+edit->text()+"}");
|
||||||
|
parsedFunc->set_function(edit->text());
|
||||||
|
plot->update_plot();
|
||||||
|
};
|
||||||
|
QObject::connect(edit, &QLineEdit::returnPressed, updateGraphFunctor);
|
||||||
|
QObject::connect(edit, &QLineEdit::editingFinished, updateGraphFunctor);
|
||||||
|
edit->setText("sin(x*8)*exp(-x/4)");
|
||||||
|
updateGraphFunctor();
|
||||||
|
|
||||||
|
|
||||||
|
// 3. set some axis properties (we use LaTeX for nice equation rendering)
|
||||||
|
plot->getXAxis()->set_axisLabel(QObject::tr("x-axis"));
|
||||||
|
plot->getYAxis()->set_axisLabel(QObject::tr("y-axis"));
|
||||||
|
|
||||||
|
|
||||||
|
// 4. scale the plot so the graph is contained
|
||||||
|
plot->setXY(-10,10,-10,10);
|
||||||
|
|
||||||
|
// show window and make it a decent size
|
||||||
|
mainWin.show();
|
||||||
|
mainWin.resize(600,400);
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
# source code for this simple demo
|
||||||
|
SOURCES = jkqtplotter_simpletest_parsedfunctionplot.cpp
|
||||||
|
|
||||||
|
# configure Qt
|
||||||
|
CONFIG += qt
|
||||||
|
QT += core gui xml svg
|
||||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
|
||||||
|
|
||||||
|
# output executable name
|
||||||
|
TARGET = jkqtplotter_simpletest_parsedfunctionplot
|
||||||
|
|
||||||
|
|
||||||
|
# include JKQtPlotter source code
|
||||||
|
DEPENDPATH += . ../../lib
|
||||||
|
INCLUDEPATH += ../../lib
|
||||||
|
CONFIG (debug, debug|release):LIBS += -L../../lib/debug -ljkqtplotterlib
|
||||||
|
CONFIG (release):LIBS += -L../../lib/release -ljkqtplotterlib
|
||||||
|
|
||||||
|
win32-msvc*: DEFINES += _USE_MATH_DEFINES
|
||||||
|
|
||||||
|
# here you can activate some debug options
|
||||||
|
#DEFINES += SHOW_JKQTPLOTTER_DEBUG
|
||||||
|
#DEFINES += JKQTBP_AUTOTIMER
|
@ -0,0 +1,8 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
|
||||||
|
SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_parsedfunctionplot
|
||||||
|
|
||||||
|
jkqtplotterlib.file = ../../lib/jkqtplotterlib.pro
|
||||||
|
|
||||||
|
jkqtplotter_simpletest_parsedfunctionplot.file=$$PWD/jkqtplotter_simpletest_parsedfunctionplot.pro
|
||||||
|
jkqtplotter_simpletest_parsedfunctionplot.depends = jkqtplotterlib
|
Loading…
Reference in New Issue
Block a user