mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user