Shade Selector on CP chart

- none - no shading on the all curve
- derived CP - as before using the CP value derived from all curve data
- CP - the value of CP for the time of the ride

NOTE: When in rangemode (i.e. on home) the CP is set to the mean CP for
the date range selected.
This commit is contained in:
Mark Liversedge
2013-02-16 13:41:55 +00:00
parent 75d5799f39
commit b389555bef
4 changed files with 99 additions and 28 deletions

View File

@@ -52,7 +52,8 @@ CpintPlot::CpintPlot(MainWindow *main, QString p, const Zones *zones) :
mainWindow(main),
current(NULL),
bests(NULL),
isFiltered(false)
isFiltered(false),
shadeMode(2)
{
setInstanceName("CP Plot");
assert(!USE_T0_IN_CP_MODEL); // doesn't work with energyMode=true
@@ -366,7 +367,7 @@ CpintPlot::plot_CP_curve(CpintPlot *thisPlot, // the plot we're currently di
if (appsettings->value(this, GC_ANTIALIAS, false).toBool() == true)
CPCurve->setRenderHint(QwtPlotItem::RenderAntialiased);
QPen pen(GColor(CCP));
pen.setWidth(appsettings->value(this, GC_LINEWIDTH, 2.0).toDouble());
pen.setWidth(2.0);
pen.setStyle(Qt::DashLine);
CPCurve->setPen(pen);
CPCurve->setData(cp_curve_time.data(), cp_curve_power.data(), curve_points);
@@ -391,6 +392,7 @@ CpintPlot::clear_CP_Curves()
}
}
// plot the all curve, with shading according to the shade mode
void
CpintPlot::plot_allCurve(CpintPlot *thisPlot,
int n_values,
@@ -406,10 +408,26 @@ CpintPlot::plot_allCurve(CpintPlot *thisPlot,
energyBests[t] = power_values[t] * time_values[t] * 60.0 / 1000.0;
}
// generate zones from derived CP value
if (cp > 0) {
// lets work out how we are shading it
switch(shadeMode) {
case 0 : // not shading!!
break;
case 1 : // value for current date
// or average for date range if a range
shadingCP = dateCP;
break;
default:
case 2 : // derived value
shadingCP = cp;
break;
}
// generate zones from shading CP value
if (shadingCP > 0) {
QList <int> power_zone;
int n_zones = zones->lowsFromCP(&power_zone, (int) int(cp));
int n_zones = zones->lowsFromCP(&power_zone, (int) int(shadingCP));
int high = n_values - 1;
int zone = 0;
while (zone < n_zones && high > 0) {
@@ -428,19 +446,21 @@ CpintPlot::plot_allCurve(CpintPlot *thisPlot,
if (appsettings->value(this, GC_ANTIALIAS, false).toBool() == true)
curve->setRenderHint(QwtPlotItem::RenderAntialiased);
QPen pen(color.darker(200));
pen.setWidth(appsettings->value(this, GC_LINEWIDTH, 2.0).toDouble());
pen.setWidth(2.0);
curve->setPen(pen);
curve->attach(thisPlot);
// use a linear gradient
color.setAlpha(180);
QColor color1 = color;
color1.setAlpha(64);
QLinearGradient linearGradient(0, 0, 0, height());
linearGradient.setColorAt(0.0, color);
linearGradient.setColorAt(1.0, color1);
linearGradient.setSpread(QGradient::PadSpread);
curve->setBrush(linearGradient); // fill below the line
if (shadeMode && shadingCP) { // 0 value means no shading please - and only if proper value for shadingCP
color.setAlpha(180);
QColor color1 = color;
color1.setAlpha(64);
QLinearGradient linearGradient(0, 0, 0, height());
linearGradient.setColorAt(0.0, color);
linearGradient.setColorAt(1.0, color1);
linearGradient.setSpread(QGradient::PadSpread);
curve->setBrush(linearGradient); // fill below the line
}
if (series == RideFile::none) { // this is Energy mode
curve->setData(time_values.data() + low,
@@ -451,7 +471,7 @@ CpintPlot::plot_allCurve(CpintPlot *thisPlot,
}
allCurves.append(curve);
if (series != RideFile::none || energyBests[high] > 100.0) {
if (shadeMode && (series != RideFile::none || energyBests[high] > 100.0)) {
QwtText text(name);
text.setFont(QFont("Helvetica", 20, QFont::Bold));
color.setAlpha(255);
@@ -554,7 +574,7 @@ CpintPlot::calculate(RideItem *rideItem)
else {
// make sure color reflects latest config
QPen pen(GColor(CCP));
pen.setWidth(2.0);
pen.setWidth(4.0);
pen.setStyle(Qt::DashLine);
CPCurve->setPen(pen);
}
@@ -792,3 +812,9 @@ CpintPlot::setFilter(QStringList list)
delete bests;
bests = NULL;
}
void
CpintPlot::setShadeMode(int x)
{
shadeMode = x;
}

View File

@@ -87,11 +87,13 @@ class CpintPlot : public QwtPlot
const QwtPlotCurve *getCPCurve() const { return CPCurve; }
double cp, tau, t0; // CP model parameters
double shadingCP; // the CP value we use to draw the shade
void deriveCPParameters();
void changeSeason(const QDate &start, const QDate &end);
void setAxisTitle(int axis, QString label);
void setSeries(RideFile::SeriesType);
QVector<double> getBests() { return bests->meanMaxArray(series); }
QVector<QDate> getBestDates() { return bests->meanMaxDates(series); }
@@ -103,6 +105,8 @@ class CpintPlot : public QwtPlot
void plot_allCurve(CpintPlot *plot, int n_values, const double *power_values);
void configChanged();
void pointHover(QwtPlotCurve *curve, int index);
void setShadeMode(int x);
void setDateCP(int x) { dateCP = x; }
void clearFilter();
void setFilter(QStringList);
@@ -121,6 +125,7 @@ class CpintPlot : public QwtPlot
QDate startDate;
QDate endDate;
const Zones *zones;
int dateCP;
RideFile::SeriesType series;
MainWindow *mainWindow;
@@ -130,6 +135,7 @@ class CpintPlot : public QwtPlot
QStringList files;
bool isFiltered;
int shadeMode;
};
#endif // _GC_CpintPlot_h

View File

@@ -30,6 +30,7 @@
#include "Season.h"
#include "SeasonParser.h"
#include "Colors.h"
#include "Zones.h"
#include <QXmlInputSource>
#include <QXmlSimpleReader>
@@ -147,23 +148,26 @@ CriticalPowerWindow::CriticalPowerWindow(const QDir &home, MainWindow *parent, b
label2->hide();
}
cpintSetCPButton = new QPushButton(tr("&Save CP value"), this);
cpintSetCPButton->setEnabled(false);
cpintSetCPButton->hide();
cl->addRow(label2, cComboSeason);
cl->addWidget(new QLabel("")); //spacing
cl->addRow(new QLabel(tr("Data series")), seriesCombo);
pcl->addRow(new QLabel(""), cpintSetCPButton);
// shading
shadeCombo = new QComboBox(this);
shadeCombo->addItem(tr("None"));
shadeCombo->addItem(tr("Using CP"));
shadeCombo->addItem(tr("Using derived CP"));
QLabel *shading = new QLabel(tr("Power Shading"));
shadeCombo->setCurrentIndex(2);
cl->addRow(shading, shadeCombo);
dateSetting = new DateSettingsEdit(this);
cl->addRow(label, dateSetting);
if (rangemode == false) {
dateSetting->hide();
label->hide();
}
cl->addWidget(new QLabel("")); //spacing
cl->addRow(new QLabel(tr("Data series")), seriesCombo);
pcl->addRow(new QLabel(""), cpintSetCPButton);
picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPicker::VLineRubberBand,
QwtPicker::AlwaysOff, cpintPlot->canvas());
@@ -196,7 +200,7 @@ CriticalPowerWindow::CriticalPowerWindow(const QDir &home, MainWindow *parent, b
connect(mainWindow, SIGNAL(rideAdded(RideItem*)), this, SLOT(newRideAdded(RideItem*)));
connect(mainWindow, SIGNAL(rideDeleted(RideItem*)), this, SLOT(newRideAdded(RideItem*)));
connect(seasons, SIGNAL(seasonsChanged()), this, SLOT(resetSeasons()));
connect(shadeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(shadingSelected(int)));
connect(dateSetting, SIGNAL(useCustomRange(DateRange)), this, SLOT(useCustomRange(DateRange)));
connect(dateSetting, SIGNAL(useThruToday()), this, SLOT(useThruToday()));
connect(dateSetting, SIGNAL(useStandardRange()), this, SLOT(useStandardRange()));
@@ -238,6 +242,13 @@ CriticalPowerWindow::rideSelected()
currentRide = myRideItem;
if (currentRide) {
if (mainWindow->zones()) {
int zoneRange = mainWindow->zones()->whichRange(currentRide->dateTime.date());
int CP = zoneRange >= 0 ? mainWindow->zones()->getCP(zoneRange) : 0;
cpintPlot->setDateCP(CP);
} else {
cpintPlot->setDateCP(0);
}
cpintPlot->calculate(currentRide);
// apply latest colors
@@ -501,11 +512,25 @@ CriticalPowerWindow::dateRangeChanged(DateRange dateRange)
if (dateRange.from == cfrom && dateRange.to == cto && !stale) return;
cfrom = dateRange.from;
cto = dateRange.to;
// lets work out the average CP configure value
if (mainWindow->zones()) {
int fromZoneRange = mainWindow->zones()->whichRange(cfrom);
int toZoneRange = mainWindow->zones()->whichRange(cto);
int CPfrom = fromZoneRange >= 0 ? mainWindow->zones()->getCP(fromZoneRange) : 0;
int CPto = toZoneRange >= 0 ? mainWindow->zones()->getCP(toZoneRange) : CPfrom;
if (CPfrom == 0) CPfrom = CPto;
int dateCP = (CPfrom + CPto) / 2;
cpintPlot->setDateCP(dateCP);
}
cpintPlot->changeSeason(dateRange.from, dateRange.to);
cpintPlot->calculate(currentRide);
cfrom = dateRange.from;
cto = dateRange.to;
stale = false;
}
@@ -522,3 +547,11 @@ void CriticalPowerWindow::filterChanged()
{
cpintPlot->calculate(currentRide);
}
void
CriticalPowerWindow::shadingSelected(int shading)
{
cpintPlot->setShadeMode(shading);
if (rangemode) dateRangeChanged(DateRange());
else cpintPlot->calculate(currentRide);
}

View File

@@ -52,6 +52,7 @@ class CriticalPowerWindow : public GcChartWindow
Q_PROPERTY(int lastN READ lastN WRITE setLastN USER true)
Q_PROPERTY(int lastNX READ lastNX WRITE setLastNX USER true)
Q_PROPERTY(int prevN READ prevN WRITE setPrevN USER true)
Q_PROPERTY(int shading READ shading WRITE setShading USER true)
Q_PROPERTY(int useSelected READ useSelected WRITE setUseSelected USER true) // !! must be last property !!
public:
@@ -107,6 +108,9 @@ class CriticalPowerWindow : public GcChartWindow
int prevN() { return dateSetting->prevN(); }
void setPrevN(int x) { dateSetting->setPrevN(x); }
int shading() { return shadeCombo->currentIndex(); }
void setShading(int x) { return shadeCombo->setCurrentIndex(x); }
protected slots:
void newRideAdded(RideItem*);
void cpintTimeValueEntered();
@@ -114,6 +118,7 @@ class CriticalPowerWindow : public GcChartWindow
void pickerMoved(const QPoint &pos);
void rideSelected();
void seasonSelected(int season);
void shadingSelected(int shading);
void setSeries(int index);
void resetSeasons();
void filterChanged();
@@ -142,6 +147,7 @@ class CriticalPowerWindow : public GcChartWindow
QLabel *cpintCPValue;
QComboBox *seriesCombo;
QComboBox *cComboSeason;
QComboBox *shadeCombo;
QPushButton *cpintSetCPButton;
QwtPlotPicker *picker;
void addSeries();