Skip to content

Commit

Permalink
DataFilter::eval() more const pass by reference
Browse files Browse the repository at this point in the history
.. for the specification and daterange.
  • Loading branch information
liversedge committed Oct 12, 2021
1 parent c8c4666 commit 9976746
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 25 deletions.
27 changes: 27 additions & 0 deletions src/Charts/GenericChart.h
Expand Up @@ -32,6 +32,31 @@

#include <QScrollArea>

// a chart annotation
class GenericAnnotationInfo {

enum annotationType { None, Label, VLine, HLine, Voronoi };
typedef annotationType AnnotationType;

public:

GenericAnnotationInfo(AnnotationType);

AnnotationType type;

// labels
QList<QLabel *> labels;

// voronoi
QString vname;
QVector<double> vx, vy; //voronoi digram

// vline and hline
Qt::PenStyle linestyle;
double value;
QString text;
};

// keeping track of the series info
class GenericSeriesInfo {

Expand Down Expand Up @@ -79,6 +104,8 @@ class GenericSeriesInfo {
bool fill;
RideMetric::MetricType aggregateby;

QList<GenericAnnotationInfo> annotations;

QList <QStringList> annotateLabels; // label annotation
QVector<double> voronoix, voronoiy; // voronoi diagram annotation
};
Expand Down
1 change: 1 addition & 0 deletions src/Charts/GenericPlot.h
Expand Up @@ -59,6 +59,7 @@ class GenericPlot;
class GenericLegend;
class GenericSelectTool;
class GenericAxisInfo;
class GenericAnnotationInfo;

// the chart
class ChartSpace;
Expand Down
2 changes: 1 addition & 1 deletion src/Charts/UserChart.h
Expand Up @@ -93,7 +93,7 @@ class UserChart : public QWidget {

// the actual config
GenericChartInfo chartinfo;
QList<GenericSeriesInfo> seriesinfo;
QList<GenericSeriesInfo> seriesinfo; // also contain annotations.
QList<GenericAxisInfo> axisinfo;

// annotations generated by the program (not the user)
Expand Down
70 changes: 60 additions & 10 deletions src/Core/DataFilter.cpp
Expand Up @@ -213,10 +213,11 @@ static struct {
// grammar does not support (a*x>1), instead we can use a*bool(x>1). All non
// zero expressions will evaluate to 1.

{ "annotate", 0 }, // annotate(type, parms) - add an annotation to the chart
// current supported annotations:
{ "annotate", 0 }, // current supported annotations:
// annotate(label, string1, string2 .. stringn) - adds label at top of a chart
// annotate(voronoi, centers) - associated with a series on a user chart
// annotate(hline, label, style, value) - associated with a series on a user chart
// annotate(vline, label, style, value) - associated with a series on a user chart (see linestyle for vals below)

{ "arguniq", 1 }, // returns an index of the uniq values in a vector, in the same way
// argsort returns an index, can then be used to select from samples
Expand Down Expand Up @@ -400,6 +401,30 @@ static QStringList pdmodels(Context *context)
return returning;
}

// whenever we use a line style
static struct {
const char *name;
Qt::PenStyle type;
} linestyles_[] = {
{ "solid", Qt::SolidLine },
{ "dash", Qt::DashLine },
{ "dot", Qt::DotLine },
{ "dashdot", Qt::DashDotLine },
{ "dashdotdot", Qt::DashDotDotLine },
{ "", Qt::NoPen },
};

static Qt::PenStyle linestyle(QString name)
{
int index=0;
while (linestyles_[index].type != Qt::NoPen) {
if (name == linestyles_[index].name)
return linestyles_[index].type;
index++;
}
return Qt::NoPen; // not known
}

QStringList
DataFilter::builtins(Context *context)
{
Expand Down Expand Up @@ -525,7 +550,7 @@ DataFilter::builtins(Context *context)

} else if (i == 66) {

returning << "annotate(label, ...)";
returning << "annotate(label|hline|vline|voronoi, ...)";

} else if (i == 67) {

Expand Down Expand Up @@ -1709,7 +1734,7 @@ void Leaf::validateFilter(Context *context, DataFilterRuntime *df, Leaf *leaf)
QRegExp dateRangeValidSymbols("^(start|stop)$", Qt::CaseInsensitive); // date range
QRegExp pmcValidSymbols("^(stress|lts|sts|sb|rr|date)$", Qt::CaseInsensitive);
QRegExp smoothAlgos("^(sma|ewma)$", Qt::CaseInsensitive);
QRegExp annotateTypes("^(label|voronoi)$", Qt::CaseInsensitive);
QRegExp annotateTypes("^(label|hline|vline|voronoi)$", Qt::CaseInsensitive);
QRegExp curveData("^(x|y|z|d|t)$", Qt::CaseInsensitive);
QRegExp aggregateFunc("^(mean|sum|max|min|count)$", Qt::CaseInsensitive);
QRegExp interpolateAlgorithms("^(linear|cubic|akima|steffen)$", Qt::CaseInsensitive);
Expand Down Expand Up @@ -2497,20 +2522,41 @@ void Leaf::validateFilter(Context *context, DataFilterRuntime *df, Leaf *leaf)
if (leaf->fparms.count() < 2 || leaf->fparms[0]->type != Leaf::Symbol) {

leaf->inerror = true;
DataFiltererrors << QString(tr("annotate(label|voronoi, ...) need at least 2 parameters."));
DataFiltererrors << QString(tr("annotate(label|hline|vline|voronoi, ...) need at least 2 parameters."));

} else {

QString type = *(leaf->fparms[0]->lvalue.n);

// is the type of annotation supported?
if (!annotateTypes.exactMatch(type)) {
leaf->inerror = true;
DataFiltererrors << QString(tr("annotation type '%1' not available").arg(type));
} else {
if (type == "voronoi" && leaf->fparms.count() != 2) {

// its valid type, but what about the parameters?
if (type == "voronoi" && leaf->fparms.count() != 2) { // VORONOI

leaf->inerror = true;
DataFiltererrors << QString(tr("annotate(voronoi, centers)"));

} else if (type == "hline" || type == "vline") { // HLINE and VLINE

// just make sure the type of line is supported, the other parameters
// can be coerced from whatever the user passed anyway
if (leaf->fparms.count() != 4 || leaf->fparms[2]->type != Leaf::Symbol
|| linestyle(*(leaf->fparms[2]->lvalue.n)) == Qt::NoPen) {
leaf->inerror = true;
DataFiltererrors << QString(tr("annotate(voronoi, centers)"));
} else {
for(int i=1; i<leaf->fparms.count(); i++) validateFilter(context, df, leaf->fparms[i]);
DataFiltererrors << QString(tr("annotate(hline|vline, 'label', solid|dash|dot|dashdot|dashdotdot, value)"));
} else {
// make sure the parms are well formed
validateFilter(context, df, leaf->fparms[1]);
validateFilter(context, df, leaf->fparms[3]);
}

} else { // Any other types, e.g LABEL

for(int i=1; i<leaf->fparms.count(); i++) validateFilter(context, df, leaf->fparms[i]);
}
}
}
Expand Down Expand Up @@ -3312,7 +3358,7 @@ static int monthsTo(QDate from, QDate to)
return months;
}

Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, const Result &x, long it, RideItem *m, RideFilePoint *p, const QHash<QString,RideMetric*> *c, Specification s, DateRange d)
Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, const Result &x, long it, RideItem *m, RideFilePoint *p, const QHash<QString,RideMetric*> *c, const Specification &s, const DateRange &d)
{
// if error state all bets are off
//if (inerror) return Result(0);
Expand Down Expand Up @@ -6072,6 +6118,10 @@ Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, const Result &x, long it, R
df->owner->annotateVoronoi(x,y);
}
}

