- added further base-class JKQTPEvaluatedFunctionWithParamsGraphBase, which extends JKQTPEvaluatedFunctionGraphBase with parameters

- modified plot-function with parameters, as the old unsafe way of giving a void* for parameters is no longer necessary with C++-lambdas and std::bind()
This commit is contained in:
jkriege2 2020-09-05 13:47:46 +02:00
parent dcdee469fe
commit 414e12920e
10 changed files with 302 additions and 476 deletions

View File

@ -18,31 +18,14 @@ The first example shows how to plot a C++ inline function:
In any such plot function, you can also use parameters, provided via the second parameter. Usually these are "internal parameters", defined by `func2->setParamsV(p0, p1, ...)`: In any such plot function, you can also use parameters, provided via the second parameter. Usually these are "internal parameters", defined by `func2->setParamsV(p0, p1, ...)`:
```.cpp ```.cpp
JKQTPXFunctionLineGraph* func2=new JKQTPXFunctionLineGraph(plot); JKQTPXFunctionLineGraph* func2=new JKQTPXFunctionLineGraph(plot);
func2->setPlotFunctionFunctor([](double x, void* params) { func2->setPlotFunctionFunctor([](double x, const QVector<double>& p) {
QVector<double>* p=static_cast<QVector<double>*>(params); return p.at(0)*sin(2.0*JKQTPSTATISTICS_PI*x*p.at(1));
return p->at(0)*sin(2.0*M_PI*x*p->at(1)); }); // here we set the parameters p0, p1
});
// here we set the parameters p0, p1
func2->setParamsV(5, 0.2); func2->setParamsV(5, 0.2);
func2->setTitle("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$"); func2->setTitle("C++-inline function with int. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
plot->addGraph(func2); plot->addGraph(func2);
``` ```
... but generally any pointer can be used as parameter (the set by `setParameter(static_cast<void*>(myDataObject))`):
```.cpp
JKQTPXFunctionLineGraph* func3=new JKQTPXFunctionLineGraph(plot);
func3->setPlotFunctionFunctor([](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->setParams(&params3);
func3->setTitle("C++-inline function with ext. params $p_0\\cdot\\sin(x*2.0*\\pi\\cdot p_1)$");
plot->addGraph(func3);
```
# C++ functors as plot functions # C++ functors as plot functions

View File

@ -55,9 +55,8 @@ void drawExample(QApplication& app, const QString& name) {
// the function is again defined as C++ inline function, but now uses internal // 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> // parameters (handed over to the function as a pointer to QVector<double>
TFUNCGRAPH* func2=new TFUNCGRAPH(plot); TFUNCGRAPH* func2=new TFUNCGRAPH(plot);
func2->setPlotFunctionFunctor([](double x, void* params) { func2->setPlotFunctionFunctor([](double x, const QVector<double>& p) {
QVector<double>* p=static_cast<QVector<double>*>(params); return p.at(0)*sin(2.0*JKQTPSTATISTICS_PI*x*p.at(1));
return p->at(0)*sin(2.0*JKQTPSTATISTICS_PI*x*p->at(1));
}); });
// here we set the parameters p0, p1 // here we set the parameters p0, p1
func2->setParamsV(5, 0.2); func2->setParamsV(5, 0.2);
@ -68,23 +67,7 @@ void drawExample(QApplication& app, const QString& name) {
}); });
plot->addGraph(func2); plot->addGraph(func2);
// 4. now we add a JKQTPXFunctionLineGraph object, which will draw a simple function // 4. of course the function may also be any C+ funtor object:
// the function is again defined as C++ inline function, but now uses external
// parameters, which may have any type (here QMap<QString,double)
/*TFUNCGRAPH* func3=new TFUNCGRAPH(plot);
func3->setPlotFunctionFunctor([](double x, void* params) {
QMap<QString,double>* p=static_cast<QMap<QString,double>*>(params);
return p->value("amplitude")*sin(2.0*JKQTPSTATISTICS_PI*x*p->value("frequency"));
});
// here we set the parameters p0, p1
QMap<QString,double> params3;
params3["amplitude"]=-3;
params3["frequency"]=0.3;
func3->setParams(&params3);
func3->setTitle("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:
TFUNCGRAPH* func4=new TFUNCGRAPH(plot); TFUNCGRAPH* func4=new TFUNCGRAPH(plot);
func4->setPlotFunctionFunctor(SincSqr(-8)); func4->setPlotFunctionFunctor(SincSqr(-8));
func4->setTitle("C++ functor $-8*\\sin^2(x)/x^2$"); func4->setTitle("C++ functor $-8*\\sin^2(x)/x^2$");
@ -95,7 +78,7 @@ void drawExample(QApplication& app, const QString& name) {
plot->addGraph(func4); plot->addGraph(func4);
// 6. now we use a JKQTPXFunctionLineGraph to draw a static C function // 5. now we use a JKQTPXFunctionLineGraph to draw a static C function
TFUNCGRAPH* func5=new TFUNCGRAPH(plot); TFUNCGRAPH* func5=new TFUNCGRAPH(plot);
func5->setPlotFunctionFunctor(&sinc); func5->setPlotFunctionFunctor(&sinc);
func5->setTitle("static C function $10*\\sin(x)/x$"); func5->setTitle("static C function $10*\\sin(x)/x$");
@ -105,7 +88,7 @@ void drawExample(QApplication& app, const QString& name) {
}); });
plot->addGraph(func5); plot->addGraph(func5);
// 7. finally JKQTPXFunctionLineGraph defines a small set of common functions // 6. finally JKQTPXFunctionLineGraph defines a small set of common functions
TFUNCGRAPH* func6=new TFUNCGRAPH(plot); TFUNCGRAPH* func6=new TFUNCGRAPH(plot);
func6->setSpecialFunction(TFUNCGRAPH::Line); func6->setSpecialFunction(TFUNCGRAPH::Line);
// here we set offset p0=-1 and slope p1=1.5 of the line p0+p1*x // here we set offset p0=-1 and slope p1=1.5 of the line p0+p1*x
@ -140,7 +123,7 @@ void drawExample(QApplication& app, const QString& name) {
plot->getPlotter()->setKeyPosition(JKQTPKeyOutsideBottomLeft); plot->getPlotter()->setKeyPosition(JKQTPKeyOutsideBottomLeft);
// 4. scale the plot so the graph is contained // 9. scale the plot so the graph is contained
plot->setXY(-10,10,-10,10); plot->setXY(-10,10,-10,10);
plot->redrawPlot(); plot->redrawPlot();

View File

@ -34,12 +34,11 @@
JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTBasePlotter* parent): JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTBasePlotter* parent):
JKQTPEvaluatedFunctionGraphBase(parent) JKQTPEvaluatedFunctionWithParamsGraphBase(parent)
{ {
functionType=SpecialFunction::UserFunction; functionType=SpecialFunction::UserFunction;
drawLine=true; drawLine=true;
fillCurve=false; fillCurve=false;
params=nullptr;
initLineStyle(parent, parentPlotStyle); initLineStyle(parent, parentPlotStyle);
initFillStyle(parent, parentPlotStyle); initFillStyle(parent, parentPlotStyle);
@ -53,7 +52,6 @@ JKQTPXFunctionLineGraph::JKQTPXFunctionLineGraph(JKQTBasePlotter* parent):
errorLineWidth=1; errorLineWidth=1;
errorFillStyle=Qt::SolidPattern; errorFillStyle=Qt::SolidPattern;
parameterColumn=-1;
errorParameterColumn=-1; errorParameterColumn=-1;
@ -181,20 +179,6 @@ jkqtpSimplePlotFunctionType JKQTPXFunctionLineGraph::getSimplePlotFunction() con
return simplePlotFunction; return simplePlotFunction;
} }
void JKQTPXFunctionLineGraph::setParams(void *__value)
{
if (this->params != __value) {
this->params = __value;
data.clear();
}
}
void *JKQTPXFunctionLineGraph::getParams() const
{
return this->params;
}
void JKQTPXFunctionLineGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { void JKQTPXFunctionLineGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
QPen p=getLinePen(painter, parent); QPen p=getLinePen(painter, parent);
@ -236,7 +220,7 @@ void JKQTPXFunctionLineGraph::createPlotData(bool collectParams) {
if (!plotFunction && !simplePlotFunction) return; if (!plotFunction && !simplePlotFunction) return;
jkqtpSimplePlotFunctionType func; jkqtpSimplePlotFunctionType func;
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, params); if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, getInternalParams());
else if (simplePlotFunction) func=simplePlotFunction; else if (simplePlotFunction) func=simplePlotFunction;
const double xmin=parent->getXMin(); const double xmin=parent->getXMin();
@ -251,29 +235,8 @@ void JKQTPXFunctionLineGraph::createPlotData(bool collectParams) {
void JKQTPXFunctionLineGraph::collectParameters() void JKQTPXFunctionLineGraph::collectParameters()
{ {
if (parent && parameterColumn>=0) { JKQTPEvaluatedFunctionWithParamsGraphBase::collectParameters();
iparams.clear();
JKQTPDatastore* datastore=parent->getDatastore();
int imin=0;
int imax=static_cast<int>(datastore->getRows(parameterColumn));
for (int i=imin; i<imax; i++) {
double xv=datastore->get(parameterColumn,i);
iparams<<xv;
}
//qDebug()<<"iparams_beforeclean:";
//for (int i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
int i=iparams.size()-1;
while (i>=0 && !JKQTPIsOKFloat(iparams[i])) {
iparams.remove(i,1);
i--;
}
//qDebug()<<"iparams:";
//for (i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
params=&iparams;
}
if (parent && errorParameterColumn>=0) { if (parent && errorParameterColumn>=0) {
ierrorparams.clear(); ierrorparams.clear();
JKQTPDatastore* datastore=parent->getDatastore(); JKQTPDatastore* datastore=parent->getDatastore();
@ -349,7 +312,7 @@ void JKQTPXFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
double yv=backtransformY(y); double yv=backtransformY(y);
double ype=0, yme=0; double ype=0, yme=0;
if ((drawErrorLines || drawErrorPolygons) && (static_cast<bool>(errorPlotFunction))) { if ((drawErrorLines || drawErrorPolygons) && (static_cast<bool>(errorPlotFunction))) {
double e=errorPlotFunction(xv, errorParams); double e=errorPlotFunction(xv, getInternalErrorParams());
ype=transformY(yv+e); ype=transformY(yv+e);
yme=transformY(yv-e); yme=transformY(yv-e);
ype=qBound(yami, ype, yama); ype=qBound(yami, ype, yama);
@ -538,7 +501,7 @@ void JKQTPYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
double yv=backtransformY(y); double yv=backtransformY(y);
double xpe=0, xme=0; double xpe=0, xme=0;
if ((drawErrorLines || drawErrorPolygons) && (static_cast<bool>(errorPlotFunction))) { if ((drawErrorLines || drawErrorPolygons) && (static_cast<bool>(errorPlotFunction))) {
double e=errorPlotFunction(yv, errorParams); double e=errorPlotFunction(yv, getInternalErrorParams());
xpe=transformX(xv+e); xpe=transformX(xv+e);
xme=transformX(xv-e); xme=transformX(xv-e);
xpe=qBound(xami, xpe, xama); xpe=qBound(xami, xpe, xama);
@ -618,7 +581,7 @@ void JKQTPYFunctionLineGraph::createPlotData(bool collectParams) {
if (!plotFunction && !simplePlotFunction) return; if (!plotFunction && !simplePlotFunction) return;
jkqtpSimplePlotFunctionType func; jkqtpSimplePlotFunctionType func;
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, params); if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, getInternalParams());
else if (simplePlotFunction) func=simplePlotFunction; else if (simplePlotFunction) func=simplePlotFunction;
const double ymin=parent->getYMin(); const double ymin=parent->getYMin();
@ -654,48 +617,6 @@ QPen JKQTPXFunctionLineGraph::getErrorLinePen(JKQTPEnhancedPainter& painter) con
} }
void JKQTPXFunctionLineGraph::setParams(const QVector<double> &params)
{
iparams=params;
setParams(&iparams);
}
void JKQTPXFunctionLineGraph::setCopiedParams(const double *params, int N)
{
QVector<double> v;
for (int i=0; i<N; i++) { v<<params[i]; }
setParams(v);
}
void JKQTPXFunctionLineGraph::setParamsV(double p1) {
QVector<double> p;
p<<p1;
setParams(p);
}
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2) {
QVector<double> p;
p<<p1<<p2;
setParams(p);
}
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2, double p3) {
QVector<double> p;
p<<p1<<p2<<p3;
setParams(p);
}
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4) {
QVector<double> p;
p<<p1<<p2<<p3<<p4;
setParams(p);
}
void JKQTPXFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4, double p5) {
QVector<double> p;
p<<p1<<p2<<p3<<p4<<p5;
setParams(p);
}
void JKQTPXFunctionLineGraph::setErrorParams(const QVector<double> &errorParams) void JKQTPXFunctionLineGraph::setErrorParams(const QVector<double> &errorParams)
{ {
@ -703,20 +624,6 @@ void JKQTPXFunctionLineGraph::setErrorParams(const QVector<double> &errorParams)
setErrorParams(&ierrorparams); setErrorParams(&ierrorparams);
} }
void JKQTPXFunctionLineGraph::setParameterColumn(int __value)
{
this->parameterColumn = __value;
}
int JKQTPXFunctionLineGraph::getParameterColumn() const
{
return this->parameterColumn;
}
void JKQTPXFunctionLineGraph::setParameterColumn(size_t __value) {
this->parameterColumn = static_cast<int>(__value);
}
void JKQTPXFunctionLineGraph::setErrorParameterColumn(int __value) void JKQTPXFunctionLineGraph::setErrorParameterColumn(int __value)
{ {
this->errorParameterColumn = __value; this->errorParameterColumn = __value;
@ -784,14 +691,13 @@ double JKQTPXFunctionLineGraph::getErrorLineWidth() const
void JKQTPXFunctionLineGraph::setSpecialFunction(JKQTPXFunctionLineGraph::SpecialFunction function) void JKQTPXFunctionLineGraph::setSpecialFunction(JKQTPXFunctionLineGraph::SpecialFunction function)
{ {
if (function==JKQTPXFunctionLineGraph::Polynomial) { if (function==JKQTPXFunctionLineGraph::Polynomial) {
setPlotFunctionFunctor([](double x, void* param) { setPlotFunctionFunctor([](double x, const QVector<double>& param) {
double res=0; double res=0;
QVector<double>* d=static_cast<QVector<double>*>(param); if (param.size()>0) {
if (d && d->size()>0) { res=param.value(0,0);
res=d->value(0,0);
double xx=x; double xx=x;
for (int i=1; i<d->size(); i++) { for (int i=1; i<param.size(); i++) {
res=res+d->value(i,0)*xx; res=res+param.value(i,0)*xx;
xx=xx*x; xx=xx*x;
} }
} }
@ -799,30 +705,23 @@ void JKQTPXFunctionLineGraph::setSpecialFunction(JKQTPXFunctionLineGraph::Specia
return res; return res;
}); });
} }
else if (function==JKQTPXFunctionLineGraph::Exponential) setPlotFunctionFunctor([](double x, void* param) { else if (function==JKQTPXFunctionLineGraph::Exponential) setPlotFunctionFunctor([](double x, const QVector<double>& param) {
double res=0; double res=0;
QVector<double>* d=static_cast<QVector<double>*>(param); if (param.size()>=3) {
if (d) { res=param.value(0,0)+param.value(1,0)*exp(x/param.value(2,0));
if (d->size()>=3) { } else if (param.size()>=2) {
res=d->value(0,0)+d->value(1,0)*exp(x/d->value(2,0)); res=param.value(0,0)*exp(x/param.value(1,0));
} else if (d->size()>=2) {
res=d->value(0,0)*exp(x/d->value(1,0));
}
} }
return res; return res;
}); });
else if (function==JKQTPXFunctionLineGraph::PowerLaw) setPlotFunctionFunctor([](double x, void* param) { else if (function==JKQTPXFunctionLineGraph::PowerLaw) setPlotFunctionFunctor([](double x, const QVector<double>& param) {
double res=0; double res=0;
QVector<double>* d=static_cast<QVector<double>*>(param); if (param.size()>=3) {
if (d) { res=param.value(0,0)+param.value(1,0)*pow(x, param.value(2,1));
if (d->size()>=3) { } else if (param.size()>=2) {
res=d->value(0,0)+d->value(1,0)*pow(x, d->value(2,1)); res=param.value(0,0)*pow(x, param.value(1,1));
} else if (d->size()>=2) { } else if (param.size()>=1) {
res=d->value(0,0)*pow(x, d->value(1,1)); res=pow(x, param.value(0,1));
} else if (d->size()>=1) {
res=pow(x, d->value(0,1));
}
} }
return res; return res;
}); });
@ -834,9 +733,6 @@ JKQTPXFunctionLineGraph::SpecialFunction JKQTPXFunctionLineGraph::getFunctionTyp
return functionType; return functionType;
} }
QVector<double> JKQTPXFunctionLineGraph::getInternalParams() const {
return iparams;
}
QVector<double> JKQTPXFunctionLineGraph::getInternalErrorParams() const { QVector<double> JKQTPXFunctionLineGraph::getInternalErrorParams() const {
return ierrorparams; return ierrorparams;
} }
@ -910,6 +806,6 @@ void *JKQTPXFunctionLineGraph::getErrorParams() const
bool JKQTPXFunctionLineGraph::usesColumn(int c) const bool JKQTPXFunctionLineGraph::usesColumn(int c) const
{ {
return (c==parameterColumn)||(c==errorParameterColumn); return JKQTPEvaluatedFunctionWithParamsGraphBase::usesColumn(c)||(c==errorParameterColumn);
} }

View File

@ -43,7 +43,7 @@
influence its result. Parameters are given as a pointer to some memory location. The function has to 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. know on its own how to interpret these.
*/ */
typedef std::function<double(double, void*)> jkqtpPlotFunctionType; typedef std::function<double(double, const QVector<double>&)> jkqtpPlotFunctionType;
/*! \brief simplified type of functions (without parameters) that may be plotted by JKQTPXFunctionLineGraph and JKQTPYFunctionLineGraph /*! \brief simplified type of functions (without parameters) that may be plotted by JKQTPXFunctionLineGraph and JKQTPYFunctionLineGraph
\ingroup jkqtplotter_functiongraphs \ingroup jkqtplotter_functiongraphs
@ -74,7 +74,7 @@ typedef std::function<double(double)> jkqtpSimplePlotFunctionType;
\see \ref JKQTPlotterFunctionPlots, JKQTPAdaptiveFunctionGraphEvaluator, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph, jkqtpstatAddPolyFit(), jkqtpstatAddWeightedRegression(), jkqtpstatAddRobustIRLSRegression(), jkqtpstatAddRegression(), jkqtpstatAddLinearWeightedRegression(), jkqtpstatAddRobustIRLSLinearRegression(), jkqtpstatAddLinearRegression() \see \ref JKQTPlotterFunctionPlots, JKQTPAdaptiveFunctionGraphEvaluator, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph, jkqtpstatAddPolyFit(), jkqtpstatAddWeightedRegression(), jkqtpstatAddRobustIRLSRegression(), jkqtpstatAddRegression(), jkqtpstatAddLinearWeightedRegression(), jkqtpstatAddRobustIRLSLinearRegression(), jkqtpstatAddLinearRegression()
*/ */
class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunctionGraphBase, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin { class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunctionWithParamsGraphBase, public JKQTPGraphLineStyleMixin, public JKQTPGraphFillStyleMixin {
Q_OBJECT Q_OBJECT
public: public:
@ -158,27 +158,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
/*! \copydoc simplePlotFunction */ \ /*! \copydoc simplePlotFunction */ \
virtual jkqtpSimplePlotFunctionType getSimplePlotFunction () const; virtual jkqtpSimplePlotFunctionType getSimplePlotFunction () const;
/*! \copydoc params */
virtual void setParams(void* __value);
/*! \copydoc params */
void* getParams() const;
/** \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!!!) */
virtual void setParams(const QVector<double>& params);
/** \brief sets the params from a copy of the given array of length \a N */
void setCopiedParams(const double* params, int N);
/** \brief set an internal parameter vector as function parameters, initialized with {p1} */
void setParamsV(double p1);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2} */
void setParamsV(double p1, double p2);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3} */
void setParamsV(double p1, double p2, double p3);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4} */
void setParamsV(double p1, double p2, double p3, double p4);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4,p5} */
void setParamsV(double p1, double p2, double p3, double p4, double p5);
/** \brief returns the currently set internal parameter vector */
QVector<double> getInternalParams() const;
/** \brief returns the currently set internal parameter vector */ /** \brief returns the currently set internal parameter vector */
QVector<double> getInternalErrorParams() const; QVector<double> getInternalErrorParams() const;
@ -220,13 +200,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
void *getErrorParams() const; void *getErrorParams() const;
/** \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!!!) */ /** \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 setErrorParams(const QVector<double>& errorParams); void setErrorParams(const QVector<double>& errorParams);
/*! \copydoc parameterColumn */
void setParameterColumn(int __value);
/*! \copydoc parameterColumn */
int getParameterColumn() const;
/*! \copydoc parameterColumn */
void setParameterColumn (size_t __value);
/*! \copydoc errorParameterColumn */ /*! \copydoc errorParameterColumn */
void setErrorParameterColumn(int __value); void setErrorParameterColumn(int __value);
/*! \copydoc errorParameterColumn */ /*! \copydoc errorParameterColumn */
@ -264,16 +237,14 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
/** \brief returns, which special function is set (or if any is set) */ /** \brief returns, which special function is set (or if any is set) */
SpecialFunction getFunctionType() const; SpecialFunction getFunctionType() const;
protected: protected:
/** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams and ierrorparams */
virtual void collectParameters() override;
/** \brief fill the data array with data from the function plotFunction */ /** \brief fill the data array with data from the function plotFunction */
virtual void createPlotData( bool collectParams=true) override; virtual void createPlotData( bool collectParams=true) override;
/** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams and ierrorparams */
virtual void collectParameters();
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the plot function */
int parameterColumn;
/** \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 */ /** \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; int errorParameterColumn;
@ -287,8 +258,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
jkqtpSimplePlotFunctionType simplePlotFunction; jkqtpSimplePlotFunctionType simplePlotFunction;
/** \brief indicates whether a special function is set (and if so, which one), or a user-supplied function */ /** \brief indicates whether a special function is set (and if so, which one), or a user-supplied function */
SpecialFunction functionType; SpecialFunction functionType;
/** \brief pointer to the parameters supplied to the plotting funtion */
void* params;
/** \brief indicates whether an error polygon should be drawn */ /** \brief indicates whether an error polygon should be drawn */
@ -317,8 +286,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXFunctionLineGraph: public JKQTPEvaluatedFunct
QBrush getErrorBrush(JKQTPEnhancedPainter& painter) const; QBrush getErrorBrush(JKQTPEnhancedPainter& painter) const;
QPen getErrorLinePen(JKQTPEnhancedPainter &painter) const; QPen getErrorLinePen(JKQTPEnhancedPainter &painter) const;
/** \brief internal storage for the current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) */
QVector<double> iparams;
/** \brief internal storage for the current error function parameters for errorPlotFunction (which may stem from different sources, as direct data, a datastore column ...) */ /** \brief internal storage for the current error function parameters for errorPlotFunction (which may stem from different sources, as direct data, a datastore column ...) */
QVector<double> ierrorparams; QVector<double> ierrorparams;
}; };

