From 9f06d48c42e6f101beb41be85ab3cda9df293094 Mon Sep 17 00:00:00 2001 From: Alejandro Martinez Date: Fri, 1 Jan 2016 17:38:20 -0300 Subject: [PATCH] Added Time in Pace Zones to RideSummary in Trends Compared Mode For Date Ranges and Intervals, only when activities are homogeneous to select the correct Pace Zones Also enabled Time in Power Zones only when activities are homogeneouse to select the correct Power Zones --- src/RideSummaryWindow.cpp | 198 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 190 insertions(+), 8 deletions(-) diff --git a/src/RideSummaryWindow.cpp b/src/RideSummaryWindow.cpp index a98e836ac..fba98d44f 100644 --- a/src/RideSummaryWindow.cpp +++ b/src/RideSummaryWindow.cpp @@ -1673,6 +1673,18 @@ RideSummaryWindow::htmlCompareSummary() const << "wcptime_in_zone_L3" << "wcptime_in_zone_L4"; + static const QStringList paceTimeInZones = QStringList() + << "time_in_zone_P1" + << "time_in_zone_P2" + << "time_in_zone_P3" + << "time_in_zone_P4" + << "time_in_zone_P5" + << "time_in_zone_P6" + << "time_in_zone_P7" + << "time_in_zone_P8" + << "time_in_zone_P9" + << "time_in_zone_P10"; + if (ridesummary) { // @@ -1803,17 +1815,27 @@ RideSummaryWindow::htmlCompareSummary() const summary += ""; } + // Counts of activity types to select Power and Pace Zones + int nActivities=0, nRides=0, nRuns=0, nSwims=0; + foreach (RideItem *metrics, intervalMetrics) { + nActivities++; + if (metrics->isRun) nRuns++; + else if (metrics->isSwim) nSwims++; + else nRides++; + } + // // TIME IN POWER ZONES (we can't do w'bal compare at present) - // - if (context->athlete->zones(false)) { // use my zones + // when all rides or all runs, use zones accordingly + if (((nActivities==nRides) || (nActivities==nRuns)) && + context->athlete->zones(nActivities==nRuns)) { // get from end if period - int rangeidx = context->athlete->zones(false)->whichRange(QDate::currentDate()); // use current zone names et al + int rangeidx = context->athlete->zones(nActivities==nRuns)->whichRange(QDate::currentDate()); // use current zone names et al if (rangeidx > -1) { // get the list of zones - ZoneRange range = const_cast(context->athlete->zones(false))->getZoneRange(rangeidx); + ZoneRange range = const_cast(context->athlete->zones(nActivities==nRuns))->getZoneRange(rangeidx); QList zones = range.zones; // we've got a range and a count of zones so all is well @@ -1949,6 +1971,80 @@ RideSummaryWindow::htmlCompareSummary() const } } + // + // TIME IN PACE ZONES + // when all runs or all swims, use zones accordingly + if (((nActivities==nRuns) || (nActivities==nSwims)) && + context->athlete->zones(nActivities==nSwims)) { + + // get from end if period + int rangeidx = context->athlete->paceZones(nActivities==nSwims)->whichRange(QDate::currentDate()); // use current zone names et al + if (rangeidx > -1) { + + // get the list of zones + PaceZoneRange range = const_cast(context->athlete->paceZones(nActivities==nSwims))->getZoneRange(rangeidx); + QList zones = range.zones; + + // we've got a range and a count of zones so all is well + // we need to throw up a table of time in zone for each interval + summary += tr("

Pace Zones

"); + summary += ""; + + // lets get some headings + summary += ""; // ne need to have a heading for the interval name + summary += ""; // spacing + + foreach (PaceZoneInfo zone, zones) { + summary += QString("").arg(zone.desc).arg(zone.name); + summary += ""; // spacing + } + summary += ""; + + // now the summary + int counter = 0; + int rows = 0; + foreach (RideItem *metrics, intervalMetrics) { + + // only ones that are checked + if (!context->compareIntervals[counter].isChecked()) { + counter++; + continue; + } + + if (rows%2) summary += ""; + else summary += ""; + + summary += ""; + summary += ""; // spacing + + int idx=0; + foreach (PaceZoneInfo zone, zones) { + + int timeZone = metrics->getForSymbol(paceTimeInZones[idx]); + int dt = timeZone - intervalMetrics[0]->getForSymbol(paceTimeInZones[idx]); + idx++; + + // time and then +time + summary += QString("").arg(time_to_string(timeZone)); + + if (counter) summary += QString("") + .arg(dt>0 ? "+" : "-") + .arg(time_to_string(fabs(dt))); + + else summary += ""; + summary += ""; // spacing + + } + summary += ""; + rows++; counter++; + } + + // done + summary += "
 %1 (%2) 
" + context->compareIntervals[counter].name + " %1%1%2 
"; + + } + } + } else { // DATE RANGE COMPARE @@ -2069,17 +2165,29 @@ RideSummaryWindow::htmlCompareSummary() const summary += ""; } + // Counts of activity types to select Power and Pace Zones + int nActivities=0, nRides=0, nRuns=0, nSwims=0; + foreach (CompareDateRange dr, context->compareDateRanges) { + int a, b, r, s; + dr.context->athlete->rideCache->getRideTypeCounts(dr.specification, a, b, r, s); + nActivities += a; + nRides += b; + nRuns += r; + nSwims += s; + } + // // TIME IN POWER ZONES AND W'BAL ZONES - // - if (context->athlete->zones(false)) { // use my zones + // when all rides or all runs, use zones accordingly + if (((nActivities==nRides) || (nActivities==nRuns)) && + context->athlete->zones(nActivities==nRuns)) { // get from end if period - int rangeidx = context->athlete->zones(false)->whichRange(QDate::currentDate()); // use current zone names et al + int rangeidx = context->athlete->zones(nActivities==nRuns)->whichRange(QDate::currentDate()); // use current zone names et al if (rangeidx > -1) { // get the list of zones - ZoneRange range = const_cast(context->athlete->zones(false))->getZoneRange(rangeidx); + ZoneRange range = const_cast(context->athlete->zones(nActivities==nRuns))->getZoneRange(rangeidx); QList zones = range.zones; // we've got a range and a count of zones so all is well @@ -2280,6 +2388,80 @@ RideSummaryWindow::htmlCompareSummary() const } } + // + // TIME IN PACE ZONES + // when all runs or all swims, use zones accordingly + if (((nActivities==nRuns) || (nActivities==nSwims)) && + context->athlete->zones(nActivities==nSwims)) { + + // get from end if period + int rangeidx = context->athlete->paceZones(nActivities==nSwims)->whichRange(QDate::currentDate()); // use current zone names et al + if (rangeidx > -1) { + + // get the list of zones + PaceZoneRange range = const_cast(context->athlete->paceZones(nActivities==nSwims))->getZoneRange(rangeidx); + QList zones = range.zones; + + // we've got a range and a count of zones so all is well + // we need to throw up a table of time in zone for each interval + summary += tr("

Pace Zones

"); + summary += ""; + + // lets get some headings + summary += ""; // ne need to have a heading for the interval name + summary += ""; // spacing + + foreach (PaceZoneInfo zone, zones) { + summary += QString("").arg(zone.desc).arg(zone.name); + summary += ""; // spacing + } + summary += ""; + + // now the summary + int counter = 0; + foreach (CompareDateRange dr, context->compareDateRanges) { + + // skip if not checked + if (!dr.isChecked()) continue; + + if (counter%2) summary += ""; + else summary += ""; + + summary += ""; + summary += ""; // spacing + + int idx=0; + foreach (PaceZoneInfo zone, zones) { + + int timeZone = dr.context->athlete->rideCache->getAggregate(paceTimeInZones[idx], dr.specification, + context->athlete->useMetricUnits, true).toDouble(); + + int dt = timeZone - context->compareDateRanges[0].context->athlete->rideCache->getAggregate(paceTimeInZones[idx], + context->compareDateRanges[0].specification, + context->athlete->useMetricUnits, true).toDouble(); + + idx++; + + // time and then +time + summary += QString("").arg(time_to_string(timeZone)); + + if (counter) summary += QString("") + .arg(dt>0 ? "+" : "-") + .arg(time_to_string(fabs(dt))); + + else summary += ""; + summary += ""; // spacing + + } + summary += ""; + counter++; + } + + // done + summary += "
 %1 (%2) 
" + dr.name + " %1%1%2 
"; + } + } + } // add the usual disclaimers etc at the bottom