Exemplo n.º 1
0
 WorkoutPlot()
 {
     workoutCurve = new QwtPlotCurve();
     setTitle("Workout Chart");
     QPen pen = QPen(Qt::blue,1.0);
     workoutCurve->setPen(pen);
     QColor brush_color = QColor(124, 91, 31);
     brush_color.setAlpha(64);
     workoutCurve->setBrush(brush_color);
     workoutCurve->attach(this);
 }
Exemplo n.º 2
0
void
CpintPlot::plot_allCurve(CpintPlot *thisPlot,
                         int n_values,
                         const double *power_values)
{
    clear_CP_Curves();

    QVector<double> energyBests(n_values);
    QVector<double> time_values(n_values);
    // generate an array of time values
    for (int t = 0; t < n_values; t++) {
        time_values[t] = (t + 1) / 60.0;
        energyBests[t] = power_values[t] * time_values[t] * 60.0 / 1000.0;
    }

    // generate zones from derived CP value
    if (cp > 0) {
        QList <int> power_zone;
        int n_zones = zones->lowsFromCP(&power_zone, (int) int(cp));
        int high = n_values - 1;
        int zone = 0;
        while (zone < n_zones && high > 0) {
            int low = high - 1;
            int nextZone = zone + 1;
            if (nextZone >= power_zone.size())
                low = 0;
            else {
                while ((low > 0) && (power_values[low] < power_zone[nextZone]))
                    --low;
            }

            QColor color = zoneColor(zone, n_zones);
            QString name = zones->getDefaultZoneName(zone);
            QwtPlotCurve *curve = new QwtPlotCurve(name);
            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());
            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 (series == RideFile::none) { // this is Energy mode 
                curve->setData(time_values.data() + low,
                               energyBests.data() + low, high - low + 1);
            } else {
                curve->setData(time_values.data() + low,
                               power_values + low, high - low + 1);
            }
            allCurves.append(curve);

            if (series != RideFile::none || energyBests[high] > 100.0) {
                QwtText text(name);
                text.setFont(QFont("Helvetica", 20, QFont::Bold));
                color.setAlpha(255);
                text.setColor(color);
                QwtPlotMarker *label_mark = new QwtPlotMarker();
                // place the text in the geometric mean in time, at a decent power
                double x, y;
                if (series == RideFile::none) {
                    x = (time_values[low] + time_values[high]) / 2;
                    y = (energyBests[low] + energyBests[high]) / 5;
                }
                else {
                    x = sqrt(time_values[low] * time_values[high]);
                    y = (power_values[low] + power_values[high]) / 5;
                }
                label_mark->setValue(x, y);
                label_mark->setLabel(text);
                label_mark->attach(thisPlot);
                allZoneLabels.append(label_mark);
            }

            high = low;
            ++zone;
        }
    }
    // no zones available: just plot the curve without zones
    else {
        QwtPlotCurve *curve = new QwtPlotCurve(tr("maximal power"));
        if (appsettings->value(this, GC_ANTIALIAS, false).toBool() == true)
            curve->setRenderHint(QwtPlotItem::RenderAntialiased);
        QPen pen(GColor(CCP));
        pen.setWidth(appsettings->value(this, GC_LINEWIDTH, 2.0).toDouble());
        curve->setPen(pen);
        QColor brush_color = GColor(CCP);
        brush_color.setAlpha(200);
        curve->setBrush(brush_color);   // brush fills below the line
        if (series == RideFile::none)
            curve->setData(time_values.data(), energyBests.data(), n_values);
        else
            curve->setData(time_values.data(), power_values, n_values);
        curve->attach(thisPlot);
        allCurves.append(curve);
    }

    // Energy mode is really only interesting in the range where energy is
    // linear in interval duration--up to about 1 hour.
    double xmax = (series == RideFile::none)  ? 60.0 : time_values[n_values - 1];

    if (series == RideFile::vam)
        thisPlot->setAxisScale(thisPlot->xBottom, (double) 4.993, (double)xmax);
    else
        thisPlot->setAxisScale(thisPlot->xBottom, (double) 0.017, (double)xmax);

    double ymax;
    if (series == RideFile::none) {
        int i = std::lower_bound(time_values.begin(), time_values.end(), 60.0) - time_values.begin();
        ymax = 10 * ceil(energyBests[i] / 10);
    }
    else {
        ymax = 100 * ceil(power_values[0] / 100);
        if (ymax == 100)
            ymax = 5 * ceil(power_values[0] / 5);
    }
    thisPlot->setAxisScale(thisPlot->yLeft, 0, ymax);
}
Exemplo n.º 3
0
void
PfPvPlot::refreshZoneItems()
{
    // clear out any zone curves which are presently defined
    if (zoneCurves.size()) {

        QListIterator<QwtPlotCurve *> i(zoneCurves);
        while (i.hasNext()) {
            QwtPlotCurve *curve = i.next();
            curve->detach();
            //delete curve;
        }
    }
    zoneCurves.clear();

    // delete any existing power zone labels
    if (zoneLabels.size()) {

        QListIterator<PfPvPlotZoneLabel *> i(zoneLabels);
        while (i.hasNext()) {
            PfPvPlotZoneLabel *label = i.next();
            label->detach();
            delete label;
        }
    }
    zoneLabels.clear();

    // set zones from ride or athlete and date of
    // first item in the compare set
    const Zones *zones;
    int zone_range = -1;

    // comparing does zones for items selected not current ride
    if (context->isCompareIntervals) {

        zones = context->athlete->zones();

        // no athlete zones anyway!
        if (!zones) return;

        // use first compare interval date
        if (context->compareIntervals.count()) {
            zone_range = zones->whichRange(context->compareIntervals[0].data->startTime().date());
        }

        // still not set 
        if (zone_range == -1) {
            zone_range = zones->whichRange(QDate::currentDate());
        }

    } else if (rideItem) {

        zones = rideItem->zones;
        zone_range = rideItem->zoneRange();

    } else {

        return; // null ride and not compare etc
    }

    if (zone_range >= 0) {
        setCP(zones->getCP(zone_range));

        // populate the zone curves
        QList <int> zone_power = zones->getZoneLows(zone_range);
        QList <QString> zone_name = zones->getZoneNames(zone_range);
        int num_zones = zone_power.size();
        if (zone_name.size() != num_zones) return;

        if (num_zones > 0) {
            QPen *pen = new QPen();
            pen->setStyle(Qt::NoPen);

            QwtArray<double> yvalues;

            // generate x values
            for (int z = 0; z < num_zones; z ++) {

                QwtPlotCurve *curve = new QwtPlotCurve(zone_name[z]);

                curve->setPen(*pen);
                QColor brush_color = zoneColor(z, num_zones);
                brush_color.setHsv(brush_color.hue(), brush_color.saturation() / 4, brush_color.value());
                curve->setBrush(brush_color);   // fill below the line
                curve->setZ(1 - 1e-6 * zone_power[z]);

                // generate data for curve
                if (z < num_zones - 1) {
                    QwtArray <double> contour_yvalues;
                    int watts = zone_power[z + 1];
                    int dwatts = (double) watts;
                    for (int i = 0; i < contour_xvalues.size(); i ++) {
                        contour_yvalues.append( (1e6 * contour_xvalues[i] < watts) ?  1e6 : dwatts / contour_xvalues[i]);
                    }
                    curve->setSamples(contour_xvalues, contour_yvalues);

                } else {

                    // top zone has a curve at "infinite" power
                    QwtArray <double> contour_x;
                    QwtArray <double> contour_y;
                    contour_x.append(contour_xvalues[0]);
                    contour_x.append(contour_xvalues[contour_xvalues.size() - 1]);
                    contour_y.append(1e6);
                    contour_y.append(1e6);
                    curve->setSamples(contour_x, contour_y);
                }

                curve->setVisible(shade_zones);
                curve->attach(this);
                zoneCurves.append(curve);
            }

            delete pen;

            // generate labels for existing zones
            for (int z = 0; z < num_zones; z ++) {
                PfPvPlotZoneLabel *label = new PfPvPlotZoneLabel(this, z);
                label->setVisible(shade_zones);
                label->attach(this);
                zoneLabels.append(label);
            }
        }
    }
}
Exemplo n.º 4
0
void
PfPvPlot::refreshZoneItems()
{
    // clear out any zone curves which are presently defined
    if (zoneCurves.size()) {

        QListIterator<QwtPlotCurve *> i(zoneCurves);
        while (i.hasNext()) {
            QwtPlotCurve *curve = i.next();
            curve->detach();
            delete curve;
        }
    }
    zoneCurves.clear();

    // delete any existing power zone labels
    if (zoneLabels.size()) {

        QListIterator<PfPvPlotZoneLabel *> i(zoneLabels);
        while (i.hasNext()) {
            PfPvPlotZoneLabel *label = i.next();
            label->detach();
            delete label;
        }
    }
    zoneLabels.clear();

    // give up for a null ride
    if (! rideItem) return;

    const Zones *zones = rideItem->zones;
    int zone_range = rideItem->zoneRange();

    if (zone_range >= 0) {
        setCP(zones->getCP(zone_range));

        // populate the zone curves
        QList <int> zone_power = zones->getZoneLows(zone_range);
        QList <QString> zone_name = zones->getZoneNames(zone_range);
        int num_zones = zone_power.size();
        assert(zone_name.size() == num_zones);

        if (num_zones > 0) {
            QPen *pen = new QPen();
            pen->setStyle(Qt::NoPen);

            QwtArray<double> yvalues;

            // generate x values
            for (int z = 0; z < num_zones; z ++) {

                QwtPlotCurve *curve = new QwtPlotCurve(zone_name[z]);

                curve->setPen(*pen);
                QColor brush_color = zoneColor(z, num_zones);
                brush_color.setHsv(brush_color.hue(), brush_color.saturation() / 4, brush_color.value());
                curve->setBrush(brush_color);   // fill below the line
                curve->setZ(1 - 1e-6 * zone_power[z]);

                // generate data for curve
                if (z < num_zones - 1) {
                    QwtArray <double> contour_yvalues;
                    int watts = zone_power[z + 1];
                    int dwatts = (double) watts;
                    for (int i = 0; i < contour_xvalues.size(); i ++) {
                        contour_yvalues.append( (1e6 * contour_xvalues[i] < watts) ?  1e6 : dwatts / contour_xvalues[i]);
                    }
                    curve->setData(contour_xvalues, contour_yvalues);

                } else {

                    // top zone has a curve at "infinite" power
                    QwtArray <double> contour_x;
                    QwtArray <double> contour_y;
                    contour_x.append(contour_xvalues[0]);
                    contour_x.append(contour_xvalues[contour_xvalues.size() - 1]);
                    contour_y.append(1e6);
                    contour_y.append(1e6);
                    curve->setData(contour_x, contour_y);
                }

                curve->setVisible(shade_zones);
                curve->attach(this);
                zoneCurves.append(curve);
            }

            delete pen;

            // generate labels for existing zones
            for (int z = 0; z < num_zones; z ++) {
                PfPvPlotZoneLabel *label = new PfPvPlotZoneLabel(this, z);
                label->setVisible(shade_zones);
                label->attach(this);
                zoneLabels.append(label);
            }
        }
    }
}