View File

@ -29,6 +29,7 @@
#include "jkqtplotter/jkqtpbaseelements.h" #include "jkqtplotter/jkqtpbaseelements.h"
#include "jkqtplotter/jkqtplotter.h" #include "jkqtplotter/jkqtplotter.h"
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
@ -131,4 +132,156 @@ bool JKQTPEvaluatedFunctionGraphBase::getDisplaySamplePoints() const
return this->displaySamplePoints; return this->displaySamplePoints;
} }
bool JKQTPEvaluatedFunctionGraphBase::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero)
{
if (data.size()==0) createPlotData();
if (data.size()>0){
bool start=true;
minx=0;
maxx=0;
smallestGreaterZero=0;
for (auto const& d: data) {
if (JKQTPIsOKFloat(d.x())) {
if (start || d.x()>maxx) maxx=d.x();
if (start || d.x()<minx) minx=d.x();
double xvsgz;
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
start=false;
}
}
return !start;
} else {
smallestGreaterZero=minx=maxx=0; return false;
}
}
bool JKQTPEvaluatedFunctionGraphBase::getYMinMax(double &miny, double &maxy, double &smallestGreaterZero)
{
if (data.size()==0) createPlotData();
if (data.size()>0){
bool start=true;
miny=0;
maxy=0;
smallestGreaterZero=0;
for (auto const& d: data) {
if (JKQTPIsOKFloat(d.y())) {
if (start || d.y()>maxy) maxy=d.y();
if (start || d.y()<miny) miny=d.y();
double xvsgz;
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
start=false;
}
}
return !start;
} else {
smallestGreaterZero=miny=maxy=0; return false;
}
}
JKQTPEvaluatedFunctionWithParamsGraphBase::JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTBasePlotter *parent):
parameterColumn(-1)
{
}
JKQTPEvaluatedFunctionWithParamsGraphBase::JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTPlotter *parent):
JKQTPEvaluatedFunctionWithParamsGraphBase(parent->getPlotter())
{
}
JKQTPEvaluatedFunctionWithParamsGraphBase::~JKQTPEvaluatedFunctionWithParamsGraphBase()
{
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::collectParameters()
{
if (parent && parameterColumn>=0) {
iparams.clear();
JKQTPDatastore* datastore=parent->getDatastore();
int imin=0;
int imax=static_cast<int>(datastore->getRows(parameterColumn));
for (int i=imin; i<imax; i++) {
double xv=datastore->get(parameterColumn,i);
iparams<<xv;
}
int i=iparams.size()-1;
while (i>=0 && !JKQTPIsOKFloat(iparams[i])) {
iparams.remove(i,1);
i--;
}
}
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParams(const QVector<double> &params)
{
iparams=params;
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setCopiedParams(const double *params, int N)
{
QVector<double> v;
for (int i=0; i<N; i++) { v<<params[i]; }
setParams(v);
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1) {
QVector<double> p;
p<<p1;
setParams(p);
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2) {
QVector<double> p;
p<<p1<<p2;
setParams(p);
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2, double p3) {
QVector<double> p;
p<<p1<<p2<<p3;
setParams(p);
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2, double p3, double p4) {
QVector<double> p;
p<<p1<<p2<<p3<<p4;
setParams(p);
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParamsV(double p1, double p2, double p3, double p4, double p5) {
QVector<double> p;
p<<p1<<p2<<p3<<p4<<p5;
setParams(p);
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParameterColumn(int __value)
{
this->parameterColumn = __value;
}
int JKQTPEvaluatedFunctionWithParamsGraphBase::getParameterColumn() const
{
return this->parameterColumn;
}
void JKQTPEvaluatedFunctionWithParamsGraphBase::setParameterColumn(size_t __value) {
this->parameterColumn = static_cast<int>(__value);
}
QVector<double> JKQTPEvaluatedFunctionWithParamsGraphBase::getInternalParams() const {
return iparams;
}
bool JKQTPEvaluatedFunctionWithParamsGraphBase::usesColumn(int c) const
{
return (c==parameterColumn);
}

View File

@ -34,67 +34,75 @@
/*! \brief Base class for graph classes that evaluate a mathematical function (e.g. defined as a C-fucntion), /** \brief Base class for graph classes that evaluate a mathematical function (e.g. defined as a C-fucntion),
using an adaptive plotting algorithm from JKQTPAdaptiveFunctionGraphEvaluator * using an adaptive plotting algorithm from JKQTPAdaptiveFunctionGraphEvaluator
\ingroup jkqtplotter_functiongraphs * \ingroup jkqtplotter_functiongraphs
*
This class uses the intelligent plotting algorithm for functions, implemented in JKQTPAdaptiveFunctionGraphEvaluator. * This class uses the intelligent plotting algorithm for functions, implemented in JKQTPAdaptiveFunctionGraphEvaluator.
It starts by sampling the function at minSamples positions. Then each function interval is bisected recursively if * It starts by sampling the function at minSamples positions. Then each function interval is bisected recursively if
necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$ * necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$
and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. the midpoint is added * and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. the midpoint is added
to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f] * to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f]
In addition all sampling points except minimum and maximum are beeing shifted by a random fraction their * 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. * distance to the other points. This helps to prevent beats when sampling periodic functions.
*
Finally the obtained data is cleaned up to reduce the amount of points, by deleting a point, when it leads to an * Finally the obtained data is cleaned up to reduce the amount of points, by deleting a point, when it leads to an
angle between consecutive line-segments of less than dataCleanupMaxAllowedAngleDegree. * angle between consecutive line-segments of less than dataCleanupMaxAllowedAngleDegree.
*
*
\see JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph * \see JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph
*/ */
class JKQTPLOTTER_LIB_EXPORT JKQTPEvaluatedFunctionGraphBase: public JKQTPGraph { class JKQTPLOTTER_LIB_EXPORT JKQTPEvaluatedFunctionGraphBase: public JKQTPGraph {
Q_OBJECT Q_OBJECT
public: public:
/** \brief class constructor */ /** \brief class constructor */
JKQTPEvaluatedFunctionGraphBase(JKQTBasePlotter* parent=nullptr); explicit JKQTPEvaluatedFunctionGraphBase(JKQTBasePlotter* parent=nullptr);
/** \brief class constructor */ /** \brief class constructor */
JKQTPEvaluatedFunctionGraphBase(JKQTPlotter* parent); explicit JKQTPEvaluatedFunctionGraphBase(JKQTPlotter* parent);
/** \brief class destructor */ /** \brief class destructor */
virtual ~JKQTPEvaluatedFunctionGraphBase() ; virtual ~JKQTPEvaluatedFunctionGraphBase() ;
/** \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;
/*! \copydoc minSamples */
/** \copydoc minSamples */
unsigned int getMinSamples() const; unsigned int getMinSamples() const;
/*! \copydoc maxRefinementDegree */ /** \copydoc maxRefinementDegree */
unsigned int getMaxRefinementDegree() const; unsigned int getMaxRefinementDegree() const;
/*! \copydoc slopeTolerance */ /** \copydoc slopeTolerance */
double getSlopeTolerance() const; double getSlopeTolerance() const;
/*! \copydoc minPixelPerSample */ /** \copydoc minPixelPerSample */
double getMinPixelPerSample() const; double getMinPixelPerSample() const;
/*! \copydoc dataCleanupMaxAllowedAngleDegree */ /** \copydoc dataCleanupMaxAllowedAngleDegree */
double getDataCleanupMaxAllowedAngleDegree() const; double getDataCleanupMaxAllowedAngleDegree() const;
/*! \copydoc displaySamplePoints */ /** \copydoc displaySamplePoints */
bool getDisplaySamplePoints() const; bool getDisplaySamplePoints() const;
public slots: public slots:
/*! \copydoc minSamples */ /** \copydoc minSamples */
void setMinSamples(const unsigned int & __value); void setMinSamples(const unsigned int & __value);
/*! \copydoc maxRefinementDegree */ /** \copydoc maxRefinementDegree */
void setMaxRefinementDegree(const unsigned int & __value); void setMaxRefinementDegree(const unsigned int & __value);
/*! \copydoc slopeTolerance */ /** \copydoc slopeTolerance */
void setSlopeTolerance(double __value); void setSlopeTolerance(double __value);
/*! \copydoc minPixelPerSample */ /** \copydoc minPixelPerSample */
void setMinPixelPerSample(double __value); void setMinPixelPerSample(double __value);
/*! \copydoc dataCleanupMaxAllowedAngleDegree */ /** \copydoc dataCleanupMaxAllowedAngleDegree */
void setDataCleanupMaxAllowedAngleDegree(double __value); void setDataCleanupMaxAllowedAngleDegree(double __value);
/*! \copydoc displaySamplePoints */ /** \copydoc displaySamplePoints */
void setDisplaySamplePoints(bool __value); void setDisplaySamplePoints(bool __value);
protected: protected:
/** \brief plot data calculated by createPlotData(), i.e. the datapoints \f$ \mbox{transform}\left(x, y=f(x, \vec{p})\right) \f$ to be plotted */ /** \brief plot data calculated by createPlotData(), i.e. the datapoints \f$ \mbox{transform}\left(x, y=f(x, \vec{p})\right) \f$ to be plotted */
QVector<QPointF> data; QVector<QPointF> data;
@ -125,4 +133,61 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPEvaluatedFunctionGraphBase: public JKQTPGraph
}; };
/** \brief extends JKQTPEvaluatedFunctionGraphBase with a set of functions that support function parameters
* \ingroup jkqtplotter_functiongraphs
*
* \see JKQTPEvaluatedFunctionGraphBase
*/
class JKQTPLOTTER_LIB_EXPORT JKQTPEvaluatedFunctionWithParamsGraphBase: public JKQTPEvaluatedFunctionGraphBase {
Q_OBJECT
public:
/** \brief class constructor */
explicit JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTBasePlotter* parent=nullptr);
/** \brief class constructor */
explicit JKQTPEvaluatedFunctionWithParamsGraphBase(JKQTPlotter* parent);
/** \brief class destructor */
virtual ~JKQTPEvaluatedFunctionWithParamsGraphBase();
/** \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!!!) */
virtual void setParams(const QVector<double>& params);
/** \brief sets the params from a copy of the given array of length \a N */
void setCopiedParams(const double* params, int N);
/** \brief returns the currently set internal parameter vector */
QVector<double> getInternalParams() const;
/** \copydoc parameterColumn */
int getParameterColumn() const;
/** \copydoc JKQTPGraph::usesColumn() */
virtual bool usesColumn(int c) const override;
public slots:
/** \brief set an internal parameter vector as function parameters, initialized with {p1} */
void setParamsV(double p1);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2} */
void setParamsV(double p1, double p2);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3} */
void setParamsV(double p1, double p2, double p3);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4} */
void setParamsV(double p1, double p2, double p3, double p4);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4,p5} */
void setParamsV(double p1, double p2, double p3, double p4, double p5);
/** \copydoc parameterColumn */
void setParameterColumn(int __value);
/** \copydoc parameterColumn */
void setParameterColumn (size_t __value);
protected:
/** \brief ensure that current function parameters for a plot function (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams */
virtual void collectParameters();
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the plot function */
int parameterColumn;
/** \brief internal storage for the current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) */
QVector<double> iparams;
};
#endif // jkqtpevaluatedfunctionbase_H #endif // jkqtpevaluatedfunctionbase_H

