OpenCores
URL https://opencores.org/ocsvn/modular_oscilloscope/modular_oscilloscope/trunk

Subversion Repositories modular_oscilloscope

[/] [modular_oscilloscope/] [trunk/] [sw/] [src/] [data_plot.cpp] - Rev 60

Compare with Previous | Blame | View Log

#include <stdlib.h>
#include <QFont>
#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_plot_grid.h>
#include <qwt_math.h>
#include "data_plot.h"
 
//
//  Initialize main window
//
DataPlot::DataPlot(QWidget *parent):
    QwtPlot(parent)
{
    // Disable polygon clipping
    QwtPainter::setDeviceClipping(false);
 
    // We don't need the cache here
    canvas()->setPaintAttribute(QwtPlotCanvas::PaintCached, false);
    canvas()->setPaintAttribute(QwtPlotCanvas::PaintPacked, false);
 
    canvas()->setFocusIndicator(QwtPlotCanvas::ItemFocusIndicator);
 
    //canvas()->setPaintAttribute(QwtPlotCanvas::FocusIndicator, true);
#if QT_VERSION >= 0x040000
//#ifdef 1
    /*
       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();
 
 
 
    // Insert new curves
    curveA = new QwtPlotCurve("Channel A");
    curveA->attach(this);
    curveA->setData(0,0,0);
    curveA->setAxis(QwtPlot::xBottom, QwtPlot::yLeft);
 
    curveB = new QwtPlotCurve("Channel B");
    curveB->attach(this);
    curveB->setData(0,0,0);
    curveB->setAxis(QwtPlot::xBottom, QwtPlot::yRight);
 
    triggerLine = new QwtPlotMarker;
    triggerLine->attach(this);
    triggerLine->setYAxis(QwtPlot::yLeft);
    triggerLine->setYValue(0);
    triggerLine->setLineStyle(QwtPlotMarker::HLine);
    triggerLine->setLinePen(QPen(Qt::white, 0, Qt::SolidLine));
    enableTriggerLine(false, 0);
 
    // Axis 
    // setAxisTitle(QwtPlot::xBottom, "Time/seconds");
    setAxisScale(QwtPlot::xBottom, 0, 10);
    enableAxis(QwtPlot::xBottom, true);
    //setAxisTitle(QwtPlot::xBottom, "Time [s]");
    //setAxisMaxMinor(QwtPlot::yLeft, 20);
    //setAxisMaxMajor(QwtPlot::yLeft, 10);
    enableAxis(QwtPlot::yLeft, true);
    setAxisScale(QwtPlot::yLeft, -2, 2);
    setAxisTitle(QwtPlot::yLeft, tr("A"));
    axisTitle(QwtPlot::yLeft).setFont(QFont("Serif", 8));
 
    setAxisMaxMajor(QwtPlot::xBottom, 13);
    setAxisMaxMinor(QwtPlot::xBottom, 10);
 
    enableAxis(QwtPlot::yRight, true);
    setAxisScale(QwtPlot::yRight, -2, 2);
    setAxisTitle(QwtPlot::yRight, "B");
 
 
    setAxisFont(QwtPlot::xBottom, QFont("Serif", 8));
    setAxisFont(QwtPlot::yRight, QFont("Serif", 8));
    setAxisFont(QwtPlot::yLeft, QFont("Serif", 8));
 
    // grid
    gridA = new QwtPlotGrid();
    gridA->setAxis(QwtPlot::xBottom, QwtPlot::yLeft);
 
    gridA->setMajPen(QPen(Qt::white, 0, Qt::DotLine));
    gridA->setMinPen(QPen(Qt::white, 0 , Qt::DotLine));
    gridA->attach(this);
 
 
    gridB = new QwtPlotGrid();
    gridB->setAxis(QwtPlot::xBottom, QwtPlot::yRight);
    //gridA->enableXMin(true);
    gridB->enableX(false);
    gridB->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
    gridB->setMinPen(QPen(Qt::gray, 0 , Qt::DotLine));
    gridB->attach(this);
 
    alignScales();
 
    setPaused(false);
 
}
 
//
//  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::setCurveAColor(const QColor &color)
{
    curveA->setPen(QPen(color));
    replot();
}
 
 
void DataPlot::setCurveBColor(const QColor &color)
{
    curveB->setPen(QPen(color));
    replot();
}
 
void DataPlot::setPaused(const bool &pause)
{
    paused = pause;
}
 
void DataPlot::curveAShow(const bool &show)
{
    if (show)
        curveA->attach(this);
    else
        curveA->detach();
}
 
void DataPlot::curveBShow(const bool &show)
{
    if (show)
        curveB->attach(this);
    else
        curveB->detach();
}
 
 
void DataPlot::curveAUpdate(QVector<double> time, QVector<double> chA)
{
    if (paused == false)
    {
        curveA->setData(time, chA);
        replot();
    }
 
    updateDivs();
}
 
void DataPlot::curveBUpdate(QVector<double> time, QVector<double> chB)
{
 
    if (paused == false)
    {
        curveB->setData(time, chB);
        replot();
    }
 
    updateDivs();
}
 
void DataPlot::updateDivs()
{
    QwtValueList tiks;
    // Get aDiv values
    tiks = gridA->yScaleDiv().ticks(QwtScaleDiv::MajorTick);
    aDiv = tiks.value(1, 0.0) - tiks.value(0, 0.0);
    aDiv = qAbs(aDiv);
 
    // Get bDiv values
    tiks = gridB->yScaleDiv().ticks(QwtScaleDiv::MajorTick);
    bDiv = tiks.value(1, 0.0) - tiks.value(0, 0.0);
    bDiv = qAbs(bDiv);
 
    // Get tDiv values
    tiks = gridA->xScaleDiv().ticks(QwtScaleDiv::MajorTick);
    tDiv = tiks.value(1, 0.0) - tiks.value(0, 0.0);
    tDiv = qAbs(tDiv);
 
    if (aDiv != 0.0)
        emit aScaleDivChanged(aDiv);
    else
        aDiv = 1e-5;
 
    if (bDiv != 0.0)
        emit aScaleDivChanged(bDiv);
    else
        bDiv = 1e-5;
 
    if (tDiv != 0.0)
        emit tScaleDivChanged(tDiv);
    else
        tDiv = 1/(20e6);
 
}
 
void  DataPlot::curveASetLimits(const double &down, const double &up)
{
    elementSetLimits(QwtPlot::yLeft, down, up);
}
 
 
void  DataPlot::curveAZoom(const int &value)
{
    elementZoom(QwtPlot::yLeft, value);
}
 
void  DataPlot::curveAMove(const int &value)
{
    elementZoom(QwtPlot::yLeft, value, true);
}
 
void DataPlot::curveAResetPos()
{
    double yUp, yDown;
    yUp = qAbs(axisScaleDiv(QwtPlot::yLeft)->upperBound());
    yDown = qAbs(axisScaleDiv(QwtPlot::yLeft)->lowerBound());
    if (yUp >= yDown)
        curveASetLimits(-yUp, yUp);
    else
        curveASetLimits(-yDown, yDown);
}
 
 
void  DataPlot::curveBSetLimits(const double &down, const double &up)
{
    elementSetLimits(QwtPlot::yRight, down, up);
}
 
 
void  DataPlot::curveBZoom(const int &value)
{
    elementZoom(QwtPlot::yRight, value);
}
 
 
void  DataPlot::curveBMove(const int &value)
{
    elementZoom(QwtPlot::yRight, value, true);
}
 
 
void DataPlot::curveBResetPos()
{
    double yUp, yDown;
    yUp = qAbs(axisScaleDiv(QwtPlot::yRight)->upperBound());
    yDown = qAbs(axisScaleDiv(QwtPlot::yRight)->lowerBound());
    if (yUp >= yDown)
        curveBSetLimits(-yUp, yUp);
    else
        curveBSetLimits(-yDown, yDown);
}
 
 
void DataPlot::timeSetLimits(const double &min, const double &max)
{
    elementSetLimits(QwtPlot::xBottom, min, max);
}
 
void DataPlot::timeZoom(const int &value)
{
    elementZoom(QwtPlot::xBottom, value);
}
 
void DataPlot::timeMove(const int &value)
{
    elementZoom(QwtPlot::xBottom, value, true);
}
 
void DataPlot::elementZoom(const int &axisId, const int &value, const bool &move)
{
    double up, down, div;
 
    switch(axisId)
    {
        case QwtPlot::yLeft:
            div = aDiv;
            break;
 
        case QwtPlot::yRight:
            div = bDiv;
            break;
 
        default:
            div = tDiv;
            break;
    }
 
    if (value == 0)  //auto scale
    {
        setAxisAutoScale(axisId);
    }
    else
    {
        up =  axisScaleDiv(axisId)->upperBound() - div * value/10.0 ;
        if (up >= 10.0)
            up = axisScaleDiv(axisId)->upperBound();
 
 
        down = move ? axisScaleDiv(axisId)->lowerBound() - div * value/10.0 :
               axisScaleDiv(axisId)->lowerBound() + div * value/10.0;
 
        if (down <= -10.0)
            down = axisScaleDiv(axisId)->lowerBound();
 
        setAxisScale(axisId, down, up);
    }
 
    updateDivs();
    replot();
}
 
 
void DataPlot::elementSetLimits(const int &axisId, const double &min, const double &max)
{
    if (min == 0 && max == 0)
        setAxisAutoScale(axisId);
    else
        setAxisScale(axisId,  \
                     min, \
                     max);
    replot();
    updateDivs();
}
 
 
 
void DataPlot::curveAShowGrid(const bool &on)
{
    elementShowGrid(QwtPlot::yLeft, on);
}
 
 
void DataPlot::curveBShowGrid(const bool &on)
{
    elementShowGrid(QwtPlot::yRight, on);
}
 
 
void DataPlot::timeShowGrid(const bool &on)
{
    elementShowGrid(QwtPlot::xBottom, on);
}
 
void DataPlot::elementShowGrid(const int &axisId, const bool &on)
{
    switch(axisId)
    {
        case QwtPlot::yLeft:
            gridA->enableY(on);
            break;
 
        case QwtPlot::yRight:
            gridB->enableY(on);
            break;
 
        default:
            gridA->enableX(on);
            break;
    }
    replot();
}
 
 
 
void DataPlot::enableTriggerLine(const bool &on, const  int &channel)
{
    int axisId;
    switch(channel)
    {
        case 1:
            axisId = QwtPlot::yRight;
            break;
 
        default:
            axisId = QwtPlot::yLeft;
            break;
    }
 
    triggerLine->setVisible(on);
    if(on)
    {
        triggerLine->show();
        triggerLine->setAxis(QwtPlot::xBottom, axisId);
        replot();
    }
    else
    {
        triggerLine->hide();
        replot();
    }
}
 
void DataPlot::setTriggerLineValue(double val)
{
    triggerLine->setYValue(val);
    replot();
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.