if (type == "hline" || type == "vline") {
}

}

// smooth
Expand Down
2 changes: 1 addition & 1 deletion src/Core/DataFilter.h
Expand Up @@ -126,7 +126,7 @@ class Leaf {
// User Metric - using symbols from QHash<..> (RideItem + Interval) and
// Spec to delimit samples in R/Python Scripts
//
Result eval(DataFilterRuntime *df, Leaf *, const Result &x, long it, RideItem *m, RideFilePoint *p = NULL, const QHash<QString,RideMetric*> *metrics=NULL, Specification spec=Specification(), DateRange d=DateRange());
Result eval(DataFilterRuntime *df, Leaf *, const Result &x, long it, RideItem *m, RideFilePoint *p = NULL, const QHash<QString,RideMetric*> *metrics=NULL, const Specification &spec=Specification(), const DateRange &d=DateRange());

// tree traversal etc
void print(int level, DataFilterRuntime*); // print leaf and all children
Expand Down
8 changes: 4 additions & 4 deletions src/Core/Specification.cpp
Expand Up @@ -27,20 +27,20 @@ Specification::Specification() : it(NULL), recintsecs(0), ri(NULL) {}

// does the date pass the specification ?
bool
Specification::pass(QDate date)
Specification::pass(QDate date) const
{
return (dr.pass(date));
}

// does the rideitem pass the specification ?
bool
Specification::pass(RideItem*item)
Specification::pass(RideItem*item) const
{
return (dr.pass(item->dateTime.date()) && fs.pass(item->fileName));
}

bool
Specification::pass(RideFilePoint *p)
Specification::pass(RideFilePoint *p) const
{
if (it == NULL) return true;
else if ((p->secs+recintsecs) >= it->start && p->secs <= it->stop) return true;
Expand Down Expand Up @@ -88,7 +88,7 @@ Specification::secsEnd() const
}

bool
Specification::isEmpty(RideFile *ride)
Specification::isEmpty(RideFile *ride) const
{
// its null !
if (!ride) return true;
Expand Down
10 changes: 5 additions & 5 deletions src/Core/Specification.h
Expand Up @@ -64,7 +64,7 @@ class FilterSet
}

// does the name in question pass the filter set ?
bool pass(QString name) {
bool pass(QString name) const {
foreach(QSet<QString> set, filters_)
if (!set.contains(name))
return false;
Expand All @@ -84,16 +84,16 @@ class Specification
Specification();

// does the date pass the specification ?
bool pass(QDate);
bool pass(QDate) const;

// does the rideitem pass the specification ?
bool pass(RideItem*);
bool pass(RideItem*) const;

// does the ridepoint pass the specification ?
bool pass(RideFilePoint *p);
bool pass(RideFilePoint *p) const;

// would it yield no data points for this ride ?
bool isEmpty(RideFile *);
bool isEmpty(RideFile *) const;

// non-null if exists
IntervalItem *interval() { return it; }
Expand Down
8 changes: 4 additions & 4 deletions src/Core/TimeUtils.h
Expand Up @@ -47,11 +47,11 @@ class DateRange : QObject
DateRange(const DateRange& other);
DateRange(QDate from = QDate(), QDate to = QDate(), QString name ="", QColor=QColor(127,127,127));
DateRange& operator=(const DateRange &);
bool operator!=(const DateRange&other) {
bool operator!=(const DateRange&other) const {
if (other.from != from || other.to != to || other.name != name) return true;
return false;
}
bool operator==(const DateRange&other) {
bool operator==(const DateRange&other) const {
if (other.from == from && other.to == to && other.name == name) return true;
return false;
}
Expand All @@ -62,14 +62,14 @@ class DateRange : QObject
QUuid id;

// does this date fall in the range selection ?
bool pass(QDate date) {
bool pass(QDate date) const {
if (from == QDate() && to == QDate()) return true;
if (from == QDate() && date <= to) return true;
if (to == QDate() && date >= from) return true;
if (date >= from && date <= to) return true;
return false;
}
bool isValid() { return valid; }
bool isValid() const { return valid; }


signals:
Expand Down

0 comments on commit 9976746

Please sign in to comment.