mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-14 00:28:42 +00:00
148 lines
3.6 KiB
C++
148 lines
3.6 KiB
C++
#include <stdlib.h>
|
|
#include <qwt_painter.h>
|
|
#include <qwt_plot_canvas.h>
|
|
#include <qwt_plot_marker.h>
|
|
#include <qwt_plot_curve.h>
|
|
#include <qwt_scale_widget.h>
|
|
#include <qwt_legend.h>
|
|
#include <qwt_scale_draw.h>
|
|
#include <qwt_math.h>
|
|
#include "data_plot.h"
|
|
|
|
//
|
|
// Initialize main window
|
|
//
|
|
DataPlot::DataPlot(QWidget *parent):
|
|
QwtPlot(parent),
|
|
d_interval(0),
|
|
d_timerId(-1)
|
|
{
|
|
// Disable polygon clipping
|
|
QwtPainter::setDeviceClipping(false);
|
|
|
|
// We don't need the cache here
|
|
canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
|
|
canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
|
|
|
|
#if QT_VERSION >= 0x040000
|
|
#ifdef Q_WS_X11
|
|
/*
|
|
Qt::WA_PaintOnScreen is only supported for X11, but leads
|
|
to substantial bugs with Qt 4.2.x/Windows
|
|
*/
|
|
canvas()->setAttribute(Qt::WA_PaintOnScreen, true);
|
|
#endif
|
|
#endif
|
|
|
|
alignScales();
|
|
|
|
// Initialize data
|
|
for (int i = 0; i< PLOT_SIZE; i++)
|
|
{
|
|
d_x[i] = 0.5 * i; // time axis
|
|
d_y[i] = 0;
|
|
d_z[i] = 0;
|
|
}
|
|
|
|
// Assign a title
|
|
setTitle("A Test for High Refresh Rates");
|
|
insertLegend(new QwtLegend(), QwtPlot::BottomLegend);
|
|
|
|
// Insert new curves
|
|
QwtPlotCurve *cRight = new QwtPlotCurve("Data Moving Right");
|
|
cRight->attach(this);
|
|
|
|
QwtPlotCurve *cLeft = new QwtPlotCurve("Data Moving Left");
|
|
cLeft->attach(this);
|
|
|
|
// Set curve styles
|
|
cRight->setPen(QPen(Qt::red));
|
|
cLeft->setPen(QPen(Qt::blue));
|
|
|
|
// Attach (don't copy) data. Both curves use the same x array.
|
|
cRight->setRawData(d_x, d_y, PLOT_SIZE);
|
|
cLeft->setRawData(d_x, d_z, PLOT_SIZE);
|
|
|
|
#if 0
|
|
// Insert zero line at y = 0
|
|
QwtPlotMarker *mY = new QwtPlotMarker();
|
|
mY->setLabelAlignment(Qt::AlignRight|Qt::AlignTop);
|
|
mY->setLineStyle(QwtPlotMarker::HLine);
|
|
mY->setYValue(0.0);
|
|
mY->attach(this);
|
|
#endif
|
|
|
|
// Axis
|
|
setAxisTitle(QwtPlot::xBottom, "Time/seconds");
|
|
setAxisScale(QwtPlot::xBottom, 0, 100);
|
|
|
|
setAxisTitle(QwtPlot::yLeft, "Values");
|
|
setAxisScale(QwtPlot::yLeft, -1.5, 1.5);
|
|
|
|
setTimerInterval(0.0);
|
|
}
|
|
|
|
//
|
|
// Set a plain canvas frame and align the scales to it
|
|
//
|
|
void DataPlot::alignScales()
|
|
{
|
|
// The code below shows how to align the scales to
|
|
// the canvas frame, but is also a good example demonstrating
|
|
// why the spreaded API needs polishing.
|
|
|
|
canvas()->setFrameStyle(QFrame::Box | QFrame::Plain );
|
|
canvas()->setLineWidth(1);
|
|
|
|
for ( int i = 0; i < QwtPlot::axisCnt; i++ )
|
|
{
|
|
QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(i);
|
|
if ( scaleWidget )
|
|
scaleWidget->setMargin(0);
|
|
|
|
QwtScaleDraw *scaleDraw = (QwtScaleDraw *)axisScaleDraw(i);
|
|
if ( scaleDraw )
|
|
scaleDraw->enableComponent(QwtAbstractScaleDraw::Backbone, false);
|
|
}
|
|
}
|
|
|
|
void DataPlot::setTimerInterval(double ms)
|
|
{
|
|
d_interval = qRound(ms);
|
|
|
|
if ( d_timerId >= 0 )
|
|
{
|
|
killTimer(d_timerId);
|
|
d_timerId = -1;
|
|
}
|
|
if (d_interval >= 0 )
|
|
d_timerId = startTimer(d_interval);
|
|
}
|
|
|
|
// Generate new values
|
|
void DataPlot::timerEvent(QTimerEvent *)
|
|
{
|
|
static double phase = 0.0;
|
|
|
|
if (phase > (M_PI - 0.0001))
|
|
phase = 0.0;
|
|
|
|
// y moves from left to right:
|
|
// Shift y array right and assign new value to y[0].
|
|
|
|
for ( int i = PLOT_SIZE - 1; i > 0; i-- )
|
|
d_y[i] = d_y[i-1];
|
|
d_y[0] = sin(phase) * (-1.0 + 2.0 * double(rand()) / double(RAND_MAX));
|
|
|
|
for ( int j = 0; j < PLOT_SIZE - 1; j++ )
|
|
d_z[j] = d_z[j+1];
|
|
|
|
d_z[PLOT_SIZE - 1] = 0.8 - (2.0 * phase/M_PI) + 0.4 *
|
|
double(rand()) / double(RAND_MAX);
|
|
|
|
// update the display
|
|
replot();
|
|
|
|
phase += M_PI * 0.02;
|
|
}
|