diff --git a/src/CompareInterval.cpp b/src/CompareInterval.cpp index e9fc25e25..4a44dce3a 100644 --- a/src/CompareInterval.cpp +++ b/src/CompareInterval.cpp @@ -20,9 +20,25 @@ #include "Context.h" #include "RideFile.h" +#include "RideFileCache.h" #include CompareInterval::CompareInterval(Context *context, QString name, RideFile *data, QColor color, Context *sourceContext, bool checked) : - context(context), name(name), data(data), color(color), sourceContext(sourceContext), checked(checked) + context(context), name(name), data(data), color(color), sourceContext(sourceContext), checked(checked), cache(NULL) { } + +CompareInterval::CompareInterval() : context(NULL), data(NULL), sourceContext(NULL), checked(false), cache(NULL) +{ +} + +RideFileCache *CompareInterval::rideFileCache() +{ + if (cache) return cache; + else return (cache = RideFileCache::createCacheFor(data)); +} + +CompareInterval::~CompareInterval() +{ + //if (cache) delete cache; +} diff --git a/src/CompareInterval.h b/src/CompareInterval.h index 24095db06..df2b11137 100644 --- a/src/CompareInterval.h +++ b/src/CompareInterval.h @@ -21,6 +21,7 @@ class Context; class RideFile; +class RideFileCache; #include #include @@ -29,17 +30,22 @@ class CompareInterval { public: CompareInterval(Context *context, QString name, RideFile *data, QColor color, Context *sourceContext, bool checked); - CompareInterval() : context(NULL), data(NULL), sourceContext(NULL), checked(false) {} + CompareInterval(); + ~CompareInterval(); Context *context; QString name; RideFile *data; QColor color; Context *sourceContext; + RideFileCache *rideFileCache(); bool checked; bool isChecked() const { return checked; } void setChecked(bool x) { checked=x; } + + private: + RideFileCache *cache; }; #endif diff --git a/src/ComparePane.cpp b/src/ComparePane.cpp index f8af8a6f9..d1feddf30 100644 --- a/src/ComparePane.cpp +++ b/src/ComparePane.cpp @@ -19,6 +19,7 @@ #include "ComparePane.h" #include "Settings.h" #include "RideFile.h" +#include "RideFileCache.h" #include "RideMetric.h" #include "SummaryMetrics.h" #include "MetricAggregator.h" @@ -682,6 +683,9 @@ ComparePane::dropEvent(QDropEvent *event) } add.data->recalculateDerivedSeries(); + // force the cache to be computed when added -- may optimise this out later + add.rideFileCache()->meanMaxArray(RideFile::watts).size(); // force the cache to be computed straight away. + // just use standard colors and cycle round // we will of course repeat, but the user can // just edit them using the button diff --git a/src/CpintPlot.cpp b/src/CpintPlot.cpp index 9eb025129..b23d403bd 100644 --- a/src/CpintPlot.cpp +++ b/src/CpintPlot.cpp @@ -1403,16 +1403,12 @@ CpintPlot::calculateForIntervals(QList compareIntervals) CompareInterval interval = compareIntervals.at(i); if (interval.isChecked()) { - // compute the mean max - QVectorvector; - MeanMaxComputer thread1(interval.data, vector, series); thread1.run(); - thread1.wait(); - // no data! - if (vector.count() == 0) return; + // no data ? + if (interval.rideFileCache()->meanMaxArray(series).count() == 0) return; // create curve data arrays - plot_interval(this, vector, interval.color); + plot_interval(this, interval.rideFileCache()->meanMaxArray(series), interval.color); } } @@ -1420,7 +1416,7 @@ CpintPlot::calculateForIntervals(QList compareIntervals) } void -CpintPlot::plot_interval(CpintPlot *thisPlot, QVector vector, QColor intervalColor) +CpintPlot::plot_interval(CpintPlot *thisPlot, QVector vector, QColor intervalColor) { QVectorx; QVectory; diff --git a/src/CpintPlot.h b/src/CpintPlot.h index 80b42b066..405c421e9 100644 --- a/src/CpintPlot.h +++ b/src/CpintPlot.h @@ -123,7 +123,7 @@ class CpintPlot : public QwtPlot void calculate(RideItem *rideItem); void plot_CP_curve(CpintPlot *plot, double cp, double tau, double t0n); void plot_allCurve(CpintPlot *plot, int n_values, const double *power_values, QColor plotColor, bool forcePlotColor); - void plot_interval(CpintPlot *plot, QVector vector, QColor plotColor); + void plot_interval(CpintPlot *plot, QVector vector, QColor plotColor); void configChanged(); void pointHover(QwtPlotCurve *curve, int index); void setShadeMode(int x); diff --git a/src/HistogramWindow.cpp b/src/HistogramWindow.cpp index 5782c041e..904153eeb 100644 --- a/src/HistogramWindow.cpp +++ b/src/HistogramWindow.cpp @@ -289,6 +289,10 @@ HistogramWindow::HistogramWindow(Context *context, bool rangemode) : GcChartWind dateSetting->hide(); connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(rideSelected())); connect(context, SIGNAL(intervalSelected()), this, SLOT(intervalSelected())); + + // comparing things + connect(context, SIGNAL(compareIntervalsStateChanged(bool)), this, SLOT(compareIntervalsStateChanged(bool))); + connect(context, SIGNAL(compareIntervalsChanged()), this, SLOT(compareIntervalsChanged())); } // if any of the controls change we pass the chart everything @@ -310,6 +314,41 @@ HistogramWindow::HistogramWindow(Context *context, bool rangemode) : GcChartWind connect(context, SIGNAL(homeFilterChanged()), this, SLOT(forceReplot())); } +bool +HistogramWindow::isCompare() const +{ + if (!rangemode && context->isCompareIntervals) return true; + + return false; +} + +void +HistogramWindow::compareIntervalsStateChanged(bool) +{ + // ... + compareChanged(); +} + +void +HistogramWindow::compareIntervalsChanged() +{ + // ... + compareChanged(); +} + +void +HistogramWindow::compareChanged() +{ + stale = true; // the 'standard' plots will need to be updated + + // Now create / delete curves etc + // ... + + // replot! + powerHist->replot(); + repaint(); +} + // // Colors (used by metric plotting) // @@ -621,7 +660,7 @@ HistogramWindow::rideSelected() RideItem *ride = myRideItem; - if (!ride || (rangemode && !stale)) return; + if (!ride || isCompare() || (rangemode && !stale)) return; if (rangemode) { // get range that applies to this ride @@ -644,7 +683,7 @@ HistogramWindow::intervalSelected() RideItem *ride = myRideItem; // null? or not plotting current ride, ignore signal - if (!ride || rangemode) return; + if (!ride || isCompare() || rangemode) return; // update interval = true; diff --git a/src/HistogramWindow.h b/src/HistogramWindow.h index 253496576..c1f2406f9 100644 --- a/src/HistogramWindow.h +++ b/src/HistogramWindow.h @@ -143,6 +143,9 @@ class HistogramWindow : public GcChartWindow // bin width editor void setBinEditors(); + // comparing things + bool isCompare() const; + public slots: void rideSelected(); @@ -170,6 +173,11 @@ class HistogramWindow : public GcChartWindow void setZoned(int); void setShade(int); + // comparing things + void compareIntervalsStateChanged(bool); + void compareIntervalsChanged(); + void compareChanged(); + protected slots: void setrBinWidthFromSlider(); diff --git a/src/PowerHist.cpp b/src/PowerHist.cpp index 5ca28ca69..4f711cf53 100644 --- a/src/PowerHist.cpp +++ b/src/PowerHist.cpp @@ -644,6 +644,12 @@ PowerHist::setData(RideFileCache *cache) curveSelected->hide(); } +void +PowerHist::setDataFromCompareIntervals() +{ + // set all the curves based upon whats in the compare intervals array +} + void PowerHist::setData(QList&results, QString totalMetric, QString distMetric, bool isFiltered, QStringList files) diff --git a/src/PowerHist.h b/src/PowerHist.h index 73e7ba316..e6cd5f463 100644 --- a/src/PowerHist.h +++ b/src/PowerHist.h @@ -115,6 +115,9 @@ class PowerHist : public QwtPlot // set data from a ride void setData(RideItem *_rideItem, bool force=false); + // set data from the compare intervals + void setDataFromCompareIntervals(); + // set data from a ridefile cache void setData(RideFileCache *source); diff --git a/src/RideFileCache.cpp b/src/RideFileCache.cpp index 1cb3bbedb..fbacb39c2 100644 --- a/src/RideFileCache.cpp +++ b/src/RideFileCache.cpp @@ -117,6 +117,62 @@ RideFileCache::RideFileCache(Context *context, QString fileName, RideFile *passe } } +RideFileCache::RideFileCache(RideFile *ride) : + context(ride->context), rideFileName(""), ride(ride) +{ + // resize all the arrays to zero + wattsMeanMax.resize(0); + hrMeanMax.resize(0); + cadMeanMax.resize(0); + nmMeanMax.resize(0); + kphMeanMax.resize(0); + xPowerMeanMax.resize(0); + npMeanMax.resize(0); + vamMeanMax.resize(0); + wattsKgMeanMax.resize(0); + aPowerMeanMax.resize(0); + wattsDistribution.resize(0); + hrDistribution.resize(0); + cadDistribution.resize(0); + nmDistribution.resize(0); + kphDistribution.resize(0); + xPowerDistribution.resize(0); + npDistribution.resize(0); + wattsKgDistribution.resize(0); + aPowerDistribution.resize(0); + + // time in zone are fixed to 10 zone max + wattsTimeInZone.resize(10); + hrTimeInZone.resize(10); + + ride->getWeight(); + + // calculate all the arrays + compute(); + + // setup the doubles the users use + doubleArray(wattsMeanMaxDouble, wattsMeanMax, RideFile::watts); + doubleArray(hrMeanMaxDouble, hrMeanMax, RideFile::hr); + doubleArray(cadMeanMaxDouble, cadMeanMax, RideFile::cad); + doubleArray(nmMeanMaxDouble, nmMeanMax, RideFile::nm); + doubleArray(kphMeanMaxDouble, kphMeanMax, RideFile::kph); + doubleArray(npMeanMaxDouble, npMeanMax, RideFile::NP); + doubleArray(vamMeanMaxDouble, vamMeanMax, RideFile::vam); + doubleArray(xPowerMeanMaxDouble, xPowerMeanMax, RideFile::xPower); + doubleArray(wattsKgMeanMaxDouble, wattsKgMeanMax, RideFile::wattsKg); + doubleArray(aPowerMeanMaxDouble, aPowerMeanMax, RideFile::aPower); + + doubleArray(wattsDistributionDouble, wattsDistribution, RideFile::watts); + doubleArray(hrDistributionDouble, hrDistribution, RideFile::hr); + doubleArray(cadDistributionDouble, cadDistribution, RideFile::cad); + doubleArray(nmDistributionDouble, nmDistribution, RideFile::nm); + doubleArray(kphDistributionDouble, kphDistribution, RideFile::kph); + doubleArray(xPowerDistributionDouble, xPowerDistribution, RideFile::xPower); + doubleArray(npDistributionDouble, npDistribution, RideFile::NP); + doubleArray(wattsKgDistributionDouble, wattsKgDistribution, RideFile::wattsKg); + doubleArray(aPowerDistributionDouble, aPowerDistribution, RideFile::aPower); +} + int RideFileCache::decimalsFor(RideFile::SeriesType series) { @@ -294,6 +350,12 @@ RideFileCache::distributionArray(RideFile::SeriesType series) } } +RideFileCache * +RideFileCache::createCacheFor(RideFile*rideFile) +{ + return new RideFileCache(rideFile); +} + // // COMPUTATION // diff --git a/src/RideFileCache.h b/src/RideFileCache.h index ce0a3c6de..fb2e7ff69 100644 --- a/src/RideFileCache.h +++ b/src/RideFileCache.h @@ -134,6 +134,9 @@ class RideFileCache // not actually a copy constructor -- but we call it IN the constructor. RideFileCache(RideFileCache *other) { *this = *other; } + // just from a raw ride file class (usually for intervals) + RideFileCache(RideFile*); + // get a single best or time in zone value from the cache file // intended to be very fast (using lseek to jump direct to the value requested static double best(Context *context, QString fileName, RideFile::SeriesType series, int duration); @@ -145,6 +148,9 @@ class RideFileCache static int decimalsFor(RideFile::SeriesType series); + // compute the cache and return it for the ride + static RideFileCache *createCacheFor(RideFile*); + // get data QVector &meanMaxArray(RideFile::SeriesType); // return meanmax array for the given series QVector &meanMaxDates(RideFile::SeriesType series); // the dates of the bests