View File

@ -29,22 +29,18 @@
#include "jkqtplotter/jkqtpbaseelements.h" #include "jkqtplotter/jkqtpbaseelements.h"
#include "jkqtplotter/jkqtplotter.h" #include "jkqtplotter/jkqtplotter.h"
#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgz<smallestGreaterZero))) smallestGreaterZero=xvsgz;
JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTBasePlotter* parent): JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTBasePlotter* parent):
JKQTPEvaluatedFunctionGraphBase(parent) JKQTPEvaluatedFunctionWithParamsGraphBase(parent)
{ {
tmin=0.0; tmin=0.0;
tmax=1.0; tmax=1.0;
params=nullptr;
initLineStyle(parent, parentPlotStyle); initLineStyle(parent, parentPlotStyle);
parameterColumn=-1;
} }
JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTPlotter* parent): JKQTPXYFunctionLineGraph::JKQTPXYFunctionLineGraph(JKQTPlotter* parent):
@ -166,19 +162,6 @@ jkqtpSimpleParametricCurveFunctionType JKQTPXYFunctionLineGraph::getSimplePlotFu
return simplePlotFunction; return simplePlotFunction;
} }
void JKQTPXYFunctionLineGraph::setParams(void *__value)
{
if (this->params != __value) {
this->params = __value;
data.clear();
}
}
void *JKQTPXYFunctionLineGraph::getParams() const
{
return this->params;
}
void JKQTPXYFunctionLineGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { void JKQTPXYFunctionLineGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) {
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();}); painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
@ -196,53 +179,6 @@ QColor JKQTPXYFunctionLineGraph::getKeyLabelColor() const {
return getLineColor(); return getLineColor();
} }
bool JKQTPXYFunctionLineGraph::getXMinMax(double &minx, double &maxx, double &smallestGreaterZero)
{
if (data.size()==0) createPlotData();
if (data.size()>0){
bool start=true;
minx=0;
maxx=0;
smallestGreaterZero=0;
for (auto const& d: data) {
if (JKQTPIsOKFloat(d.x())) {
if (start || d.x()>maxx) maxx=d.x();
if (start || d.x()<minx) minx=d.x();
double xvsgz;
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
start=false;
}
}
return !start;
} else {
smallestGreaterZero=minx=maxx=0; return false;
}
}
bool JKQTPXYFunctionLineGraph::getYMinMax(double &miny, double &maxy, double &smallestGreaterZero)
{
if (data.size()==0) createPlotData();
if (data.size()>0){
bool start=true;
miny=0;
maxy=0;
smallestGreaterZero=0;
for (auto const& d: data) {
if (JKQTPIsOKFloat(d.y())) {
if (start || d.y()>maxy) maxy=d.y();
if (start || d.y()<miny) miny=d.y();
double xvsgz;
xvsgz=d.x(); SmallestGreaterZeroCompare_xvsgz();
start=false;
}
}
return !start;
} else {
smallestGreaterZero=miny=maxy=0; return false;
}
}
void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) { void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) {
#ifdef JKQTBP_AUTOTIMER #ifdef JKQTBP_AUTOTIMER
@ -255,7 +191,7 @@ void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) {
if (!plotFunction && !simplePlotFunction) return; if (!plotFunction && !simplePlotFunction) return;
jkqtpSimpleParametricCurveFunctionType func; jkqtpSimpleParametricCurveFunctionType func;
if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, params); if (plotFunction) func=std::bind(plotFunction, std::placeholders::_1, getInternalParams());
else if (simplePlotFunction) func=simplePlotFunction; else if (simplePlotFunction) func=simplePlotFunction;
jkqtpSimpleParametricCurveFunctionType fTransformedFunc= std::bind([&](const JKQTPPlotElement* plot, double t) -> QPointF { return plot->transform(func(t)); }, this, std::placeholders::_1); jkqtpSimpleParametricCurveFunctionType fTransformedFunc= std::bind([&](const JKQTPPlotElement* plot, double t) -> QPointF { return plot->transform(func(t)); }, this, std::placeholders::_1);
@ -265,33 +201,6 @@ void JKQTPXYFunctionLineGraph::createPlotData(bool collectParams) {
data=JKQTPSimplyfyLineSegemnts(data, dataCleanupMaxAllowedAngleDegree); data=JKQTPSimplyfyLineSegemnts(data, dataCleanupMaxAllowedAngleDegree);
} }
void JKQTPXYFunctionLineGraph::collectParameters()
{
if (parent && parameterColumn>=0) {
iparams.clear();
JKQTPDatastore* datastore=parent->getDatastore();
int imin=0;
int imax=static_cast<int>(datastore->getRows(parameterColumn));
for (int i=imin; i<imax; i++) {
double xv=datastore->get(parameterColumn,i);
iparams<<xv;
}
//qDebug()<<"iparams_beforeclean:";
//for (int i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
int i=iparams.size()-1;
while (i>=0 && !JKQTPIsOKFloat(iparams[i])) {
iparams.remove(i,1);
i--;
}
//qDebug()<<"iparams:";
//for (i=0; i<iparams.size(); i++) qDebug()<<iparams[i];
params=&iparams;
}
}
void JKQTPXYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) { void JKQTPXYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
#ifdef JKQTBP_AUTOTIMER #ifdef JKQTBP_AUTOTIMER
@ -328,77 +237,6 @@ void JKQTPXYFunctionLineGraph::draw(JKQTPEnhancedPainter& painter) {
void JKQTPXYFunctionLineGraph::setParams(const QVector<double> &params)
{
iparams=params;
setParams(&iparams);
}
void JKQTPXYFunctionLineGraph::setCopiedParams(const double *params, int N)
{
QVector<double> v;
for (int i=0; i<N; i++) { v<<params[i]; }
setParams(v);
}
void JKQTPXYFunctionLineGraph::setParamsV(double p1) {
QVector<double> p;
p<<p1;
setParams(p);
}
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2) {
QVector<double> p;
p<<p1<<p2;
setParams(p);
}
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2, double p3) {
QVector<double> p;
p<<p1<<p2<<p3;
setParams(p);
}
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4) {
QVector<double> p;
p<<p1<<p2<<p3<<p4;
setParams(p);
}
void JKQTPXYFunctionLineGraph::setParamsV(double p1, double p2, double p3, double p4, double p5) {
QVector<double> p;
p<<p1<<p2<<p3<<p4<<p5;
setParams(p);
}
void JKQTPXYFunctionLineGraph::setParameterColumn(int __value)
{
this->parameterColumn = __value;
}
int JKQTPXYFunctionLineGraph::getParameterColumn() const
{
return this->parameterColumn;
}
void JKQTPXYFunctionLineGraph::setParameterColumn(size_t __value) {
this->parameterColumn = static_cast<int>(__value);
}
QVector<double> JKQTPXYFunctionLineGraph::getInternalParams() const {
return iparams;
}
bool JKQTPXYFunctionLineGraph::usesColumn(int c) const
{
return (c==parameterColumn);
}
double JKQTPXYFunctionLineGraph::getTMin() const double JKQTPXYFunctionLineGraph::getTMin() const
{ {
return tmin; return tmin;

View File

@ -43,7 +43,7 @@
influence its result. Parameters are given as a pointer to some memory location. The function has to 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. know on its own how to interpret these.
*/ */
typedef std::function<QPointF(double, void*)> jkqtpParametricCurveFunctionType; typedef std::function<QPointF(double, const QVector<double>)> jkqtpParametricCurveFunctionType;
/*! \brief simplified type of functions (without parameters) that may be plotted by JKQTPXYFunctionLineGraph /*! \brief simplified type of functions (without parameters) that may be plotted by JKQTPXYFunctionLineGraph
\ingroup jkqtplotter_functiongraphs \ingroup jkqtplotter_functiongraphs
@ -88,7 +88,7 @@ typedef std::function<QPointF(double)> jkqtpSimpleParametricCurveFunctionType;
\see \ref JKQTPlotterEvalCurves , JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph \see \ref JKQTPlotterEvalCurves , JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph
*/ */
class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunctionGraphBase, public JKQTPGraphLineStyleMixin { class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunctionWithParamsGraphBase, public JKQTPGraphLineStyleMixin {
Q_OBJECT Q_OBJECT
public: public:
@ -124,16 +124,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunc
/** \brief returns the color to be used for the key label */ /** \brief returns the color to be used for the key label */
virtual QColor getKeyLabelColor() const override; virtual QColor getKeyLabelColor() const 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 sets a functor to be plotted /** \brief sets a functor to be plotted
* *
* \see plotFunction * \see plotFunction
@ -159,41 +149,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunc
/*! \copydoc simplePlotFunction */ \ /*! \copydoc simplePlotFunction */ \
virtual jkqtpSimpleParametricCurveFunctionType getSimplePlotFunction () const; virtual jkqtpSimpleParametricCurveFunctionType getSimplePlotFunction () const;
/*! \copydoc params */
virtual void setParams(void* __value);
/*! \copydoc params */
void* getParams() const;
/** \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!!!) */
virtual void setParams(const QVector<double>& params);
/** \brief sets the params from a copy of the given array of length \a N */
void setCopiedParams(const double* params, int N);
/** \brief set an internal parameter vector as function parameters, initialized with {p1} */
void setParamsV(double p1);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2} */
void setParamsV(double p1, double p2);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3} */
void setParamsV(double p1, double p2, double p3);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4} */
void setParamsV(double p1, double p2, double p3, double p4);
/** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4,p5} */
void setParamsV(double p1, double p2, double p3, double p4, double p5);
/** \brief returns the currently set internal parameter vector */
QVector<double> getInternalParams() const;
/*! \copydoc parameterColumn */
void setParameterColumn(int __value);
/*! \copydoc parameterColumn */
int getParameterColumn() const;
/*! \copydoc parameterColumn */
void setParameterColumn (size_t __value);
/** \copydoc JKQTPGraph::usesColumn() */
virtual bool usesColumn(int c) const override;
/*! \copydoc tmin */ /*! \copydoc tmin */
double getTMin() const; double getTMin() const;
@ -216,21 +171,13 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXYFunctionLineGraph: public JKQTPEvaluatedFunc
double tmax; double tmax;
/** \brief fill the data array with data from the function plotFunction */ /** \brief fill the data array with data from the function plotFunction */
virtual void createPlotData( bool collectParams=true) override; virtual void createPlotData( bool collectParams=true) override;
/** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams */
virtual void collectParameters() ;
/** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the plot function */
int parameterColumn;
/** \brief the function to be plotted */ /** \brief the function to be plotted */
jkqtpParametricCurveFunctionType plotFunction; jkqtpParametricCurveFunctionType plotFunction;
/** \brief a simple function to be plotted, simplified form without parameters */ /** \brief a simple function to be plotted, simplified form without parameters */
jkqtpSimpleParametricCurveFunctionType simplePlotFunction; jkqtpSimpleParametricCurveFunctionType simplePlotFunction;
/** \brief pointer to the parameters supplied to the plotting funtion */
void* params;
/** \brief internal storage for the current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) */
QVector<double> iparams;
}; };
#endif // jkqtpevaluatedparametriccurve_H #endif // jkqtpevaluatedparametriccurve_H

