Example #1
0
PerfPlot::PerfPlot() : STScurve(NULL), LTScurve(NULL), SBcurve(NULL), DAYcurve(NULL)
{
    xsd = new PPTimeScaleDraw(QDateTime());
    xsd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::xBottom, xsd);

    insertLegend(new QwtLegend(), QwtPlot::BottomLegend);
    setAxisTitle(yLeft, tr("Exponentially Weighted Average Stress"));
    setAxisTitle(xBottom, tr("Time (days)"));
    setAxisTitle(yRight, tr("Daily Stress"));
    enableAxis(yRight, true);
    static_cast<QwtPlotCanvas*>(canvas())->setFrameStyle(QFrame::NoFrame);

    setAxisMaxMinor(xBottom, 0);
    setAxisMaxMinor(yLeft, 0);
    setAxisMaxMinor(yRight, 0);

    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::yLeft, sd);

    sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::yRight, sd);

    grid = new QwtPlotGrid();
    grid->attach(this);

    configUpdate();
}
Example #2
0
void
HrPwPlot::configChanged(qint32)
{
    // setColors bg
    setCanvasBackground(GColor(CPLOTBACKGROUND));

    QPalette palette;
    palette.setBrush(QPalette::Window, QBrush(GColor(CPLOTBACKGROUND)));
    palette.setBrush(QPalette::Background, QBrush(GColor(CPLOTBACKGROUND)));
    palette.setColor(QPalette::WindowText, GColor(CPLOTMARKER));
    palette.setColor(QPalette::Text, GColor(CPLOTMARKER));
    setPalette(palette);

    // tick draw
    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->setTickLength(QwtScaleDiv::MinorTick, 0);
    setAxisScaleDraw(QwtPlot::xBottom, sd);
    axisWidget(QwtPlot::xBottom)->setPalette(palette);

    sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->enableComponent(QwtScaleDraw::Ticks, false);
    sd->enableComponent(QwtScaleDraw::Backbone, false);
    setAxisScaleDraw(QwtPlot::yLeft, sd);
    axisWidget(QwtPlot::yLeft)->setPalette(palette);

    QPen gridPen;
    gridPen.setColor(GColor(CPLOTGRID));
    grid->setPen(gridPen);
}
Example #3
0
ScatterPlot::ScatterPlot(Context *context) : context(context)
{
    setAutoDelete(false); // no don't delete on detach !
    curve = NULL;
    curve2 = NULL;
    hover = NULL;
    hover2 = NULL;
    grid = NULL;
    ride = NULL;
    static_cast<QwtPlotCanvas*>(canvas())->setFrameStyle(QFrame::NoFrame);

    setAxisMaxMinor(xBottom, 0);
    setAxisMaxMinor(yLeft, 0);

    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::xBottom, sd);

    sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->enableComponent(QwtScaleDraw::Ticks, false);
    sd->enableComponent(QwtScaleDraw::Backbone, false);
    setAxisScaleDraw(QwtPlot::yLeft, sd);

    connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
    connect(context, SIGNAL(intervalHover(IntervalItem*)), this, SLOT(intervalHover(IntervalItem*)));

    // lets watch the mouse move...
    new mouseTracker(this);

    configChanged(CONFIG_APPEARANCE | CONFIG_GENERAL); // use latest wheelsize/cranklength and colors
}
Example #4
0
void BarChart::setOrientation( int o )
{
    const Qt::Orientation orientation =
        ( o == 0 ) ? Qt::Vertical : Qt::Horizontal;

    int axis1 = QwtPlot::xBottom;
    int axis2 = QwtPlot::yLeft;

    if ( orientation == Qt::Horizontal )
        qSwap( axis1, axis2 );

    d_barChartItem->setOrientation( orientation );

    setAxisTitle( axis1, "Distros" );
    setAxisMaxMinor( axis1, 3 );
    setAxisScaleDraw( axis1, new DistroScaleDraw( orientation, d_distros ) );

    setAxisTitle( axis2, "Hits per day ( HPD )" );
    setAxisMaxMinor( axis2, 3 );

    QwtScaleDraw *scaleDraw = new QwtScaleDraw();
    scaleDraw->setTickLength( QwtScaleDiv::MediumTick, 4 );
    setAxisScaleDraw( axis2, scaleDraw );

    plotLayout()->setCanvasMargin( 0 );
    replot();
}
Example #5
0
void SaxsviewImage::setMinorTicksVisible(bool on) {
  //
  // There is a ScaleDraw component "Ticks", like the "Labels" used
  // for the visibility of the labels, but "Ticks" shows/hides
  // all ticks, not selected ones. Here we "disable" tick marks by
  // setting their size to 0 if disabled, and their default value
  // when enabled.
  //
  for (int i = QwtPlot::yLeft; i < QwtPlot::axisCnt; ++i) {
    QwtScaleDraw *draw = p->scales[i]->scaleDraw();
    draw->setTickLength(QwtScaleDiv::MinorTick, on ? 4 : 0);
    draw->setTickLength(QwtScaleDiv::MediumTick, on ? 6 : 0);
  }

  replot();
}
Example #6
0
void SaxsviewImage::setMajorTicksVisible(bool on) {
  for (int i = QwtPlot::yLeft; i < QwtPlot::axisCnt; ++i) {
    QwtScaleDraw *draw = p->scales[i]->scaleDraw();
    draw->setTickLength(QwtScaleDiv::MajorTick, on ? 8 : 0);
  }

  replot();
}
Example #7
0
CpintPlot::CpintPlot(Context *context, QString p, const Zones *zones, bool rangemode) :
    path(p),
    thisCurve(NULL),
    CPCurve(NULL),
    allCurve(NULL),
    zones(zones),
    series(RideFile::watts),
    context(context),
    current(NULL),
    bests(NULL),
    isFiltered(false),
    shadeMode(2),
    rangemode(rangemode)
{
    setAutoFillBackground(true);

    setAxisTitle(xBottom, tr("Interval Length"));
    LogTimeScaleDraw *ld = new LogTimeScaleDraw;

    ld->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(xBottom, ld);
    setAxisScaleEngine(xBottom, new QwtLogScaleEngine);
    QwtScaleDiv div( (double)0.017, (double)60 );
    div.setTicks(QwtScaleDiv::MajorTick, LogTimeScaleDraw::ticks);
    setAxisScaleDiv(QwtPlot::xBottom, div);

    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->enableComponent(QwtScaleDraw::Ticks, false);
    sd->enableComponent(QwtScaleDraw::Backbone, false);
    setAxisScaleDraw(yLeft, sd);
    setAxisTitle(yLeft, tr("Average Power (watts)"));
    setAxisMaxMinor(yLeft, 0);
    plotLayout()->setAlignCanvasToScales(true);

    //grid = new QwtPlotGrid();
    //grid->enableX(true);
    //grid->attach(this);

    curveTitle.attach(this);
    curveTitle.setXValue(5);
    curveTitle.setYValue(60);
    curveTitle.setLabel(QwtText("", QwtText::PlainText)); // default to no title

    zoomer = new penTooltip(static_cast<QwtPlotCanvas*>(this->canvas()));
    zoomer->setMousePattern(QwtEventPattern::MouseSelect1,
                            Qt::LeftButton, Qt::ShiftModifier);

    canvasPicker = new LTMCanvasPicker(this);
    static_cast<QwtPlotCanvas*>(canvas())->setFrameStyle(QFrame::NoFrame);
    connect(canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), this, SLOT(pointHover(QwtPlotCurve*, int)));

    configChanged(); // apply colors

    ecp = new ExtendedCriticalPower(context);
    extendedCPCurve4 = NULL;
    extendedCurveTitle2 = NULL;
}
Example #8
0
void
PowerHist::setYMax()
{
    double MaxY = curve->maxYValue();
    if (MaxY < curveSelected->maxYValue()) MaxY = curveSelected->maxYValue();
    static const double tmin = 1.0/60;
    setAxisScale(yLeft, (lny ? tmin : 0.0), MaxY * 1.1);

    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::yLeft, sd);
}
Example #9
0
ScatterPlot::ScatterPlot(Context *context) : context(context)
{
    setInstanceName("2D Plot");
    all = NULL;
    grid = NULL;
    canvas()->setFrameStyle(QFrame::NoFrame);

    setAxisMaxMinor(xBottom, 0);
    setAxisMaxMinor(yLeft, 0);

    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::xBottom, sd);

    sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::yLeft, sd);

    connect(context, SIGNAL(configChanged()), this, SLOT(configChanged()));
    configChanged(); // use latest colors etc
}
Example #10
0
ScatterPlot::ScatterPlot(Context *context) : context(context)
{
    all = NULL;
    grid = NULL;
    static_cast<QwtPlotCanvas*>(canvas())->setFrameStyle(QFrame::NoFrame);

    setAxisMaxMinor(xBottom, 0);
    setAxisMaxMinor(yLeft, 0);

    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(QwtPlot::xBottom, sd);

    sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->enableComponent(QwtScaleDraw::Ticks, false);
    sd->enableComponent(QwtScaleDraw::Backbone, false);
    setAxisScaleDraw(QwtPlot::yLeft, sd);

    connect(context, SIGNAL(configChanged()), this, SLOT(configChanged()));
    configChanged(); // use latest colors etc
}
Example #11
0
CpintPlot::CpintPlot(Context *context, QString p, const Zones *zones) :
    path(p),
    thisCurve(NULL),
    CPCurve(NULL),
    allCurve(NULL),
    zones(zones),
    series(RideFile::watts),
    context(context),
    current(NULL),
    bests(NULL),
    isFiltered(false),
    shadeMode(2)
{
    setInstanceName("CP Plot");
    assert(!USE_T0_IN_CP_MODEL); // doesn't work with energyMode=true

    setAxisTitle(xBottom, tr("Interval Length"));
    LogTimeScaleDraw *ld = new LogTimeScaleDraw;
    ld->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(xBottom, ld);
    setAxisScaleEngine(xBottom, new LogTimeScaleEngine);
    setAxisScale(xBottom, (double)0.017, (double)60);

    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(yLeft, sd);
    setAxisTitle(yLeft, tr("Average Power (watts)"));
    setAxisMaxMinor(yLeft, 0);
    plotLayout()->setAlignCanvasToScales(true);

    grid = new QwtPlotGrid();
    grid->enableX(true);
    grid->attach(this);

    curveTitle.attach(this);
    curveTitle.setXValue(5);
    curveTitle.setYValue(20);
    curveTitle.setLabel(QwtText("", QwtText::PlainText)); // default to no title

    zoomer = new penTooltip(this->canvas());
    zoomer->setMousePattern(QwtEventPattern::MouseSelect1,
                            Qt::LeftButton, Qt::ShiftModifier);

    canvasPicker = new LTMCanvasPicker(this);
    canvas()->setFrameStyle(QFrame::NoFrame);
    connect(canvasPicker, SIGNAL(pointHover(QwtPlotCurve*, int)), this, SLOT(pointHover(QwtPlotCurve*, int)));

    configChanged(); // apply colors
}
Example #12
0
MUPlot::MUPlot(MUWidget *muw, CriticalPowerWindow *parent, Context *context) 
       : QwtPlot(parent), QwtSyntheticPointData(MUN), 
         context(context), muw(muw), parent(parent), modelCurve(NULL), slowCurve(NULL), fastCurve(NULL), mmpCurve(NULL)
{

    // initalise all the model stufff
    // probably abstract this out later
    muSet = NULL;
    slowHandle = NULL;
    slowLine = NULL;
    slowDrag = false;
    fastHandle = NULL;
    fastLine = NULL;
    fastDrag = false;

    setAutoDelete(false);
    setAutoFillBackground(true);
    static_cast<QwtPlotCanvas*>(canvas())->setFrameStyle(QFrame::NoFrame);

    // left yAxis scale prettify
    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->enableComponent(QwtScaleDraw::Ticks, false);
    sd->enableComponent(QwtScaleDraw::Backbone, false);
    setAxisScaleDraw(yLeft, sd);
    setAxisTitle(yLeft, tr("w(x)"));
    setAxisMaxMinor(yLeft, 0);
    plotLayout()->setAlignCanvasToScales(true);

    // 0.5 increments on bottom axis
    QwtValueList ytick[QwtScaleDiv::NTickTypes];
    for (double i=0.0f; i<=10.0f; i+= 1.0)
        ytick[QwtScaleDiv::MajorTick]<<i;
    setAxisScaleDiv(yLeft,QwtScaleDiv(0.0f,10.0f,ytick));

    // bottom xAxis scale prettify
    sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->enableComponent(QwtScaleDraw::Ticks, false);
    sd->enableComponent(QwtScaleDraw::Backbone, false);
    setAxisScaleDraw(xBottom, sd);
    setAxisTitle(xBottom, tr("Motor Unit, x"));
    setAxisMaxMinor(xBottom, 0);

    // 0.2 increments on bottom axis
    QwtValueList xtick[QwtScaleDiv::NTickTypes];
    for (double i=0.0f; i<=1.0f; i+= 0.2)
        xtick[QwtScaleDiv::MajorTick]<<i;
    setAxisScaleDiv(xBottom,QwtScaleDiv(0.0f,1.0f,xtick));

    // now color everything we created
    configChanged(CONFIG_APPEARANCE);

    // set to a 2 Normal Model
    setModel(2);

    // set mouse tracker
    parent->setMouseTracking(true);
    installEventFilter(parent);
    new muMouseTracker(this);
}
Example #13
0
PfPvPlot::PfPvPlot(Context *context)
    : rideItem (NULL), context(context), hover(NULL), cp_ (0), cad_ (85), cl_ (0.175), shade_zones(true)
{
    static_cast<QwtPlotCanvas*>(canvas())->setFrameStyle(QFrame::NoFrame);

    setAutoFillBackground(true);
    setAxisTitle(yLeft, tr("Average Effective Pedal Force (N)"));
    setAxisScale(yLeft, 0, 600);
    setAxisTitle(xBottom, tr("Circumferential Pedal Velocity (m/s)"));
    setAxisScale(xBottom, 0, 3);
    setAxisMaxMinor(yLeft, 0);
    setAxisMaxMinor(xBottom, 0);
    QwtScaleDraw *sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    setAxisScaleDraw(xBottom, sd);
    sd = new QwtScaleDraw;
    sd->setTickLength(QwtScaleDiv::MajorTick, 3);
    sd->enableComponent(QwtScaleDraw::Ticks, false);
    sd->enableComponent(QwtScaleDraw::Backbone, false);
    setAxisScaleDraw(yLeft, sd);

    mX = new QwtPlotMarker();
    mX->setLineStyle(QwtPlotMarker::VLine);
    mX->attach(this);

    mY = new QwtPlotMarker();
    mY->setLineStyle(QwtPlotMarker::HLine);
    mY->attach(this);

    cpCurve = new QwtPlotCurve();
    cpCurve->setRenderHint(QwtPlotItem::RenderAntialiased);
    cpCurve->attach(this);

    curve = new QwtPlotCurve();
    curve->attach(this);

    cl_ = appsettings->value(this, GC_CRANKLENGTH).toDouble() / 1000.0;

    // markup timeInQuadrant
    tiqMarker[0] = new QwtPlotMarker(); tiqMarker[0]->attach(this);
    tiqMarker[0]->setXValue(2.9);
    tiqMarker[0]->setYValue(580);

    tiqMarker[1] = new QwtPlotMarker(); tiqMarker[1]->attach(this);
    tiqMarker[1]->setXValue(0.1);
    tiqMarker[1]->setYValue(580);

    tiqMarker[2] = new QwtPlotMarker(); tiqMarker[2]->attach(this);
    tiqMarker[2]->setXValue(0.1);
    tiqMarker[2]->setYValue(10);

    tiqMarker[3] = new QwtPlotMarker(); tiqMarker[3]->attach(this);
    tiqMarker[3]->setXValue(2.9);
    tiqMarker[3]->setYValue(10);

    merge_intervals = false;
    frame_intervals = true;

    // only default on first time through, after this the user may have adjusted
    if (appsettings->value(this, GC_SHADEZONES, true).toBool()==false) shade_zones = false;
    else shade_zones = true;

    configChanged();

    recalc();
}
Example #14
0
void
PowerHist::recalc(bool force)
{
    QVector<unsigned int> *array = NULL;
    QVector<unsigned int> *selectedArray = NULL;
    int arrayLength = 0;

    // lets make sure we need to recalculate
    if (force == false &&
        LASTsource == source &&
        LASTcache == cache &&
        LASTrideItem == rideItem &&
        LASTseries == series &&
        LASTshade == shade &&
        LASTuseMetricUnits == context->athlete->useMetricUnits &&
        LASTlny == lny &&
        LASTzoned == zoned &&
        LASTbinw == binw &&
        LASTwithz == withz &&
        LASTdt == dt &&
        LASTabsolutetime == absolutetime) {
        return; // nothing has changed

    } else {

        // remember for next time
        LASTsource = source;
        LASTcache = cache;
        LASTrideItem = rideItem;
        LASTseries = series;
        LASTshade = shade;
        LASTuseMetricUnits = context->athlete->useMetricUnits;
        LASTlny = lny;
        LASTzoned = zoned;
        LASTbinw = binw;
        LASTwithz = withz;
        LASTdt = dt;
        LASTabsolutetime = absolutetime;
    }


    if (source == Ride && !rideItem) return;

    // make sure the interval length is set if not plotting metrics
    if (source != Metric && dt <= 0) return;

    if (source == Metric) {

        // we use the metricArray
        array = &metricArray;
        arrayLength = metricArray.size();
        selectedArray = NULL;

    } else if (series == RideFile::watts && zoned == false) {

        array = &wattsArray;
        arrayLength = wattsArray.size();
        selectedArray = &wattsSelectedArray;

    } else if ((series == RideFile::watts || series == RideFile::wattsKg) && zoned == true) {

        array = &wattsZoneArray;
        arrayLength = wattsZoneArray.size();
        selectedArray = &wattsZoneSelectedArray;

    } else if (series == RideFile::aPower && zoned == false) {

        array = &aPowerArray;
        arrayLength = aPowerArray.size();
        selectedArray = &aPowerSelectedArray;

    } else if (series == RideFile::wattsKg && zoned == false) {

        array = &wattsKgArray;
        arrayLength = wattsKgArray.size();
        selectedArray = &wattsKgSelectedArray;

    } else if (series == RideFile::nm) {

        array = &nmArray;
        arrayLength = nmArray.size();
        selectedArray = &nmSelectedArray;

    } else if (series == RideFile::hr && zoned == false) {

        array = &hrArray;
        arrayLength = hrArray.size();
        selectedArray = &hrSelectedArray;

    } else if (series == RideFile::hr && zoned == true) {

        array = &hrZoneArray;
        arrayLength = hrZoneArray.size();
        selectedArray = &hrZoneSelectedArray;

    } else if (series == RideFile::kph) {

        array = &kphArray;
        arrayLength = kphArray.size();
        selectedArray = &kphSelectedArray;

    } else if (series == RideFile::cad) {
        array = &cadArray;
        arrayLength = cadArray.size();
        selectedArray = &cadSelectedArray;
    }

    RideFile::SeriesType baseSeries = (series == RideFile::wattsKg) ? RideFile::watts : series;

    // null curve please -- we have no data!
    if (!array || arrayLength == 0 || (source == Ride && !rideItem->ride()->isDataPresent(baseSeries))) {
        // create empty curves when no data
        const double zero = 0;
        curve->setData(&zero, &zero, 0);
        curveSelected->setData(&zero, &zero, 0);
        updatePlot();
        return;
    }

    // binning of data when not zoned - we can't zone for series besides
    // watts and hr so ignore zoning for those data series
    if (zoned == false || (zoned == true && (series != RideFile::watts && series != RideFile::wattsKg && series != RideFile::hr))) {

        // we add a bin on the end since the last "incomplete" bin
        // will be dropped otherwise
        int count = int(ceil((arrayLength - 1) / (binw)))+1;

        // allocate space for data, plus beginning and ending point
        QVector<double> parameterValue(count+2, 0.0);
        QVector<double> totalTime(count+2, 0.0);
        QVector<double> totalTimeSelected(count+2, 0.0);
        int i;
        for (i = 1; i <= count; ++i) {
            double high = i * round(binw/delta);
            double low = high - round(binw/delta);
            if (low==0 && !withz) low++;
            parameterValue[i] = high*delta;
            totalTime[i]  = 1e-9;  // nonzero to accomodate log plot
            totalTimeSelected[i] = 1e-9;  // nonzero to accomodate log plot
            while (low < high && low<arrayLength) {
                if (selectedArray && (*selectedArray).size()>low)
                    totalTimeSelected[i] += dt * (*selectedArray)[low];
                totalTime[i] += dt * (*array)[low++];
            }
        }
        totalTime[i] = 1e-9;       // nonzero to accomodate log plot
        totalTimeSelected[i] = 1e-9;       // nonzero to accomodate log plot
        parameterValue[i] = i * delta * binw;
        totalTime[0] = 1e-9;
        totalTimeSelected[0] = 1e-9;
        parameterValue[0] = 0;

        // convert vectors from absolute time to percentage
        // if the user has selected that
        if (!absolutetime) {
            percentify(totalTime, 1);
            percentify(totalTimeSelected, 1);
        }

        curve->setData(parameterValue.data(), totalTime.data(), count + 2);
        curveSelected->setData(parameterValue.data(), totalTimeSelected.data(), count + 2);

        QwtScaleDraw *sd = new QwtScaleDraw;
        sd->setTickLength(QwtScaleDiv::MajorTick, 3);
        setAxisScaleDraw(QwtPlot::xBottom, sd);

        // HR typically starts at 80 or so, rather than zero
        // lets crop the chart so we can focus on the data
        // if we're working with HR data...
        minX=0;
        if (!withz && series == RideFile::hr) {
            for (int i=1; i<hrArray.size(); i++) {
                if (hrArray[i] > 0.1) {
                    minX = i;
                    break;
                }
            }
        }
        setAxisScale(xBottom, minX, parameterValue[count + 1]);

        // we only do zone labels when using absolute values
        refreshZoneLabels();
        refreshHRZoneLabels();

    } else {

        // we're not binning instead we are prettyfing the columnar
        // display in much the same way as the weekly summary workds
        // Each zone column will have 4 points
        QVector<double> xaxis (array->size() * 4);
        QVector<double> yaxis (array->size() * 4);
        QVector<double> selectedxaxis (selectedArray->size() * 4);
        QVector<double> selectedyaxis (selectedArray->size() * 4);

        // samples to time
        for (int i=0, offset=0; i<array->size(); i++) {

            double x = (double) i - 0.5;
            double y = dt * (double)(*array)[i];

            xaxis[offset] = x +0.05;
            yaxis[offset] = 0;
            offset++;
            xaxis[offset] = x+0.05;
            yaxis[offset] = y;
            offset++;
            xaxis[offset] = x+0.95;
            yaxis[offset] = y;
            offset++;
            xaxis[offset] = x +0.95;
            yaxis[offset] = 0;
            offset++;
        }

        for (int i=0, offset=0; i<selectedArray->size(); i++) {
            double x = (double)i - 0.5;
            double y = dt * (double)(*selectedArray)[i];

            selectedxaxis[offset] = x +0.05;
            selectedyaxis[offset] = 0;
            offset++;
            selectedxaxis[offset] = x+0.05;
            selectedyaxis[offset] = y;
            offset++;
            selectedxaxis[offset] = x+0.95;
            selectedyaxis[offset] = y;
            offset++;
            selectedxaxis[offset] = x +0.95;
            selectedyaxis[offset] = 0;
            offset++;
        }

        if (!absolutetime) {
            percentify(yaxis, 2);
            percentify(selectedyaxis, 2);
        }

        // set those curves
        curve->setData(xaxis.data(), yaxis.data(), xaxis.size());
        curveSelected->setData(selectedxaxis.data(), selectedyaxis.data(), selectedxaxis.size());

        // zone scale draw
        if ((series == RideFile::watts || series == RideFile::wattsKg) && zoned && rideItem && rideItem->zones) {
            setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(rideItem->zones, rideItem->zoneRange()));
            if (rideItem->zoneRange() >= 0)
                setAxisScale(QwtPlot::xBottom, -0.99, rideItem->zones->numZones(rideItem->zoneRange()), 1);
            else
                setAxisScale(QwtPlot::xBottom, -0.99, 0, 1);
        }

        // hr scale draw
        int hrRange;
        if (series == RideFile::hr && zoned && rideItem && context->athlete->hrZones() &&
            (hrRange=context->athlete->hrZones()->whichRange(rideItem->dateTime.date())) != -1) {
            setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones(), hrRange));

            if (hrRange >= 0)
                setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones()->numZones(hrRange), 1);
            else
                setAxisScale(QwtPlot::xBottom, -0.99, 0, 1);
        }

        // watts zoned for a time range
        if (source == Cache && zoned && (series == RideFile::watts || series == RideFile::wattsKg) && context->athlete->zones()) {
            setAxisScaleDraw(QwtPlot::xBottom, new ZoneScaleDraw(context->athlete->zones(), 0));
            if (context->athlete->zones()->getRangeSize())
                setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->zones()->numZones(0), 1); // use zones from first defined range
        }

        // hr zoned for a time range
        if (source == Cache && zoned && series == RideFile::hr && context->athlete->hrZones()) {
            setAxisScaleDraw(QwtPlot::xBottom, new HrZoneScaleDraw(context->athlete->hrZones(), 0));
            if (context->athlete->hrZones()->getRangeSize())
                setAxisScale(QwtPlot::xBottom, -0.99, context->athlete->hrZones()->numZones(0), 1); // use zones from first defined range
        }

        setAxisMaxMinor(QwtPlot::xBottom, 0);
    }

    setYMax();
    configChanged(); // setup the curve colors to appropriate values
    updatePlot();
}