From 5f6033ee31eef81573b72a43a00fcfea030f574c Mon Sep 17 00:00:00 2001 From: Damien Date: Thu, 1 Sep 2011 19:24:57 +0200 Subject: [PATCH] Add a Maximums column in the ride summary Add maximums to the ride summary, which also required adding max_speed and max_cadence to the basic ride metrics. Fixes #440. --- src/BasicRideMetrics.cpp | 79 +++++++++++++++++++++++++++++++++++++++ src/DBAccess.cpp | 2 +- src/LTMPopup.cpp | 1 + src/RideSummaryWindow.cpp | 16 ++++++-- src/html/ltm-summary.html | 35 +++++++++++++++-- 5 files changed, 126 insertions(+), 7 deletions(-) diff --git a/src/BasicRideMetrics.cpp b/src/BasicRideMetrics.cpp index e77d8da9c..9813ad4d0 100644 --- a/src/BasicRideMetrics.cpp +++ b/src/BasicRideMetrics.cpp @@ -429,6 +429,84 @@ static bool maxHrAdded = ////////////////////////////////////////////////////////////////////////////// +class MaxSpeed : public RideMetric { + public: + + MaxSpeed() + { + setSymbol("max_speed"); + setName(tr("Max Speed")); + setMetricUnits(tr("kph")); + setImperialUnits(tr("mph")); + setType(RideMetric::Peak); + setPrecision(1); + setConversion(MILES_PER_KM); + } + + void compute(const RideFile *ride, const Zones *, int, + const HrZones *, int, + const QHash &, + const MainWindow *) { + double max = 0.0; + foreach (const RideFilePoint *point, ride->dataPoints()) + if (point->kph > max) max = point->kph; + + setValue(max); + } + + void aggregateWith(const RideMetric &other) { + assert(symbol() == other.symbol()); + const MaxSpeed &ms = dynamic_cast(other); + + setValue(ms.value(true) > value(true) ? ms.value(true) : value(true)); + } + RideMetric *clone() const { return new MaxSpeed(*this); } +}; + +static bool maxSpeedAdded = + RideMetricFactory::instance().addMetric(MaxSpeed()); + +////////////////////////////////////////////////////////////////////////////// + +class MaxCadence : public RideMetric { + public: + + MaxCadence() + { + setSymbol("max_cadence"); + setName(tr("Max Cadence")); + setMetricUnits(tr("rpm")); + setImperialUnits(tr("rpm")); + setType(RideMetric::Peak); + setPrecision(1); + setConversion(MILES_PER_KM); + } + + void compute(const RideFile *ride, const Zones *, int, + const HrZones *, int, + const QHash &, + const MainWindow *) { + double max = 0.0; + foreach (const RideFilePoint *point, ride->dataPoints()) + if (point->cad > max) max = point->cad; + + setValue(max); + } + + void aggregateWith(const RideMetric &other) { + assert(symbol() == other.symbol()); + const MaxCadence &mc = dynamic_cast(other); + + setValue(mc.value(true) > value(true) ? mc.value(true) : value(true)); + } + RideMetric *clone() const { return new MaxCadence(*this); } +}; + +static bool maxCadenceAdded = + RideMetricFactory::instance().addMetric(MaxCadence()); + +////////////////////////////////////////////////////////////////////////////// + class NinetyFivePercentHeartRate : public RideMetric { double hr; public: @@ -625,3 +703,4 @@ static bool addMaxPowerVariance() static bool maxPowerVarianceAdded = addMaxPowerVariance(); +////////////////////////////////////////////////////////////////////////////// diff --git a/src/DBAccess.cpp b/src/DBAccess.cpp index 6b9be4189..d54935bd7 100644 --- a/src/DBAccess.cpp +++ b/src/DBAccess.cpp @@ -40,7 +40,7 @@ // DB Schema Version - YOU MUST UPDATE THIS IF THE SCHEMA VERSION CHANGES!!! // Schema version will change if a) the default metadata.xml is updated // or b) new metrics are added / old changed -static int DBSchemaVersion = 27; +static int DBSchemaVersion = 28; DBAccess::DBAccess(MainWindow* main, QDir home) : main(main), home(home) { diff --git a/src/LTMPopup.cpp b/src/LTMPopup.cpp index 88a80e806..bc31dc65d 100644 --- a/src/LTMPopup.cpp +++ b/src/LTMPopup.cpp @@ -24,6 +24,7 @@ LTMPopup::LTMPopup(MainWindow *parent) : QWidget(parent), main(parent) useMetricUnits = appsettings->value(this, GC_UNIT).toString() == "Metric"; setAutoFillBackground(false); setContentsMargins(0,0,0,0); + setFixedWidth(800); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->setContentsMargins(0,0,0,0); diff --git a/src/RideSummaryWindow.cpp b/src/RideSummaryWindow.cpp index 65f7cb2d4..f6819441c 100644 --- a/src/RideSummaryWindow.cpp +++ b/src/RideSummaryWindow.cpp @@ -128,8 +128,8 @@ RideSummaryWindow::htmlSummary() const bool metricUnits = (unit.toString() == "Metric"); - const int columns = 3; - const char *columnNames[] = { "Totals", "Averages", "Metrics*" }; + const int columns = 4; + const char *columnNames[] = { "Totals", "Averages", "Maximums", "Metrics*" }; const char *totalColumn[] = { "workout_time", "time_riding", @@ -147,6 +147,14 @@ RideSummaryWindow::htmlSummary() const NULL }; + const char *maximumColumn[] = { + "max_speed", + "max_power", + "max_heartrate", + "max_cadence", + NULL + }; + QString s = appsettings->value(this, GC_SETTINGS_SUMMARY_METRICS, GC_SETTINGS_SUMMARY_METRICS_DEFAULT).toString(); QStringList metricColumnList = s.split(","); @@ -210,6 +218,7 @@ RideSummaryWindow::htmlSummary() const QStringList worklist; for (int i=0; totalColumn[i];i++) worklist << totalColumn[i]; for (int i=0; averageColumn[i];i++) worklist << averageColumn[i]; + for (int i=0; maximumColumn[i];i++) worklist << maximumColumn[i]; for (int i=0; metricColumn[i];i++) worklist << metricColumn[i]; for (int i=0; timeInZones[i];i++) worklist << timeInZones[i]; @@ -237,7 +246,8 @@ RideSummaryWindow::htmlSummary() const switch (i) { case 0: metricsList = totalColumn; break; case 1: metricsList = averageColumn; break; - case 2: metricsList = metricColumn; break; + case 2: metricsList = maximumColumn; break; + case 3: metricsList = metricColumn; break; default: assert(false); } for (int j = 0;; ++j) { diff --git a/src/html/ltm-summary.html b/src/html/ltm-summary.html index 1542491dd..a70f2699f 100644 --- a/src/html/ltm-summary.html +++ b/src/html/ltm-summary.html @@ -8,7 +8,7 @@ - - - +
+
@@ -42,7 +42,7 @@
+
@@ -71,7 +71,36 @@
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+Maximums +
Speed ($${max_speed:units}):$${max_speed}
Power (watts):$${max_power}
Heart Rate (bpm):$${max_heartrate}
Cadence (rpm):$${max_cad}
+