View File

@ -91,12 +91,9 @@ void JKQTPXParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
} }
fdata.varcount=0; fdata.varcount=0;
try { try {
QVector<double>* parameters=static_cast<QVector<double>*>(params); for (const auto& p: getInternalParams()) {
if (parameters) { fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), p);
for (int i=0; i<parameters->size(); i++) { fdata.varcount=fdata.varcount+1;
fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), parameters->at(i));
fdata.varcount=fdata.varcount+1;
}
} }
fdata.parser->addVariableDouble(std::string("x"), 0.0); fdata.parser->addVariableDouble(std::string("x"), 0.0);
if (fdata.node) delete fdata.node; if (fdata.node) delete fdata.node;
@ -150,7 +147,7 @@ void JKQTPXParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
} }
double JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunction(double x, void* /*data*/, JKQTPXParsedFunctionLineGraphFunctionData *fdata) { double JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunction(double x, const QVector<double>& /*data*/, JKQTPXParsedFunctionLineGraphFunctionData *fdata) {
JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunctionData* d=fdata;//static_cast<JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunctionData*>(data); JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunctionData* d=fdata;//static_cast<JKQTPXParsedFunctionLineGraph::JKQTPXParsedFunctionLineGraphFunctionData*>(data);
if (d && d->parser && d->node) { if (d && d->parser && d->node) {
try { try {
@ -267,12 +264,9 @@ void JKQTPYParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
} }
fdata.varcount=0; fdata.varcount=0;
try { try {
QVector<double>* parameters=static_cast<QVector<double>*>(params); for (const auto& p: getInternalParams()) {
if (parameters) { fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), p);
for (int i=0; i<parameters->size(); i++) { fdata.varcount=fdata.varcount+1;
fdata.parser->addVariableDouble(std::string("p")+jkqtp_inttostr(fdata.varcount+1), parameters->at(i));
fdata.varcount=fdata.varcount+1;
}
} }
fdata.parser->addVariableDouble(std::string("x"), 0.0); fdata.parser->addVariableDouble(std::string("x"), 0.0);
fdata.parser->addVariableDouble(std::string("y"), 0.0); fdata.parser->addVariableDouble(std::string("y"), 0.0);
@ -327,7 +321,7 @@ void JKQTPYParsedFunctionLineGraph::createPlotData(bool /*collectParams*/)
qDebug()<<"refined to "<<count<<" daatapoints";*/ qDebug()<<"refined to "<<count<<" daatapoints";*/
} }
double JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunction(double x, void* /*data*/, JKQTPYParsedFunctionLineGraphFunctionData *fdata) { double JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunction(double x, const QVector<double> & /*data*/, JKQTPYParsedFunctionLineGraphFunctionData *fdata) {
JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunctionData* d=fdata;//static_cast<JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunctionData*>(data); JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunctionData* d=fdata;//static_cast<JKQTPYParsedFunctionLineGraph::JKQTPYParsedFunctionLineGraphFunctionData*>(data);
if (d && d->parser && d->node) { if (d && d->parser && d->node) {
try { try {

View File

@ -97,7 +97,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPXParsedFunctionLineGraph: public JKQTPXFunctio
virtual void createPlotData(bool collectParams=true) override; virtual void createPlotData(bool collectParams=true) override;
/** \brief implements the actual plot function */ /** \brief implements the actual plot function */
static double JKQTPXParsedFunctionLineGraphFunction(double x, void *data, JKQTPXParsedFunctionLineGraphFunctionData* fdata) ; static double JKQTPXParsedFunctionLineGraphFunction(double x, const QVector<double> &data, JKQTPXParsedFunctionLineGraphFunctionData* fdata) ;
}; };
@ -165,6 +165,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPYParsedFunctionLineGraph: public JKQTPYFunctio
/** \brief fill the data array with data from the function plotFunction */ /** \brief fill the data array with data from the function plotFunction */
virtual void createPlotData(bool collectParams=true) override; virtual void createPlotData(bool collectParams=true) override;
/** \brief implements the actual plot function */ /** \brief implements the actual plot function */
static double JKQTPYParsedFunctionLineGraphFunction(double x, void *data, JKQTPYParsedFunctionLineGraphFunctionData* fdata); static double JKQTPYParsedFunctionLineGraphFunction(double x, const QVector<double>& data, JKQTPYParsedFunctionLineGraphFunctionData* fdata);
}; };
#endif // jkqtpgraphsparsedfunction_H #endif // jkqtpgraphsparsedfunction_H