mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-04-15 05:32:21 +00:00
Histogram Chart - Add Show Zone Limits option for Power/HR/Pace
This is part 1 of #3911, part 2 will be WBal zones and part 3 Polarized Zones.
This commit is contained in:
@@ -264,6 +264,10 @@ HistogramWindow::HistogramWindow(Context *context, bool rangemode) : GcChartWind
|
||||
showInCPZones->setText(tr("Use polarised zones"));
|
||||
cl->addRow(blankLabel7 = new QLabel(""), showInCPZones);
|
||||
|
||||
showZoneLimits = new QCheckBox;
|
||||
showZoneLimits->setText(tr("Show Zone limits"));
|
||||
cl->addRow(blankLabel8 = new QLabel(""), showZoneLimits);
|
||||
|
||||
// bin width
|
||||
QHBoxLayout *binWidthLayout = new QHBoxLayout;
|
||||
QLabel *binWidthLabel = new QLabel(tr("Bin width"), this);
|
||||
@@ -347,6 +351,8 @@ HistogramWindow::HistogramWindow(Context *context, bool rangemode) : GcChartWind
|
||||
connect(showInCPZones, SIGNAL(stateChanged(int)), this, SLOT(forceReplot()));
|
||||
connect(showInZones, SIGNAL(stateChanged(int)), this, SLOT(setZoned(int)));
|
||||
connect(showInZones, SIGNAL(stateChanged(int)), this, SLOT(forceReplot()));
|
||||
connect(showZoneLimits, SIGNAL(stateChanged(int)), this, SLOT(setZoneLimited(int)));
|
||||
connect(showZoneLimits, SIGNAL(stateChanged(int)), this, SLOT(forceReplot()));
|
||||
connect(shadeZones, SIGNAL(stateChanged(int)), this, SLOT(setShade(int)));
|
||||
connect(shadeZones, SIGNAL(stateChanged(int)), this, SLOT(forceReplot()));
|
||||
connect(showSumY, SIGNAL(currentIndexChanged(int)), this, SLOT(forceReplot()));
|
||||
@@ -416,6 +422,7 @@ HistogramWindow::compareChanged()
|
||||
powerHist->setShading(shadeZones->isChecked() ? true : false);
|
||||
powerHist->setZoned(showInZones->isChecked() ? true : false);
|
||||
powerHist->setCPZoned(showInCPZones->isChecked() ? true : false);
|
||||
powerHist->setZoneLimited(showZoneLimits->isChecked() ? true : false);
|
||||
powerHist->setlnY(showLnY->isChecked() ? true : false);
|
||||
powerHist->setWithZeros(showZeroes->isChecked() ? true : false);
|
||||
powerHist->setSumY(showSumY->currentIndex()== 0 ? true : false);
|
||||
@@ -637,6 +644,7 @@ HistogramWindow::switchMode()
|
||||
shadeZones->show();
|
||||
showInZones->show();
|
||||
showInCPZones->show();
|
||||
showZoneLimits->show();
|
||||
|
||||
// select the series..
|
||||
seriesChanged();
|
||||
@@ -658,6 +666,7 @@ HistogramWindow::switchMode()
|
||||
shadeZones->hide();
|
||||
showInZones->hide();
|
||||
showInCPZones->hide();
|
||||
showZoneLimits->hide();
|
||||
|
||||
// show all the metric controls
|
||||
blankLabel1->show();
|
||||
@@ -931,6 +940,12 @@ HistogramWindow::setZoned(int x)
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
HistogramWindow::setZoneLimited(int x)
|
||||
{
|
||||
showZoneLimits->setCheckState((Qt::CheckState)x);
|
||||
}
|
||||
|
||||
void
|
||||
HistogramWindow::setShade(int x)
|
||||
{
|
||||
@@ -1032,6 +1047,7 @@ HistogramWindow::updateChart()
|
||||
powerHist->setShading(shadeZones->isChecked() ? true : false);
|
||||
powerHist->setZoned(showInZones->isChecked() ? true : false);
|
||||
powerHist->setCPZoned(showInCPZones->isChecked() ? true : false);
|
||||
powerHist->setZoneLimited(showZoneLimits->isChecked() ? true : false);
|
||||
powerHist->setlnY(showLnY->isChecked() ? true : false);
|
||||
powerHist->setWithZeros(showZeroes->isChecked() ? true : false);
|
||||
powerHist->setSumY(showSumY->currentIndex()== 0 ? true : false);
|
||||
@@ -1073,6 +1089,7 @@ HistogramWindow::updateChart()
|
||||
powerHist->setShading(shadeZones->isChecked() ? true : false);
|
||||
powerHist->setZoned(showInZones->isChecked() ? true : false);
|
||||
powerHist->setCPZoned(showInCPZones->isChecked() ? true : false);
|
||||
powerHist->setZoneLimited(showZoneLimits->isChecked() ? true : false);
|
||||
powerHist->setlnY(showLnY->isChecked() ? true : false);
|
||||
powerHist->setWithZeros(showZeroes->isChecked() ? true : false);
|
||||
powerHist->setSumY(showSumY->currentIndex()== 0 ? true : false);
|
||||
|
||||
@@ -67,6 +67,7 @@ class HistogramWindow : public GcChartWindow
|
||||
Q_PROPERTY(bool shade READ shade WRITE setShade USER true)
|
||||
Q_PROPERTY(bool zoned READ zoned WRITE setZoned USER true)
|
||||
Q_PROPERTY(bool cpZoned READ cpZoned WRITE setCPZoned USER true)
|
||||
Q_PROPERTY(bool zoneLimited READ zoneLimited WRITE setZoneLimited USER true)
|
||||
Q_PROPERTY(QString filter READ filter WRITE setFilter USER true)
|
||||
Q_PROPERTY(QDate fromDate READ fromDate WRITE setFromDate USER true)
|
||||
Q_PROPERTY(QDate toDate READ toDate WRITE setToDate USER true)
|
||||
@@ -105,6 +106,8 @@ class HistogramWindow : public GcChartWindow
|
||||
void setCPZoned(bool x) { return showInCPZones->setChecked(x); }
|
||||
bool zoned() const { return showInZones->isChecked(); }
|
||||
void setZoned(bool x) { return showInZones->setChecked(x); }
|
||||
bool zoneLimited() const { return showZoneLimits->isChecked(); }
|
||||
void setZoneLimited(bool x) { return showZoneLimits->setChecked(x); }
|
||||
bool isFiltered() const { if (rangemode) return (isfiltered || context->ishomefiltered || context->isfiltered);
|
||||
else return false; }
|
||||
QString filter() const { return searchBox->filter(); }
|
||||
@@ -172,6 +175,7 @@ class HistogramWindow : public GcChartWindow
|
||||
|
||||
void setZoned(int);
|
||||
void setCPZoned(int);
|
||||
void setZoneLimited(int);
|
||||
void setShade(int);
|
||||
|
||||
// comparing things
|
||||
@@ -204,6 +208,7 @@ class HistogramWindow : public GcChartWindow
|
||||
QCheckBox *shadeZones; // Shade zone background
|
||||
QCheckBox *showInZones; // Plot by Zone
|
||||
QCheckBox *showInCPZones; // Plot by CP domain Moderate/Heavy/Severe Zone
|
||||
QCheckBox *showZoneLimits; // Show Zone limits in labels
|
||||
QComboBox *seriesCombo; // Which data series to plot
|
||||
|
||||
// reveal controls
|
||||
@@ -242,7 +247,7 @@ class HistogramWindow : public GcChartWindow
|
||||
QLabel *comboLabel, *metricLabel1, *metricLabel2, *showLabel,
|
||||
*blankLabel1, *blankLabel2,
|
||||
*blankLabel3, *blankLabel4, *blankLabel5, *blankLabel6,
|
||||
*blankLabel7, *colorLabel;
|
||||
*blankLabel7, *blankLabel8, *colorLabel;
|
||||
|
||||
// in range mode we can also plot a distribution chart
|
||||
// based upon metrics and not just data series
|
||||
|
||||
@@ -695,7 +695,7 @@ PowerHist::recalcCompare()
|
||||
}
|
||||
if (zones && zone_range != -1) {
|
||||
if ((series == RideFile::watts || series == RideFile::wattsKg)) {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(zones, zone_range));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(zones, zone_range, zoneLimited));
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, zones->numZones(zone_range), 1);
|
||||
}
|
||||
}
|
||||
@@ -718,7 +718,7 @@ PowerHist::recalcCompare()
|
||||
}
|
||||
if (hrzones && hrzone_range != -1) {
|
||||
if (series == RideFile::hr) {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(hrzones, hrzone_range));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(hrzones, hrzone_range, zoneLimited));
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, hrzones->numZones(hrzone_range), 1);
|
||||
}
|
||||
}
|
||||
@@ -741,7 +741,7 @@ PowerHist::recalcCompare()
|
||||
}
|
||||
if (pacezones && pacezone_range != -1) {
|
||||
if (series == RideFile::kph) {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PaceZoneScaleDraw(pacezones, pacezone_range));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PaceZoneScaleDraw(pacezones, pacezone_range, zoneLimited));
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, pacezones->numZones(pacezone_range), 1);
|
||||
}
|
||||
}
|
||||
@@ -796,6 +796,7 @@ PowerHist::recalc(bool force)
|
||||
LASTlny == lny &&
|
||||
LASTzoned == zoned &&
|
||||
LASTcpzoned == cpzoned &&
|
||||
LASTzoneLimited == zoneLimited &&
|
||||
LASTbinw == binw &&
|
||||
LASTwithz == withz &&
|
||||
LASTdt == dt &&
|
||||
@@ -814,12 +815,14 @@ PowerHist::recalc(bool force)
|
||||
LASTlny = lny;
|
||||
LASTzoned = zoned;
|
||||
LASTcpzoned = cpzoned;
|
||||
LASTzoneLimited = zoneLimited;
|
||||
LASTbinw = binw;
|
||||
LASTwithz = withz;
|
||||
LASTdt = dt;
|
||||
LASTabsolutetime = absolutetime;
|
||||
}
|
||||
|
||||
setParameterAxisTitle();
|
||||
|
||||
if (source == Ride && !rideItem) {
|
||||
return;
|
||||
@@ -918,7 +921,7 @@ PowerHist::recalc(bool force)
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, 3, 1);
|
||||
} else {
|
||||
int zone_range = context->athlete->zones(rideItem->sport)->whichRange(rideItem->dateTime.date());
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(context->athlete->zones(rideItem->sport), zone_range));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(context->athlete->zones(rideItem->sport), zone_range, zoneLimited));
|
||||
if (zone_range >= 0)
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->zones(rideItem->sport)->numZones(zone_range), 1);
|
||||
else
|
||||
@@ -935,7 +938,7 @@ PowerHist::recalc(bool force)
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PolarisedZoneScaleDraw());
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, 3, 1);
|
||||
} else {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones(rideItem->sport), hrRange));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones(rideItem->sport), hrRange, zoneLimited));
|
||||
if (hrRange >= 0)
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones(rideItem->sport)->numZones(hrRange), 1);
|
||||
else
|
||||
@@ -953,7 +956,7 @@ PowerHist::recalc(bool force)
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PolarisedZoneScaleDraw());
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, 3, 1);
|
||||
} else {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PaceZoneScaleDraw(context->athlete->paceZones(rideItem->isSwim), paceRange));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PaceZoneScaleDraw(context->athlete->paceZones(rideItem->isSwim), paceRange, zoneLimited));
|
||||
|
||||
if (paceRange >= 0)
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->paceZones(rideItem->isSwim)->numZones(paceRange), 1);
|
||||
@@ -968,7 +971,7 @@ PowerHist::recalc(bool force)
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PolarisedZoneScaleDraw());
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, 3, 1);
|
||||
} else {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(context->athlete->zones("Bike"), 0));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(context->athlete->zones("Bike"), 0, zoneLimited));
|
||||
if (context->athlete->zones("Bike")->getRangeSize())
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->zones("Bike")->numZones(0), 1); // use zones from first defined range
|
||||
}
|
||||
@@ -980,7 +983,7 @@ PowerHist::recalc(bool force)
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PolarisedZoneScaleDraw());
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, 3, 1);
|
||||
} else {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones("Bike"), 0));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones("Bike"), 0, zoneLimited));
|
||||
if (context->athlete->hrZones("Bike")->getRangeSize())
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones("Bike")->numZones(0), 1); // use zones from first defined range
|
||||
}
|
||||
@@ -992,7 +995,7 @@ PowerHist::recalc(bool force)
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PolarisedZoneScaleDraw());
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, 3, 1);
|
||||
} else {
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PaceZoneScaleDraw(context->athlete->paceZones(false), 0));
|
||||
setAxisScaleDraw(QwtPlot::xBottom, new PaceZoneScaleDraw(context->athlete->paceZones(false), 0, zoneLimited));
|
||||
if (context->athlete->paceZones(false)->getRangeSize())
|
||||
setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->paceZones(false)->numZones(0), 1); // use zones from first defined range
|
||||
}
|
||||
@@ -2273,6 +2276,13 @@ PowerHist::setZoned(bool value)
|
||||
setComparePens();
|
||||
}
|
||||
|
||||
void
|
||||
PowerHist::setZoneLimited(bool value)
|
||||
{
|
||||
zoneLimited = value;
|
||||
setComparePens();
|
||||
}
|
||||
|
||||
void
|
||||
PowerHist::setWithZeros(bool value)
|
||||
{
|
||||
|
||||
@@ -171,6 +171,7 @@ class PowerHist : public QwtPlot
|
||||
void setWithZeros(bool value);
|
||||
void setZoned(bool value);
|
||||
void setCPZoned(bool value);
|
||||
void setZoneLimited(bool value);
|
||||
void setSumY(bool value);
|
||||
void configChanged(qint32);
|
||||
void setAxisTitle(int axis, QString label);
|
||||
@@ -226,6 +227,7 @@ class PowerHist : public QwtPlot
|
||||
bool shade;
|
||||
bool zoned; // show in zones
|
||||
bool cpzoned; // show in cp zones
|
||||
bool zoneLimited; // show zone limits
|
||||
double binw;
|
||||
bool withz; // whether zeros are included in histogram
|
||||
double dt; // length of sample
|
||||
@@ -280,6 +282,7 @@ class PowerHist : public QwtPlot
|
||||
bool LASTlny;
|
||||
bool LASTzoned; // show in zones
|
||||
bool LASTcpzoned; // show in zones
|
||||
bool LASTzoneLimited; // show zone limits
|
||||
double LASTbinw;
|
||||
bool LASTwithz; // whether zeros are included in histogram
|
||||
double LASTdt; // length of sample
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
class ZoneScaleDraw: public QwtScaleDraw
|
||||
{
|
||||
public:
|
||||
ZoneScaleDraw(const Zones *zones, int range=-1) : zones(zones) {
|
||||
ZoneScaleDraw(const Zones *zones, int range=-1, bool zoneLimited=false) : zones(zones), zoneLimited(zoneLimited) {
|
||||
setRange(range);
|
||||
setTickLength(QwtScaleDiv::MajorTick, 3);
|
||||
}
|
||||
@@ -59,18 +59,17 @@ class ZoneScaleDraw: public QwtScaleDraw
|
||||
virtual QwtText label(double v) const
|
||||
{
|
||||
if (v <0 || v > (names.count()-1) || range < 0) return QString("");
|
||||
else if (!zoneLimited) return names[v];
|
||||
else {
|
||||
return names[v];
|
||||
#if 0
|
||||
if (v == names.count()-1) return QString("%1\n%2w+").arg(names[v]).arg(from[v]);
|
||||
else return QString("%1\n%2-%3w").arg(names[v]).arg(from[v]).arg(to[v]);
|
||||
#endif
|
||||
if (v == names.count()-1) return QString("%1 (%2+ %3)").arg(names[v]).arg(from[v]).arg(RideFile::unitName(RideFile::watts, nullptr));
|
||||
else return QString("%1 (%2-%3)").arg(names[v]).arg(from[v]).arg(to[v]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const Zones *zones;
|
||||
int range;
|
||||
bool zoneLimited;
|
||||
QList<QString> names;
|
||||
QList <int> from, to;
|
||||
};
|
||||
@@ -125,7 +124,7 @@ class WbalZoneScaleDraw: public QwtScaleDraw
|
||||
class HrZoneScaleDraw: public QwtScaleDraw
|
||||
{
|
||||
public:
|
||||
HrZoneScaleDraw(const HrZones *zones, int range=-1) : zones(zones) {
|
||||
HrZoneScaleDraw(const HrZones *zones, int range=-1, bool zoneLimited=false) : zones(zones), zoneLimited(zoneLimited) {
|
||||
setRange(range);
|
||||
setTickLength(QwtScaleDiv::MajorTick, 3);
|
||||
}
|
||||
@@ -156,18 +155,17 @@ class HrZoneScaleDraw: public QwtScaleDraw
|
||||
virtual QwtText label(double v) const
|
||||
{
|
||||
if (v < 0 || v > (names.count()-1) || range < 0) return QString("");
|
||||
else if (!zoneLimited) return names[v];
|
||||
else {
|
||||
return names[v];
|
||||
#if 0
|
||||
if (v == names.count()-1) return QString("%1\n%2bpm+").arg(names[v]).arg(from[v]);
|
||||
else return QString("%1\n%2-%3bpm").arg(names[v]).arg(from[v]).arg(to[v]);
|
||||
#endif
|
||||
if (v == names.count()-1) return QString("%1 (%2+ %3)").arg(names[v]).arg(from[v]).arg(RideFile::unitName(RideFile::hr, nullptr));
|
||||
else return QString("%1 (%2-%3)").arg(names[v]).arg(from[v]).arg(to[v]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const HrZones *zones;
|
||||
int range;
|
||||
bool zoneLimited;
|
||||
QList<QString> names;
|
||||
QList <int> from, to;
|
||||
|
||||
@@ -176,7 +174,7 @@ class HrZoneScaleDraw: public QwtScaleDraw
|
||||
class PaceZoneScaleDraw: public QwtScaleDraw
|
||||
{
|
||||
public:
|
||||
PaceZoneScaleDraw(const PaceZones *zones, int range=-1) : zones(zones) {
|
||||
PaceZoneScaleDraw(const PaceZones *zones, int range=-1, bool zoneLimited=false) : zones(zones), zoneLimited(zoneLimited) {
|
||||
setRange(range);
|
||||
setTickLength(QwtScaleDiv::MajorTick, 3);
|
||||
}
|
||||
@@ -201,26 +199,27 @@ class PaceZoneScaleDraw: public QwtScaleDraw
|
||||
from.clear();
|
||||
to.clear();
|
||||
}
|
||||
metricPace = appsettings->value(nullptr, zones->paceSetting(), GlobalContext::context()->useMetricUnits).toBool();
|
||||
}
|
||||
|
||||
// return label
|
||||
virtual QwtText label(double v) const
|
||||
{
|
||||
if (v < 0 || v > (names.count()-1) || range < 0) return QString("");
|
||||
else if (!zoneLimited) return names[v];
|
||||
else {
|
||||
return names[v];
|
||||
#if 0
|
||||
if (v == names.count()-1) return QString("%1\n%2kph+").arg(names[v]).arg(from[v]);
|
||||
else return QString("%1\n%2-%3kph").arg(names[v]).arg(from[v]).arg(to[v]);
|
||||
#endif
|
||||
if (v == names.count()-1) return QString("%1 (%2+ %3)").arg(names[v]).arg(zones->kphToPaceString(from[v], metricPace)).arg(zones->paceUnits(metricPace));
|
||||
else return QString("%1 (%2-%3)").arg(names[v]).arg(zones->kphToPaceString(from[v], metricPace)).arg(zones->kphToPaceString(to[v], metricPace));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const PaceZones *zones;
|
||||
int range;
|
||||
bool zoneLimited;
|
||||
QList<QString> names;
|
||||
QList <double> from, to;
|
||||
bool metricPace;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user