From 694be2d111575a1ce8ddabf03e601cf6d3cdfc30 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Thu, 12 Mar 2020 19:26:51 +0000 Subject: [PATCH] Generic Plot DateTime Axis support .. when plotting on trends view the x-axis is a date based range. .. still need to update for time based axis when looking at activities. --- src/Charts/GenericLegend.cpp | 11 +++++++---- src/Charts/GenericLegend.h | 4 +++- src/Charts/GenericPlot.cpp | 20 +++++++++++++++++--- src/Charts/GenericSelectTool.cpp | 30 +++++++++++++++++++++++------- src/Core/DataFilter.cpp | 2 +- 5 files changed, 51 insertions(+), 16 deletions(-) diff --git a/src/Charts/GenericLegend.cpp b/src/Charts/GenericLegend.cpp index 3271c71dd..2e5ca05d7 100644 --- a/src/Charts/GenericLegend.cpp +++ b/src/Charts/GenericLegend.cpp @@ -27,7 +27,7 @@ #include GenericLegendItem::GenericLegendItem(Context *context, QWidget *parent, QString name, QColor color) : - QWidget(parent), context(context), name(name), color(color) + QWidget(parent), context(context), name(name), color(color), datetime(false) { value=0; @@ -138,8 +138,10 @@ GenericLegendItem::paintEvent(QPaintEvent *) // just paint the value for now QString string; - if (hasvalue) string=QString("%1").arg(value, 0, 'f', 2); - else string=" "; + if (hasvalue) { + if (datetime) string=QDateTime::fromMSecsSinceEpoch(value).toString("dd MMM yy"); + else string=QString("%1").arg(value, 0, 'f', 2); + } else string=" "; // remove redundat dps (e.g. trailing zeroes) string = Utils::removeDP(string); @@ -213,13 +215,14 @@ GenericLegend::setOrientation(Qt::Orientation o) } void -GenericLegend::addX(QString name) +GenericLegend::addX(QString name, bool datetime) { // if it already exists remove it if (items.value(name,NULL) != NULL) removeSeries(name); GenericLegendItem *add = new GenericLegendItem(context, this, name, GColor(CPLOTMARKER)); add->setClickable(false); + add->setDateTime(datetime); layout->insertWidget(0, add); items.insert(name,add); diff --git a/src/Charts/GenericLegend.h b/src/Charts/GenericLegend.h index 63e6d28f3..c3fb12cea 100644 --- a/src/Charts/GenericLegend.h +++ b/src/Charts/GenericLegend.h @@ -62,6 +62,7 @@ class GenericLegendItem : public QWidget { void setValue(double p) { if (enabled) { hasvalue=true; value=p; update(); } } // set value to display void noValue() { if (enabled) { hasvalue=false; update(); } } // no value to display void setClickable(bool x) { clickable=x; } + void setDateTime(bool x) { datetime=x; } void configChanged(qint32); // context changed private: @@ -72,6 +73,7 @@ class GenericLegendItem : public QWidget { bool hasvalue; bool enabled; bool clickable; + bool datetime; double value; // geometry for painting fast / updated on config changes @@ -87,7 +89,7 @@ class GenericLegend : public QWidget { GenericLegend(Context *context, GenericPlot *parent); void addSeries(QString name, QColor color); - void addX(QString name); + void addX(QString name, bool datetime); void removeSeries(QString name); void removeAllSeries(); diff --git a/src/Charts/GenericPlot.cpp b/src/Charts/GenericPlot.cpp index 6e0dce1c6..920c77c23 100644 --- a/src/Charts/GenericPlot.cpp +++ b/src/Charts/GenericPlot.cpp @@ -650,7 +650,20 @@ GenericPlot::finaliseChart() //fflush(stderr); QAbstractAxis *add=NULL; switch (axisinfo->type) { - case GenericAxisInfo::DATERANGE: // TODO + case GenericAxisInfo::DATERANGE: + { + + QDateTimeAxis *vaxis = new QDateTimeAxis(qchart); + add=vaxis; // gets added later + + vaxis->setMin(QDateTime::fromMSecsSinceEpoch(axisinfo->min())); + vaxis->setMax(QDateTime::fromMSecsSinceEpoch(axisinfo->max())); + vaxis->setFormat("dd MMM yy"); + + // attach to the chart + qchart->addAxis(add, axisinfo->locate()); + } + break; case GenericAxisInfo::TIME: // TODO case GenericAxisInfo::CONTINUOUS: { @@ -748,8 +761,9 @@ GenericPlot::finaliseChart() // look for first series with a horizontal axis (we will use this later) foreach(QAbstractAxis *axis, series->attachedAxes()) { if (axis->orientation() == Qt::Horizontal) { - if (axis->type()==QAbstractAxis::AxisTypeValue) legend->addX(static_cast(axis)->titleText()); - else if (axis->type()==QAbstractAxis::AxisTypeLogValue) legend->addX(static_cast(axis)->titleText()); + if (axis->type()==QAbstractAxis::AxisTypeValue) legend->addX(static_cast(axis)->titleText(), false); + else if (axis->type()==QAbstractAxis::AxisTypeLogValue) legend->addX(static_cast(axis)->titleText(), false); + else if (axis->type()==QAbstractAxis::AxisTypeDateTime) legend->addX(static_cast(axis)->titleText(), true); havexaxis=true; break; } diff --git a/src/Charts/GenericSelectTool.cpp b/src/Charts/GenericSelectTool.cpp index 710cd6706..0672f1f7c 100644 --- a/src/Charts/GenericSelectTool.cpp +++ b/src/Charts/GenericSelectTool.cpp @@ -138,10 +138,12 @@ void GenericSelectTool::paint(QPainter*painter, const QStyleOptionGraphicsItem * // get the scene rect for the y axis // we are a little careful since axisRect QAbstractAxis *yaxis = NULL; + QAbstractAxis *xaxis = NULL; foreach (QAbstractAxis *axis, series->attachedAxes()) { if (axis->orientation() == Qt::Vertical) { yaxis=axis; - break; + } else { + xaxis=axis; } } if (yaxis) { @@ -184,7 +186,11 @@ void GenericSelectTool::paint(QPainter*painter, const QStyleOptionGraphicsItem * // x value painter->setPen(QPen(GColor(CPLOTMARKER))); - label=QString("%1").arg(v.x(),0,'f',0); // no decimal places XXX fixup on series info + // datetime? + if (xaxis && xaxis->type() == QAbstractAxis::AxisTypeDateTime) + label=QDateTime::fromMSecsSinceEpoch(v.x()).toString("dd MMM yy"); + else + label=QString("%1").arg(v.x(),0,'f',0); // no decimal places XXX fixup on series info label = Utils::removeDP(label); // remove unneccessary decimal places painter->setClipRect(mapRectFromScene(host->qchart->plotArea())); painter->drawText(posxp-(QPointF(fm.tightBoundingRect(label).width()/2.0,4)), label); @@ -215,7 +221,8 @@ void GenericSelectTool::paint(QPainter*painter, const QStyleOptionGraphicsItem * if (calc.xaxis != NULL) { - if (calc.xaxis->type() == QAbstractAxis::AxisTypeValue) { + if (calc.xaxis->type() == QAbstractAxis::AxisTypeValue || + calc.xaxis->type() == QAbstractAxis::AxisTypeDateTime) { // slope calcs way over the top for a line chart // where there are multiple series being plotted @@ -273,14 +280,23 @@ void GenericSelectTool::paint(QPainter*painter, const QStyleOptionGraphicsItem * QPen markerpen(GColor(CPLOTMARKER)); painter->setPen(markerpen); - QString label=QString("%1").arg(calc.x.max); + QString label; + if (calc.xaxis->type() == QAbstractAxis::AxisTypeDateTime) label=QDateTime::fromMSecsSinceEpoch(calc.x.max).toString("dd MMM yy"); + else label=QString("%1").arg(calc.x.max); painter->drawText(maxxp-QPointF(0,4), label); - label=QString("%1").arg(calc.x.min); + if (calc.xaxis->type() == QAbstractAxis::AxisTypeDateTime) label=QDateTime::fromMSecsSinceEpoch(calc.x.min).toString("dd MMM yy"); + else label=QString("%1").arg(calc.x.min); painter->drawText(minxp-QPointF(0,4), label); // scatter sees mean, line/timeseries more likely to want dx - if (host->charttype == GC_CHART_SCATTER) label=QString("%1").arg(calc.x.mean); - else label=QString("%1").arg(calc.x.max - calc.x.min); + if (calc.xaxis->type() == QAbstractAxis::AxisTypeDateTime) { + int days = QDate(1970,01,01).daysTo(QDateTime::fromMSecsSinceEpoch(calc.x.max).date()) - + QDate(1970,01,01).daysTo(QDateTime::fromMSecsSinceEpoch(calc.x.min).date()); + label=QString("%1 days").arg(days); + } else { + if (host->charttype == GC_CHART_SCATTER) label=QString("%1").arg(calc.x.mean); + else label=QString("%1").arg(calc.x.max - calc.x.min); + } painter->drawText(avgxp-QPointF(0,4), label); // diff --git a/src/Core/DataFilter.cpp b/src/Core/DataFilter.cpp index 14571428d..509e95330 100644 --- a/src/Core/DataFilter.cpp +++ b/src/Core/DataFilter.cpp @@ -2446,7 +2446,7 @@ Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, float x, RideItem *m, RideF count++; double value=0; - if(wantdate) value= QDate(1970,01,01).daysTo(ride->dateTime.date()); + if(wantdate) value= ride->dateTime.toMSecsSinceEpoch(); else value = ride->getForSymbol(df->lookupMap.value(symbol,""), c); returning.number += value;