mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
added weekly summary
This commit is contained in:
27
src/TODO
27
src/TODO
@@ -1,34 +1,7 @@
|
||||
|
||||
|
||||
- Sort ride into tree list, don't just append
|
||||
- For cpint, calculate a value for every whole second, using the same or next
|
||||
largest actual time value from the actual data. That way, SRM and PT
|
||||
values will align
|
||||
- Pop up an "importing rides" thermometer when importing
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- Remember last settings for showPower, showHr, etc.
|
||||
- Add interval summary to ride summary
|
||||
- Switch x-axis from minutes to miles
|
||||
- Add units to ride summary
|
||||
- Add weekly summary
|
||||
- Add cpint
|
||||
- Power distribution histogram: Rob Carlsen said:
|
||||
|
||||
I believe that it displays the percentage of time that you've spent in
|
||||
various power ranges, however you can change that to display the
|
||||
absolute time you've spent in each range. the default is 20 watt
|
||||
increments, but the recommendation in the book is to decrease the
|
||||
granularity to 10 watt increments for better estimation of your FTP.
|
||||
|
||||
i thought that using this chart to estimate FTP would only be useful
|
||||
when there were MANY workout files compiled, rather than looking at
|
||||
one workout. all the charts on the "athlete home page" of WKO+ seem to
|
||||
display a collection of past workouts, usually about the last 28 days.
|
||||
|
||||
- Power and HR zones
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
tabWidget = new QTabWidget;
|
||||
rideSummary = new QTextEdit;
|
||||
rideSummary->setReadOnly(true);
|
||||
tabWidget->addTab(rideSummary, "Ride Summary");
|
||||
tabWidget->addTab(rideSummary, tr("Ride Summary"));
|
||||
|
||||
/////////////////////////// Ride Plot Tab ///////////////////////////
|
||||
|
||||
@@ -121,15 +121,15 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
QHBoxLayout *smoothLayout = new QHBoxLayout;
|
||||
QLabel *smoothLabel = new QLabel(tr("Smoothing (secs)"), window);
|
||||
smoothLineEdit = new QLineEdit(window);
|
||||
smoothLineEdit->setFixedWidth(30);
|
||||
smoothLineEdit->setFixedWidth(40);
|
||||
|
||||
smoothLayout->addWidget(smoothLabel);
|
||||
smoothLayout->addWidget(smoothLineEdit);
|
||||
smoothSlider = new QSlider(Qt::Horizontal);
|
||||
smoothSlider->setTickPosition(QSlider::TicksBelow);
|
||||
smoothSlider->setTickInterval(1);
|
||||
smoothSlider->setTickInterval(10);
|
||||
smoothSlider->setMinimum(2);
|
||||
smoothSlider->setMaximum(60);
|
||||
smoothSlider->setMaximum(600);
|
||||
smoothLineEdit->setValidator(new QIntValidator(smoothSlider->minimum(),
|
||||
smoothSlider->maximum(),
|
||||
smoothLineEdit));
|
||||
@@ -213,6 +213,12 @@ MainWindow::MainWindow(const QDir &home) :
|
||||
|
||||
tabWidget->addTab(window, "Power Histogram");
|
||||
|
||||
//////////////////////// Power Histogram Tab ////////////////////////
|
||||
|
||||
weeklySummary = new QTextEdit;
|
||||
weeklySummary->setReadOnly(true);
|
||||
tabWidget->addTab(weeklySummary, tr("Weekly Summary"));
|
||||
|
||||
////////////////////////////// Signals //////////////////////////////
|
||||
|
||||
connect(treeWidget, SIGNAL(itemSelectionChanged()),
|
||||
@@ -432,6 +438,55 @@ MainWindow::rideSelected()
|
||||
if (tabWidget->currentIndex() == 2)
|
||||
cpintPlot->calculate(ride->fileName, ride->dateTime);
|
||||
powerHist->setData(ride->raw);
|
||||
|
||||
QDate wstart = ride->dateTime.date();
|
||||
wstart = wstart.addDays(Qt::Monday - wstart.dayOfWeek());
|
||||
assert(wstart.dayOfWeek() == Qt::Monday);
|
||||
QDate wend = wstart.addDays(7);
|
||||
double weeklySeconds = 0.0;
|
||||
double weeklyDistance = 0.0;
|
||||
double weeklyWork = 0.0;
|
||||
|
||||
for (int i = 0; i < allRides->childCount(); ++i) {
|
||||
if (allRides->child(i)->type() == RIDE_TYPE) {
|
||||
RideItem *item = (RideItem*) allRides->child(i);
|
||||
if ((item->dateTime.date() >= wstart)
|
||||
&& (item->dateTime.date() < wend)) {
|
||||
weeklySeconds += item->secsMovingOrPedaling();
|
||||
weeklyDistance += item->totalDistance();
|
||||
weeklyWork += item->totalWork();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int minutes = ((int) round(weeklySeconds)) / 60;
|
||||
int hours = (int) minutes / 60;
|
||||
minutes %= 60;
|
||||
|
||||
const char *dateFormat = "MM/dd/yyyy";
|
||||
weeklySummary->setHtml(tr(
|
||||
"<center>"
|
||||
"<h2>Week of %1 through %2</h2>"
|
||||
"<h2>Summary</h2>"
|
||||
"<p>"
|
||||
"<table align=\"center\" width=\"60%\" border=0>"
|
||||
"<tr><td>Total time riding:</td>"
|
||||
" <td align=\"right\">%3:%4</td></tr>"
|
||||
"<tr><td>Total distance (miles):</td>"
|
||||
" <td align=\"right\">%5</td></tr>"
|
||||
"<tr><td>Total work (kJ):</td>"
|
||||
" <td align=\"right\">%6</td></tr>"
|
||||
"</table>"
|
||||
"</center>"
|
||||
)
|
||||
.arg(wstart.toString(dateFormat))
|
||||
.arg(wstart.addDays(6).toString(dateFormat))
|
||||
.arg(hours)
|
||||
.arg(minutes, 2, 10, QLatin1Char('0'))
|
||||
.arg((unsigned) round(weeklyDistance))
|
||||
.arg((unsigned) round(weeklyWork))
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ class MainWindow : public QMainWindow
|
||||
QTreeWidget *treeWidget;
|
||||
QTabWidget *tabWidget;
|
||||
QTextEdit *rideSummary;
|
||||
QTextEdit *weeklySummary;
|
||||
AllPlot *allPlot;
|
||||
CpintPlot *cpintPlot;
|
||||
QLabel *cpintTimeLabel;
|
||||
|
||||
@@ -62,28 +62,20 @@ static void summarize(QString &intervals,
|
||||
unsigned last_interval,
|
||||
double time_start, double time_end,
|
||||
double mile_start, double mile_end,
|
||||
unsigned &int_watts_cnt,
|
||||
double &int_watts_sum,
|
||||
unsigned &int_hr_cnt,
|
||||
double &int_hr_sum,
|
||||
unsigned &int_cad_cnt,
|
||||
double &int_cad_sum,
|
||||
unsigned &int_mph_cnt,
|
||||
double &int_mph_sum)
|
||||
{
|
||||
double dur = round(time_end - time_start);
|
||||
double len = mile_end - mile_start;
|
||||
double minutes = (int) (dur/60.0);
|
||||
double seconds = dur - (60 * minutes);
|
||||
double watts_avg = (int_watts_cnt == 0) ? 0
|
||||
: (int) (int_watts_sum / int_watts_cnt);
|
||||
double hr_avg = (int_hr_cnt == 0) ? 0
|
||||
: (int) (int_hr_sum / int_hr_cnt);
|
||||
double cad_avg = (int_cad_cnt == 0) ? 0
|
||||
: (int) (int_cad_sum / int_cad_cnt);
|
||||
double mph_avg = (int_mph_cnt == 0) ? 0
|
||||
: (int) (int_mph_sum / int_mph_cnt);
|
||||
double energy = watts_avg / 1000.0 * dur;
|
||||
double watts_avg = int_watts_sum / dur;
|
||||
double hr_avg = int_hr_sum / dur;
|
||||
double cad_avg = int_cad_sum / dur;
|
||||
double mph_avg = int_mph_sum / dur;
|
||||
double energy = int_watts_sum / 1000.0; // watts_avg / 1000.0 * dur;
|
||||
|
||||
intervals += "<tr><td align=\"center\">%1</td>";
|
||||
intervals += "<td align=\"center\">%2:%3</td>";
|
||||
@@ -103,10 +95,31 @@ static void summarize(QString &intervals,
|
||||
intervals = intervals.arg(cad_avg, 0, 'f', 0);
|
||||
intervals = intervals.arg(mph_avg, 0, 'f', 1);
|
||||
|
||||
int_watts_cnt = 0; int_watts_sum = 0.0;
|
||||
int_hr_cnt = 0; int_hr_sum = 0.0;
|
||||
int_cad_cnt = 0; int_cad_sum = 0.0;
|
||||
int_mph_cnt = 0; int_mph_sum = 0.0;
|
||||
int_watts_sum = 0.0;
|
||||
int_hr_sum = 0.0;
|
||||
int_cad_sum = 0.0;
|
||||
int_mph_sum = 0.0;
|
||||
}
|
||||
|
||||
double RideItem::secsMovingOrPedaling()
|
||||
{
|
||||
if (summary.isEmpty())
|
||||
htmlSummary();
|
||||
return secs_moving_or_pedaling;
|
||||
}
|
||||
|
||||
double RideItem::totalDistance()
|
||||
{
|
||||
if (summary.isEmpty())
|
||||
htmlSummary();
|
||||
return total_distance;
|
||||
}
|
||||
|
||||
double RideItem::totalWork()
|
||||
{
|
||||
if (summary.isEmpty())
|
||||
htmlSummary();
|
||||
return total_work;
|
||||
}
|
||||
|
||||
QString
|
||||
@@ -124,7 +137,7 @@ RideItem::htmlSummary()
|
||||
return summary;
|
||||
}
|
||||
|
||||
double secs_moving_or_pedaling = 0.0;
|
||||
secs_moving_or_pedaling = 0.0;
|
||||
double secs_moving = 0.0;
|
||||
double total_watts = 0.0;
|
||||
double secs_watts = 0.0;
|
||||
@@ -137,13 +150,9 @@ RideItem::htmlSummary()
|
||||
QString intervals = "";
|
||||
unsigned last_interval = UINT_MAX;
|
||||
double int_watts_sum = 0.0;
|
||||
unsigned int_watts_cnt = 0;
|
||||
double int_hr_sum = 0.0;
|
||||
unsigned int_hr_cnt = 0;
|
||||
double int_cad_sum = 0.0;
|
||||
unsigned int_cad_cnt = 0;
|
||||
double int_mph_sum = 0.0;
|
||||
unsigned int_mph_cnt = 0;
|
||||
|
||||
double time_start, time_end, mile_start, mile_end;
|
||||
|
||||
@@ -155,10 +164,8 @@ RideItem::htmlSummary()
|
||||
|
||||
if (last_interval != UINT_MAX) {
|
||||
summarize(intervals, last_interval, time_start,
|
||||
time_end, mile_start, mile_end,
|
||||
int_watts_cnt, int_watts_sum, int_hr_cnt,
|
||||
int_hr_sum, int_cad_cnt, int_cad_sum,
|
||||
int_mph_cnt, int_mph_sum);
|
||||
time_end, mile_start, mile_end, int_watts_sum,
|
||||
int_hr_sum, int_cad_sum, int_mph_sum);
|
||||
}
|
||||
|
||||
last_interval = point->interval;
|
||||
@@ -174,24 +181,20 @@ RideItem::htmlSummary()
|
||||
if (point->watts >= 0.0) {
|
||||
total_watts += point->watts * secs_delta;
|
||||
secs_watts += secs_delta;
|
||||
int_watts_sum += point->watts;
|
||||
int_watts_cnt += 1;
|
||||
int_watts_sum += point->watts * secs_delta;
|
||||
}
|
||||
if (point->hr > 0) {
|
||||
total_hr += point->hr * secs_delta;
|
||||
secs_hr += secs_delta;
|
||||
int_hr_sum += point->hr;
|
||||
int_hr_cnt += 1;
|
||||
int_hr_sum += point->hr * secs_delta;
|
||||
}
|
||||
if (point->cad > 0) {
|
||||
total_cad += point->cad * secs_delta;
|
||||
secs_cad += secs_delta;
|
||||
int_cad_sum += point->cad;
|
||||
int_cad_cnt += 1;
|
||||
int_cad_sum += point->cad * secs_delta;
|
||||
}
|
||||
if (point->mph >= 0) {
|
||||
int_mph_sum += point->mph;
|
||||
int_mph_cnt += 1;
|
||||
int_mph_sum += point->mph * secs_delta;
|
||||
}
|
||||
|
||||
mile_end = point->miles;
|
||||
@@ -199,14 +202,15 @@ RideItem::htmlSummary()
|
||||
}
|
||||
|
||||
summarize(intervals, last_interval, time_start,
|
||||
time_end, mile_start, mile_end,
|
||||
int_watts_cnt, int_watts_sum, int_hr_cnt,
|
||||
int_hr_sum, int_cad_cnt, int_cad_sum,
|
||||
int_mph_cnt, int_mph_sum);
|
||||
time_end, mile_start, mile_end, int_watts_sum,
|
||||
int_hr_sum, int_cad_sum, int_mph_sum);
|
||||
|
||||
avg_watts = (secs_watts == 0.0) ? 0.0
|
||||
: round(total_watts / secs_watts);
|
||||
|
||||
total_distance = raw->points.back()->miles;
|
||||
total_work = total_watts / 1000.0;
|
||||
|
||||
summary += "<p><table align=\"center\" width=\"60%\" border=0>";
|
||||
summary += "<tr><td>Total workout time:</td><td align=\"right\">" +
|
||||
time_to_string(raw->points.back()->secs);
|
||||
@@ -214,10 +218,10 @@ RideItem::htmlSummary()
|
||||
time_to_string(secs_moving_or_pedaling) + "</td></tr>";
|
||||
summary += QString("<tr><td>Total distance (miles):</td>"
|
||||
"<td align=\"right\">%1</td></tr>")
|
||||
.arg(raw->points.back()->miles, 0, 'f', 1);
|
||||
.arg(total_distance, 0, 'f', 1);
|
||||
summary += QString("<tr><td>Total work (kJ):</td>"
|
||||
"<td align=\"right\">%1</td></tr>")
|
||||
.arg((unsigned) (avg_watts / 1000.0 * secs_moving_or_pedaling));
|
||||
.arg((unsigned) round(total_work));
|
||||
summary += QString("<tr><td>Average speed (mph):</td>"
|
||||
"<td align=\"right\">%1</td></tr>")
|
||||
.arg(((secs_moving == 0.0) ? 0.0
|
||||
|
||||
@@ -25,17 +25,29 @@
|
||||
|
||||
class RawFile;
|
||||
|
||||
struct RideItem : public QTreeWidgetItem {
|
||||
QString path;
|
||||
QString fileName;
|
||||
QDateTime dateTime;
|
||||
QString summary;
|
||||
RawFile *raw;
|
||||
class RideItem : public QTreeWidgetItem {
|
||||
|
||||
RideItem(QTreeWidgetItem *parent, int type, QString path,
|
||||
QString fileName, const QDateTime &dateTime);
|
||||
protected:
|
||||
|
||||
QString htmlSummary();
|
||||
double secs_moving_or_pedaling;
|
||||
double total_distance;
|
||||
double total_work;
|
||||
|
||||
public:
|
||||
|
||||
QString path;
|
||||
QString fileName;
|
||||
QDateTime dateTime;
|
||||
QString summary;
|
||||
RawFile *raw;
|
||||
|
||||
RideItem(QTreeWidgetItem *parent, int type, QString path,
|
||||
QString fileName, const QDateTime &dateTime);
|
||||
|
||||
QString htmlSummary();
|
||||
double secsMovingOrPedaling();
|
||||
double totalDistance();
|
||||
double totalWork();
|
||||
};
|
||||
|
||||
#endif // _GC_RideItem_h
|
||||
|
||||
Reference in New Issue
Block a user