/* * Copyright (c) 2009 Mark Liversedge (liversedge@gmail.com) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include "RealtimePlot.h" #include "Colors.h" // Power history double RealtimePwrData::x(size_t i) const { return (double)MAXSAMPLES-i; } double RealtimePwrData::y(size_t i) const { return pwrData[(pwrCur+i) < MAXSAMPLES ? (pwrCur+i) : (pwrCur+i-MAXSAMPLES)]; } size_t RealtimePwrData::size() const { return MAXSAMPLES; } //QwtSeriesData *RealtimePwrData::copy() const { return new RealtimePwrData(const_cast(this)); } void RealtimePwrData::init() { pwrCur=0; for (int i=0; i(this)); } void Realtime30PwrData::init() { pwrCur=0; for (int i=0; i<150; i++) pwrData[i]=0; } void Realtime30PwrData::addData(double v) { pwrData[pwrCur++] = v; if (pwrCur==150) pwrCur=0; } QPointF Realtime30PwrData::sample(size_t i) const { return QPointF(x(i), y(i)); } QRectF Realtime30PwrData::boundingRect() const { // TODO dgr return QRectF(-5000, 5000, 10000, 10000); } // Cadence history double RealtimeCadData::x(size_t i) const { return (double)MAXSAMPLES-i; } double RealtimeCadData::y(size_t i) const { return cadData[(cadCur+i) < MAXSAMPLES ? (cadCur+i) : (cadCur+i-MAXSAMPLES)]; } size_t RealtimeCadData::size() const { return MAXSAMPLES; } //QwtSeriesData *RealtimeCadData::copy() const { return new RealtimeCadData(const_cast(this)); } void RealtimeCadData::init() { cadCur=0; for (int i=0; i(this)); } void RealtimeSpdData::init() { spdCur=0; for (int i=0; i(this)); } void RealtimeHrData::init() { hrCur=0; for (int i=0; isetPalette(pal); axisWidget(QwtPlot::yLeft)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScale(yRight, 0, 230); // cadence / hr pal.setColor(QPalette::WindowText, GColor(CHEARTRATE)); pal.setColor(QPalette::Text, GColor(CHEARTRATE)); axisWidget(QwtPlot::yRight)->setPalette(pal); axisWidget(QwtPlot::yRight)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScale(xBottom, MAXSAMPLES, 0, 15); // time ago pal.setColor(QPalette::WindowText, GColor(CPLOTMARKER)); pal.setColor(QPalette::Text, GColor(CPLOTMARKER)); axisWidget(QwtPlot::xBottom)->setPalette(pal); axisWidget(QwtPlot::xBottom)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisScale(QwtAxisId(QwtAxis::yRight,2).id, 0, 60); // speed km/h - 60kmh on a turbo is good going! pal.setColor(QPalette::WindowText, GColor(CSPEED)); pal.setColor(QPalette::Text, GColor(CSPEED)); axisWidget(QwtAxisId(QwtAxis::yRight,2).id)->setPalette(pal); axisWidget(QwtAxisId(QwtAxis::yRight,2).id)->scaleDraw()->setTickLength(QwtScaleDiv::MajorTick, 3); setAxisLabelRotation(QwtAxisId(QwtAxis::yRight,2).id,90); setAxisLabelAlignment(QwtAxisId(QwtAxis::yRight,2).id,Qt::AlignVCenter); enableAxis(xBottom, false); // very little value and some cpu overhead enableAxis(yLeft, true); enableAxis(yRight, true); enableAxis(QwtAxisId(QwtAxis::yRight,2).id, true); // 30s Power curve pwr30Curve = new QwtPlotCurve("30s Power"); pwr30Curve->setRenderHint(QwtPlotItem::RenderAntialiased); // too cpu intensive pwr30Curve->attach(this); pwr30Curve->setYAxis(QwtPlot::yLeft); // Power curve pwrCurve = new QwtPlotCurve("Power"); //pwrCurve->setRenderHint(QwtPlotItem::RenderAntialiased); pwrCurve->setData(pwrData); pwrCurve->attach(this); pwrCurve->setYAxis(QwtPlot::yLeft); altPwrCurve = new QwtPlotCurve("Alt Power"); //pwrCurve->setRenderHint(QwtPlotItem::RenderAntialiased); altPwrCurve->setData(altPwrData); altPwrCurve->attach(this); altPwrCurve->setYAxis(QwtPlot::yLeft); // HR hrCurve = new QwtPlotCurve("HeartRate"); //hrCurve->setRenderHint(QwtPlotItem::RenderAntialiased); hrCurve->setData(hrData); hrCurve->attach(this); hrCurve->setYAxis(QwtPlot::yRight); // Cadence cadCurve = new QwtPlotCurve("Cadence"); //cadCurve->setRenderHint(QwtPlotItem::RenderAntialiased); cadCurve->setData(cadData); cadCurve->attach(this); cadCurve->setYAxis(QwtPlot::yRight); // Speed spdCurve = new QwtPlotCurve("Speed"); //spdCurve->setRenderHint(QwtPlotItem::RenderAntialiased); spdCurve->setData(spdData); spdCurve->attach(this); spdCurve->setYAxis(QwtAxisId(QwtAxis::yRight,2).id); // Load // lodCurve = new QwtPlotCurve("Load"); // //lodCurve->setRenderHint(QwtPlotItem::RenderAntialiased); // QPen lodpen = QPen(QColor(128,128,128)); // lodpen.setWidth(2.0); // lodCurve->setPen(lodpen); // QColor brush_color = QColor(124, 91, 31); // brush_color.setAlpha(64); // lodCurve->setBrush(brush_color); // fill below the line // lodCurve->setData(lodData); // lodCurve->attach(this); // lodCurve->setYAxis(QwtPlot::yLeft); static_cast(canvas())->setFrameStyle(QFrame::NoFrame); configChanged(); // set colors } void RealtimePlot::setAxisTitle(int axis, QString label) { // setup the default fonts QFont stGiles; // hoho - Chart Font St. Giles ... ok you have to be British to get this joke stGiles.fromString(appsettings->value(this, GC_FONT_CHARTLABELS, QFont().toString()).toString()); stGiles.setPointSize(appsettings->value(NULL, GC_FONT_CHARTLABELS_SIZE, 8).toInt()); QwtText title(label); title.setFont(stGiles); QwtPlot::setAxisFont(axis, stGiles); QwtPlot::setAxisTitle(axis, title); } void RealtimePlot::configChanged() { double width = appsettings->value(this, GC_LINEWIDTH, 2.0).toDouble(); setCanvasBackground(GColor(CTRAINPLOTBACKGROUND)); QPen pwr30pen = QPen(GColor(CPOWER), width, Qt::DashLine); pwr30Curve->setPen(pwr30pen); pwr30Curve->setData(pwr30Data); QPen pwrpen = QPen(GColor(CPOWER)); pwrpen.setWidth(width); pwrCurve->setPen(pwrpen); QPen apwrpen = QPen(GColor(CALTPOWER)); apwrpen.setWidth(width); altPwrCurve->setPen(apwrpen); QPen hrpen = QPen(GColor(CHEARTRATE)); hrpen.setWidth(width); hrCurve->setPen(hrpen); QPen cadpen = QPen(GColor(CCADENCE)); cadpen.setWidth(width); cadCurve->setPen(cadpen); QPen spdpen = QPen(GColor(CSPEED)); spdpen.setWidth(width); spdCurve->setPen(spdpen); } void RealtimePlot::showPower(int state) { showPowerState = state; pwrCurve->setVisible(state == Qt::Checked); enableAxis(yLeft, showAltState == Qt::Checked || showPowerState == Qt::Checked || showPow30sState == Qt::Checked); replot(); } void RealtimePlot::showPow30s(int state) { showPow30sState = state; pwr30Curve->setVisible(state == Qt::Checked); enableAxis(yLeft, showAltState == Qt::Checked || showPowerState == Qt::Checked || showPow30sState == Qt::Checked); replot(); } void RealtimePlot::showHr(int state) { showHrState = state; hrCurve->setVisible(state == Qt::Checked); enableAxis(yRight, showCadState == Qt::Checked || showHrState == Qt::Checked); replot(); } void RealtimePlot::showSpeed(int state) { showSpeedState = state; spdCurve->setVisible(state == Qt::Checked); enableAxis(QwtAxisId(QwtAxis::yRight,2).id, state == Qt::Checked); replot(); } void RealtimePlot::showCad(int state) { showCadState = state; cadCurve->setVisible(state == Qt::Checked); enableAxis(yRight, showCadState == Qt::Checked || showHrState == Qt::Checked); replot(); } void RealtimePlot::showAlt(int state) { showAltState = state; altPwrCurve->setVisible(state == Qt::Checked); enableAxis(yLeft, showAltState == Qt::Checked || showPowerState == Qt::Checked || showPow30sState == Qt::Checked); replot(); } void RealtimePlot::setSmoothing(int value) { smooth = value; }