Sophie

Sophie

distrib > Mandriva > cooker > i586 > by-pkgid > 76bdad05b5dca2a491582dbec0713d55 > files > 211

libqwt-devel-6.0.1-2.i586.rpm

#include <qglobal.h>
#include <qwt_painter.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_layout.h>
#include <qwt_scale_widget.h>
#include <qwt_scale_draw.h>
#include "plot.h"
#include "circularbuffer.h"
#include "settings.h"

static double wave(double x) 
{
    const double period = 1.0;
    const double c = 5.0;

    double v = ::fmod(x, period);

    const double amplitude = qAbs(x - qRound(x / c) * c) / ( 0.5 * c );
    v = amplitude * qSin(v / period * 2 * M_PI);

    return v;
}

static double noise(double)
{
    return 2.0 * ( qrand() / ((double)RAND_MAX + 1) ) - 1.0;
}

Plot::Plot(QWidget *parent):
    QwtPlot(parent),
    d_interval(10.0), // seconds
    d_timerId(-1)
{
    // Assign a title
    setTitle("Testing Refresh Rates");

    setCanvasBackground(Qt::white);

    alignScales();

    // Insert grid
    d_grid = new QwtPlotGrid();
    d_grid->attach(this);

    // Insert curve
    d_curve = new QwtPlotCurve("Data Moving Right");
    d_curve->setPen(QPen(Qt::black));
    d_curve->setData(new CircularBuffer(d_interval, 10));
    d_curve->attach(this);

    // Axis 
    setAxisTitle(QwtPlot::xBottom, "Seconds");
    setAxisScale(QwtPlot::xBottom, -d_interval, 0.0);

    setAxisTitle(QwtPlot::yLeft, "Values");
    setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
    
    d_clock.start();

    setSettings(d_settings);
}

//
//  Set a plain canvas frame and align the scales to it
//
void Plot::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);
    }

    plotLayout()->setAlignCanvasToScales(true);
}

void Plot::setSettings(const Settings &s)
{
    if ( d_timerId >= 0 )
        killTimer(d_timerId);

    d_timerId = startTimer(s.updateInterval);

    d_grid->setPen(s.grid.pen);
    d_grid->setVisible(s.grid.pen.style() != Qt::NoPen);

    CircularBuffer *buffer = (CircularBuffer *)d_curve->data();
    if ( s.curve.numPoints != buffer->size() ||
        s.curve.functionType != d_settings.curve.functionType )
    {

        switch(s.curve.functionType)
        {
            case Settings::Wave:
                buffer->setFunction(wave);
                break;
            case Settings::Noise:
                buffer->setFunction(noise);
                break;
            default:
                buffer->setFunction(NULL);
        }

        buffer->fill(d_interval, s.curve.numPoints);
    }

    d_curve->setPen(s.curve.pen);
    d_curve->setBrush(s.curve.brush);

    d_curve->setPaintAttribute(QwtPlotCurve::ClipPolygons,
        s.curve.paintAttributes & QwtPlotCurve::ClipPolygons);
    d_curve->setRenderHint(QwtPlotCurve::RenderAntialiased,
        s.curve.renderHint & QwtPlotCurve::RenderAntialiased);

    canvas()->setAttribute(Qt::WA_PaintOnScreen, s.canvas.paintOnScreen);

    canvas()->setPaintAttribute(
        QwtPlotCanvas::BackingStore, s.canvas.useBackingStore);
    canvas()->setPaintAttribute(
        QwtPlotCanvas::ImmediatePaint, s.canvas.immediatePaint);

    QwtPainter::setPolylineSplitting(s.curve.lineSplitting);

    d_settings = s;
}

void Plot::timerEvent(QTimerEvent *)
{
    CircularBuffer *buffer = (CircularBuffer *)d_curve->data();
    buffer->setReferenceTime(d_clock.elapsed() / 1000.0);

    switch(d_settings.updateType)
    {
        case Settings::RepaintCanvas:
        {
            // the axes in this example doesn't change. So all we need to do
            // is to repaint the canvas.

            canvas()->replot();
            break;
        }
        default:
        {
            replot();
        }
    }
}