mirror of https://github.com/jhol/qtdmm.git
882 lines
19 KiB
C++
882 lines
19 KiB
C++
//======================================================================
|
|
// File: dmmgraph.cpp
|
|
// Author: Matthias Toussaint
|
|
// Created: Tue Apr 10 17:45:35 CEST 2001
|
|
//----------------------------------------------------------------------
|
|
// Permission to use, copy, modify, and distribute this software and its
|
|
// documentation for any purpose and without fee is hereby granted,
|
|
// provided that below copyright notice appear in all copies and that
|
|
// both that copyright notice and this permission notice appear in
|
|
// supporting documentation.
|
|
//
|
|
// This file is provided AS IS with no warranties of any kind. The
|
|
// author shall have no liability with respect to the infringement of
|
|
// copyrights, trade secrets or any patents by this file or any part
|
|
// thereof. In no event will the author be liable for any lost revenue
|
|
// or profits or other special, indirect and consequential damages.
|
|
//----------------------------------------------------------------------
|
|
// (c) 2001 Matthias Toussaint
|
|
//======================================================================
|
|
|
|
#include <dmmgraph.h>
|
|
#include <qpainter.h>
|
|
#include <qpixmap.h>
|
|
#include <iostream.h>
|
|
#include <qapplication.h>
|
|
#include <qpaintdevicemetrics.h>
|
|
#include <qcursor.h>
|
|
#include <qtooltip.h>
|
|
#include <qfiledialog.h>
|
|
#include <qfile.h>
|
|
#include <qtextstream.h>
|
|
|
|
DMMGraph::DMMGraph( QWidget *parent, const char *name ) :
|
|
QWidget( parent, name ),
|
|
m_size( 600 ),
|
|
m_length( 3600 ),
|
|
m_scaleMin( 0 ),
|
|
m_scaleMax( 0 ),
|
|
m_autoScale( true ),
|
|
m_pointer( 0 ),
|
|
m_ystep( 1 ),
|
|
m_sampleTime( 2 ),
|
|
m_sampleLength( 500 ),
|
|
m_running( false ),
|
|
m_mode( DMMGraph::Manual ),
|
|
m_mouseDown( false ),
|
|
m_lastValValid( false )
|
|
{
|
|
m_array = new QArray<double> (m_length);
|
|
|
|
scrollbar = new QScrollBar( QScrollBar::Horizontal, this );
|
|
scrollbar->setGeometry( 0, height()-16, width(), 16 );
|
|
scrollbar->setTracking( true );
|
|
scrollbar->setCursor( arrowCursor );
|
|
|
|
connect( scrollbar, SIGNAL( valueChanged(int) ),
|
|
this, SLOT( update() ));
|
|
|
|
m_remainingLength = m_sampleLength;
|
|
emitInfo();
|
|
|
|
m_infoBox = new QLabel( 0, 0, WStyle_Customize | WStyle_NoBorder |
|
|
WStyle_Tool );
|
|
m_infoBox->resize( 100, 50 );
|
|
m_infoBox->setFrameStyle( QFrame::Box | QFrame::Plain );
|
|
m_infoBox->setPalette( QToolTip::palette() );
|
|
|
|
setBackgroundMode( QWidget::NoBackground );
|
|
}
|
|
|
|
DMMGraph::~DMMGraph()
|
|
{
|
|
}
|
|
|
|
void
|
|
DMMGraph::paintEvent( QPaintEvent * )
|
|
{
|
|
QPixmap pix( width(), height()-16 );
|
|
QPainter p;
|
|
p.begin( &pix );
|
|
|
|
paint( &p, width(), height()-16, m_xfactor, m_xstep, m_yfactor, m_ystep,
|
|
m_maxUnit, m_hUnitFact, m_hUnit, true, false );
|
|
|
|
p.end();
|
|
p.begin( this );
|
|
p.drawPixmap( 0, 0, pix );
|
|
|
|
if (m_mouseDown)
|
|
{
|
|
drawCursor( m_mpos );
|
|
fillInfoBox( m_mpos );
|
|
}
|
|
}
|
|
|
|
void
|
|
DMMGraph::print( QPrinter *prt, const QString & title, const QString & comment )
|
|
{
|
|
if (!title.isEmpty())
|
|
{
|
|
prt->setDocName( title );
|
|
}
|
|
else
|
|
{
|
|
QString tmpStr;
|
|
tmpStr.sprintf( "QtDMM: %s", QDateTime::currentDateTime().toString().latin1() );
|
|
}
|
|
|
|
prt->setCreator( "QtDMM: (c) 2001 Matthias Toussaint" );
|
|
prt->setPrintProgram( "QtDMM: (c) 2001 Matthias Toussaint" );
|
|
|
|
QPainter p;
|
|
p.begin( prt );
|
|
|
|
QPaintDeviceMetrics pdm( prt );
|
|
|
|
int w = pdm.width();
|
|
int h = pdm.height();
|
|
|
|
p.setFont( QFont( "Helvetica", 20 ) );
|
|
|
|
QRect tRect = p.boundingRect( 0, 0, w, h, Qt::AlignTop | Qt::AlignHCenter | Qt::WordBreak, title );
|
|
|
|
p.drawText( tRect, Qt::AlignTop | Qt::AlignHCenter | Qt::WordBreak, title );
|
|
|
|
p.setFont( QFont( "Helvetica", 12 ));
|
|
|
|
QFontMetrics fm = p.fontMetrics();
|
|
int maxWidth = QMAX( fm.width( tr( "Sampling start:" ) ),
|
|
fm.width( tr( "Sampling resolution:" )));
|
|
int tHeight = fm.height();
|
|
|
|
p.drawText( 0, tRect.height()+10, maxWidth, tHeight, Qt::AlignLeft | Qt::AlignVCenter,
|
|
tr( "Sampling start:" ) );
|
|
p.drawText( maxWidth+10, tRect.height()+10, w-maxWidth-10, tHeight, Qt::AlignLeft | Qt::AlignVCenter,
|
|
m_graphStart.toString() );
|
|
|
|
p.drawText( 0, tRect.height()+10+tHeight, maxWidth, tHeight, Qt::AlignLeft | Qt::AlignVCenter,
|
|
tr( "Sampling resolution:" ) );
|
|
QString tmpStr;
|
|
tmpStr.sprintf( "%d %s", m_sampleTime, tr( "Seconds" ).latin1() );
|
|
p.drawText( maxWidth+10, tRect.height()+10+tHeight,
|
|
w-maxWidth-10, tHeight, Qt::AlignLeft | Qt::AlignVCenter,
|
|
tmpStr );
|
|
|
|
p.setFont( QFont( "Helvetica", 10 ));
|
|
|
|
QRect cRect = p.boundingRect( 0, 0, w, h, Qt::AlignTop | Qt::AlignLeft | Qt::WordBreak, comment );
|
|
|
|
p.drawText( 0, tRect.height()+20+2*tHeight, w, cRect.height(),
|
|
Qt::AlignLeft | Qt::AlignTop | Qt::WordBreak, comment );
|
|
|
|
h -= tRect.height()+30+2*tHeight+cRect.height();
|
|
|
|
double yfactor, ystep;
|
|
yfactor = createYScale( h, ystep );
|
|
|
|
double xfactor, xstep, hUnitFact, maxUnit;
|
|
QString hUnit;
|
|
xfactor = createTimeScale( w, xstep, hUnitFact, maxUnit, hUnit );
|
|
|
|
p.setClipRect( 0, tRect.height()+30+2*tHeight+cRect.height(), w, h );
|
|
p.setClipping( true );
|
|
|
|
p.translate( 0, tRect.height()+30+2*tHeight+cRect.height() );
|
|
|
|
paint( &p, w, h, xfactor, xstep, yfactor, ystep,
|
|
maxUnit, hUnitFact, hUnit, prt->colorMode() == QPrinter::Color, true );
|
|
|
|
p.end();
|
|
}
|
|
|
|
void
|
|
DMMGraph::paint( QPainter *p, int w, int h,
|
|
double xfactor, double xstep,
|
|
double yfactor, double ystep,
|
|
double maxUnit, double hUnitFact, const QString & hUnit,
|
|
bool color, bool printer )
|
|
{
|
|
p->setBrush( Qt::white );
|
|
p->setPen( Qt::black );
|
|
p->drawRect( 0, 0, w, h );
|
|
|
|
if (m_scaleMin != m_scaleMax)
|
|
{
|
|
paintHorizontalGrid( p, w, h, yfactor, ystep, color );
|
|
paintVerticalGrid( p, w, h, xfactor, xstep, maxUnit, hUnitFact, hUnit, color );
|
|
paintData( p, w, h, xfactor, yfactor, color, printer );
|
|
}
|
|
}
|
|
|
|
void
|
|
DMMGraph::paintHorizontalGrid( QPainter *p, int w, int h, double yfactor, double ystep, bool color )
|
|
{
|
|
if (color)
|
|
{
|
|
p->setPen( Qt::gray );
|
|
}
|
|
else
|
|
{
|
|
p->setPen( Qt::black );
|
|
}
|
|
int y = (int)qRound( 1+(m_scaleMax)/yfactor );
|
|
p->drawLine( 47, y, w-1, y );
|
|
p->drawLine( 50, 1, 50, h-1-20 );
|
|
p->drawLine( 50, h-1-20, w-1, h-1-20 );
|
|
|
|
if (color)
|
|
{
|
|
p->setPen( QPen( Qt::gray, 0, Qt::DotLine ) );
|
|
}
|
|
else
|
|
{
|
|
p->setPen( QPen( Qt::black, 0, Qt::DotLine ) );
|
|
}
|
|
|
|
QString scaleVal;
|
|
double val = 0.0;
|
|
while (val < m_scaleMax)
|
|
{
|
|
y = (int)qRound( 1+(m_scaleMax-val)/yfactor );
|
|
p->drawLine( 47, y, w-1, y );
|
|
if (y>20)
|
|
{
|
|
scaleVal.sprintf( "%g", val );
|
|
p->drawText( 1, y-10, 44, 20, Qt::AlignRight | Qt::AlignVCenter, scaleVal );
|
|
}
|
|
val += ystep;
|
|
}
|
|
val = -ystep;
|
|
while (val > m_scaleMin)
|
|
{
|
|
y = (int)qRound( 1+(m_scaleMax-val)/yfactor );
|
|
p->drawLine( 47, y, w-1, y );
|
|
scaleVal.sprintf( "%g", val );
|
|
p->drawText( 1, y-10, 44, 20, Qt::AlignRight | Qt::AlignVCenter, scaleVal );
|
|
val -= ystep;
|
|
}
|
|
|
|
p->drawText( 4, 4, 40, 20, Qt::AlignLeft | Qt::AlignVCenter, m_unit );
|
|
}
|
|
|
|
void
|
|
DMMGraph::paintVerticalGrid( QPainter *p, int w, int h, double xfactor, double xstep,
|
|
double maxUnit, double hUnitFact, const QString & hUnit, bool color )
|
|
{
|
|
if (color)
|
|
{
|
|
p->setPen( QPen( Qt::gray, 0, Qt::DotLine ) );
|
|
}
|
|
else
|
|
{
|
|
p->setPen( QPen( Qt::black, 0, Qt::DotLine ) );
|
|
}
|
|
|
|
QString scaleVal;
|
|
double val = xstep;
|
|
while (val < maxUnit)
|
|
{
|
|
int x = 50 + (int)qRound( 1+(val)/hUnitFact - scrollbar->value()/xfactor );
|
|
if (x > 51 && x < w-20)
|
|
{
|
|
p->drawLine( x, 1, x, h-1-20 );
|
|
if (x < w-45)
|
|
{
|
|
scaleVal.sprintf( "%g", val );
|
|
p->drawText( x-20, h-1-20, 40, 20, Qt::AlignCenter, scaleVal );
|
|
}
|
|
}
|
|
val += xstep;
|
|
}
|
|
p->drawText( w-40, h-1-20, 36, 20, Qt::AlignRight | Qt::AlignVCenter, hUnit );
|
|
}
|
|
|
|
void
|
|
DMMGraph::paintData( QPainter *p, int w, int h, double xfactor, double yfactor, bool color, bool printer )
|
|
{
|
|
int x = (int)qRound( (m_pointer-scrollbar->value()-1)/xfactor ) + 51;
|
|
if (!printer && x>50 && x <= w)
|
|
{
|
|
p->setPen( Qt::darkRed );
|
|
p->drawLine( x, 1, x, h-1-20 );
|
|
}
|
|
|
|
int y = (int)qRound( 1+(m_scaleMax-(*m_array)[scrollbar->value()])/yfactor );
|
|
|
|
if (color)
|
|
{
|
|
p->setPen( QPen( Qt::blue, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
|
|
}
|
|
else
|
|
{
|
|
p->setPen( QPen( Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) );
|
|
}
|
|
|
|
p->moveTo( 51, y );
|
|
|
|
for (int i=scrollbar->value()+1; i<m_pointer; i++)
|
|
{
|
|
int x = (int)qRound( (i-scrollbar->value())/xfactor ) + 51;
|
|
if (x <= w)
|
|
{
|
|
int y = (int)qRound( 1+(m_scaleMax-(*m_array)[i])/yfactor );
|
|
|
|
p->lineTo( x, y );
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
DMMGraph::resizeEvent( QResizeEvent * )
|
|
{
|
|
scrollbar->setGeometry( 0, height()-16, width(), 16 );
|
|
|
|
m_yfactor = createYScale( height()-16, m_ystep );
|
|
m_xfactor = createTimeScale( width(), m_xstep, m_hUnitFact,
|
|
m_maxUnit, m_hUnit );
|
|
}
|
|
|
|
void
|
|
DMMGraph::setGraphSize( int size, int length )
|
|
{
|
|
m_size = size/m_sampleTime;
|
|
m_length = length/m_sampleTime + 1;
|
|
|
|
scrollbar->setMaxValue( m_length-m_size );
|
|
scrollbar->setLineStep( m_size/10 );
|
|
scrollbar->setPageStep( m_size );
|
|
|
|
m_array->resize( m_length );
|
|
if (m_pointer >= m_length)
|
|
{
|
|
m_pointer = m_length-1;
|
|
}
|
|
|
|
emitInfo();
|
|
|
|
resizeEvent( 0 );
|
|
update();
|
|
}
|
|
|
|
void
|
|
DMMGraph::startSLOT()
|
|
{
|
|
m_sampleCounter = 0;
|
|
m_sum = 0;
|
|
clearSLOT();
|
|
m_running = true;
|
|
m_remainingLength = m_sampleLength;
|
|
m_pointer = 0;
|
|
|
|
emitInfo();
|
|
emit running( true );
|
|
|
|
m_graphStart = QDateTime::currentDateTime();
|
|
}
|
|
|
|
void
|
|
DMMGraph::stopSLOT()
|
|
{
|
|
m_running = false;
|
|
|
|
emitInfo();
|
|
emit running( false );
|
|
}
|
|
|
|
void
|
|
DMMGraph::addValue( double val )
|
|
{
|
|
if (m_mode == DMMGraph::Time && !m_running)
|
|
{
|
|
// we may miss the start due to aliasing otherwise
|
|
int diff = m_startTime.secsTo( QTime::currentTime() );
|
|
|
|
if (diff >= 0 && diff < 2)
|
|
{
|
|
qApp->beep();
|
|
startSLOT();
|
|
}
|
|
}
|
|
|
|
if (m_mode == DMMGraph::Raising && !m_running)
|
|
{
|
|
if (m_lastValValid)
|
|
{
|
|
if (m_lastVal < m_raisingThreshold && val >= m_raisingThreshold)
|
|
{
|
|
qApp->beep();
|
|
startSLOT();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_mode == DMMGraph::Falling && !m_running)
|
|
{
|
|
if (m_lastValValid)
|
|
{
|
|
if (m_lastVal > m_fallingThreshold && val <= m_fallingThreshold)
|
|
{
|
|
qApp->beep();
|
|
startSLOT();
|
|
}
|
|
}
|
|
}
|
|
|
|
m_lastValValid = true;
|
|
m_lastVal = val;
|
|
|
|
if (!m_running) return;
|
|
|
|
m_sum += val;
|
|
|
|
if (0 == m_sampleCounter)
|
|
{
|
|
if (!m_first)
|
|
{
|
|
val = m_sum / (double)m_sampleTime;
|
|
}
|
|
m_first = false;
|
|
m_sum = 0.0;
|
|
|
|
if (m_pointer >= m_length)
|
|
{
|
|
for (int i=1; i<m_length; i++)
|
|
{
|
|
(*m_array)[i-1] = (*m_array)[i];
|
|
}
|
|
m_pointer = m_length-1;
|
|
}
|
|
|
|
(*m_array)[m_pointer++] = val;
|
|
|
|
bool resFlag = false;
|
|
|
|
if (m_autoScale)
|
|
{
|
|
if (val > m_scaleMax*0.95) { m_scaleMax = val*1.2; resFlag = true; }
|
|
if (val < m_scaleMin*0.95) { m_scaleMin = val*1.2; resFlag = true; }
|
|
}
|
|
|
|
if (resFlag)
|
|
resizeEvent( 0 );
|
|
|
|
update();
|
|
}
|
|
|
|
emitInfo();
|
|
|
|
m_sampleCounter++;
|
|
if (m_sampleCounter == m_sampleTime) m_sampleCounter = 0;
|
|
|
|
if (0 == m_remainingLength)
|
|
{
|
|
qApp->beep();
|
|
stopSLOT();
|
|
return;
|
|
}
|
|
|
|
m_remainingLength--;
|
|
}
|
|
|
|
double
|
|
DMMGraph::createYScale( int h, double & ystep )
|
|
{
|
|
double yfactor = (m_scaleMax-m_scaleMin) / (double)(h-1-20);
|
|
|
|
double idiv = (double)(h-2)/40.;
|
|
double ddiv = (m_scaleMax-m_scaleMin)/idiv;
|
|
|
|
if (ddiv > 0.001 && ddiv <=0.002 )
|
|
{
|
|
ystep = 0.001;
|
|
}
|
|
else if (ddiv > 0.002 && ddiv <=0.005 )
|
|
{
|
|
ystep = 0.002;
|
|
}
|
|
else if (ddiv > 0.005 && ddiv <=0.01 )
|
|
{
|
|
ystep = 0.005;
|
|
}
|
|
else if (ddiv > 0.01 && ddiv <=0.02 )
|
|
{
|
|
ystep = 0.01;
|
|
}
|
|
else if (ddiv > 0.02 && ddiv <=0.05 )
|
|
{
|
|
ystep = 0.02;
|
|
}
|
|
else if (ddiv > 0.05 && ddiv <=0.1 )
|
|
{
|
|
ystep = 0.05;
|
|
}
|
|
else if (ddiv > 0.1 && ddiv <=0.2 )
|
|
{
|
|
ystep = 0.1;
|
|
}
|
|
else if (ddiv > 0.2 && ddiv <=0.5 )
|
|
{
|
|
ystep = 0.2;
|
|
}
|
|
else if (ddiv > 0.5 && ddiv <=1 )
|
|
{
|
|
ystep = 0.5;
|
|
}
|
|
else if (ddiv > 1 && ddiv <=2 )
|
|
{
|
|
ystep = 1;
|
|
}
|
|
else if (ddiv > 2 && ddiv <=5 )
|
|
{
|
|
ystep = 2;
|
|
}
|
|
else if (ddiv > 5 && ddiv <=10 )
|
|
{
|
|
ystep = 5;
|
|
}
|
|
else if (ddiv > 10 && ddiv <=20 )
|
|
{
|
|
ystep = 10;
|
|
}
|
|
else if (ddiv > 20 && ddiv <=50 )
|
|
{
|
|
ystep = 20;
|
|
}
|
|
else if (ddiv > 50 && ddiv <=100 )
|
|
{
|
|
ystep = 50;
|
|
}
|
|
else if (ddiv > 50 && ddiv <=100 )
|
|
{
|
|
ystep = 50;
|
|
}
|
|
else if (ddiv > 100 && ddiv <=200 )
|
|
{
|
|
ystep = 100;
|
|
}
|
|
else if (ddiv > 200 && ddiv <=500 )
|
|
{
|
|
ystep = 200;
|
|
}
|
|
else if (ddiv > 500 && ddiv <=1000 )
|
|
{
|
|
ystep = 500;
|
|
}
|
|
else if (ddiv > 1000 && ddiv <=2000 )
|
|
{
|
|
ystep = 1000;
|
|
}
|
|
else if (ddiv > 2000 && ddiv <=5000 )
|
|
{
|
|
ystep = 2000;
|
|
}
|
|
else if (ddiv > 5000 && ddiv <=10000 )
|
|
{
|
|
ystep = 5000;
|
|
}
|
|
else
|
|
{
|
|
ystep = 10000;
|
|
}
|
|
|
|
return yfactor;
|
|
}
|
|
|
|
// returns xfactor
|
|
double
|
|
DMMGraph::createTimeScale( int w, double & xstep, double & hUnitFact,
|
|
double & maxUnit, QString & hUnit )
|
|
{
|
|
double xfactor = (double)m_size/(double)(w-52);
|
|
|
|
double idiv = (double)(w-2-50)/80.;
|
|
double ddiv = m_size*m_sampleTime/idiv;
|
|
|
|
hUnit = tr( "[sec]" );
|
|
hUnitFact = xfactor*m_sampleTime;
|
|
maxUnit = m_length*m_sampleTime;
|
|
|
|
if (ddiv > 60)
|
|
{
|
|
ddiv /= 60;
|
|
hUnit = tr( "[min]" );
|
|
hUnitFact /= 60;
|
|
maxUnit /= 60;
|
|
|
|
if (ddiv > 60)
|
|
{
|
|
ddiv /= 60;
|
|
hUnitFact /= 60;
|
|
maxUnit /= 60;
|
|
|
|
hUnit = tr( "[hour]" );
|
|
|
|
if (ddiv > 24)
|
|
{
|
|
ddiv /= 24;
|
|
hUnitFact /= 24;
|
|
maxUnit /= 24;
|
|
|
|
hUnit = tr( "[day]" );
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ddiv > 1 && ddiv <=2 )
|
|
{
|
|
xstep = 1;
|
|
}
|
|
else if (ddiv > 2 && ddiv <=5 )
|
|
{
|
|
xstep = 2;
|
|
}
|
|
else if (ddiv > 5 && ddiv <=10 )
|
|
{
|
|
xstep = 5;
|
|
}
|
|
else if (ddiv > 10 && ddiv <=15 )
|
|
{
|
|
xstep = 10;
|
|
}
|
|
else if (ddiv > 15 && ddiv <=30 )
|
|
{
|
|
xstep = 15;
|
|
}
|
|
else if (ddiv > 30 && ddiv <=60 )
|
|
{
|
|
xstep = 30;
|
|
}
|
|
else if (ddiv > 60 && ddiv <=120 )
|
|
{
|
|
xstep = 60;
|
|
}
|
|
else if (ddiv > 120 && ddiv <=180 )
|
|
{
|
|
xstep = 120;
|
|
}
|
|
else if (ddiv > 180 && ddiv <=300 )
|
|
{
|
|
xstep = 180;
|
|
}
|
|
else if (ddiv > 300 && ddiv <=600 )
|
|
{
|
|
xstep = 300;
|
|
}
|
|
else if (ddiv > 600 && ddiv <=1000 )
|
|
{
|
|
xstep = 600;
|
|
}
|
|
else if (ddiv > 1000 && ddiv <=2000 )
|
|
{
|
|
xstep = 1000;
|
|
}
|
|
else if (ddiv > 2000 && ddiv <=5000 )
|
|
{
|
|
xstep = 2000;
|
|
}
|
|
else if (ddiv > 5000 && ddiv <=10000 )
|
|
{
|
|
xstep = 5000;
|
|
}
|
|
else if (ddiv > 10000 && ddiv <=20000 )
|
|
{
|
|
xstep = 10000;
|
|
}
|
|
else
|
|
{
|
|
xstep = 20000;
|
|
}
|
|
|
|
return xfactor;
|
|
}
|
|
|
|
void
|
|
DMMGraph::setUnit( const QString & unit )
|
|
{
|
|
if (unit.left(1) == "n")
|
|
{
|
|
m_unit = unit.mid( 1 );
|
|
}
|
|
else if (unit.left(1) == "u")
|
|
{
|
|
m_unit = unit.mid( 1 );
|
|
}
|
|
else if (unit.left(1) == "m")
|
|
{
|
|
m_unit = unit.mid( 1 );
|
|
}
|
|
else if (unit.left(1) == "k")
|
|
{
|
|
m_unit = unit.mid( 1 );
|
|
}
|
|
else if (unit.left(1) == "M")
|
|
{
|
|
m_unit = unit.mid( 1 );
|
|
}
|
|
else
|
|
{
|
|
m_unit = unit;
|
|
}
|
|
|
|
QString tmp = m_unit;
|
|
m_unit = "[";
|
|
m_unit += tmp;
|
|
m_unit += "]";
|
|
}
|
|
|
|
void
|
|
DMMGraph::clearSLOT()
|
|
{
|
|
m_pointer = 0;
|
|
if (m_autoScale)
|
|
{
|
|
m_scaleMin = m_scaleMax = 0;
|
|
}
|
|
|
|
m_graphStart = QDateTime::currentDateTime();
|
|
m_first = true;
|
|
|
|
update();
|
|
}
|
|
|
|
void
|
|
DMMGraph::emitInfo()
|
|
{
|
|
int h = m_remainingLength / 60 / 60;
|
|
int m = (m_remainingLength / 60 ) % 60;
|
|
int s = m_remainingLength % 60;
|
|
|
|
QString txt;
|
|
txt.sprintf( "%d/%d - %02d:%02d:%02d - %s",
|
|
m_pointer, m_length, h, m, s,
|
|
m_running ? tr( "Sampling" ).latin1() : tr( "Stopped" ).latin1() );
|
|
emit info( txt );
|
|
}
|
|
|
|
void
|
|
DMMGraph::mousePressEvent( QMouseEvent *ev )
|
|
{
|
|
if (m_scaleMin == m_scaleMax) return;
|
|
if (ev->x() < 51) return;
|
|
|
|
drawCursor( ev->pos() );
|
|
m_mpos = ev->pos();
|
|
m_mouseDown = true;
|
|
|
|
m_infoBox->move( ev->globalPos().x()+4, ev->globalPos().y()+4 );
|
|
fillInfoBox( ev->pos() );
|
|
m_infoBox->show();
|
|
}
|
|
|
|
void
|
|
DMMGraph::mouseMoveEvent( QMouseEvent *ev )
|
|
{
|
|
if (m_scaleMin == m_scaleMax) return;
|
|
if (!m_mouseDown) return;
|
|
|
|
drawCursor( m_mpos );
|
|
if (ev->x() < 51)
|
|
{
|
|
drawCursor( QPoint( 51, ev->y() ));
|
|
m_mpos = QPoint( 51, ev->y() );
|
|
}
|
|
else
|
|
{
|
|
drawCursor( ev->pos() );
|
|
m_mpos = ev->pos();
|
|
}
|
|
m_infoBox->move( ev->globalPos().x()+4, ev->globalPos().y()+4 );
|
|
fillInfoBox( ev->pos() );
|
|
|
|
}
|
|
|
|
void
|
|
DMMGraph::mouseReleaseEvent( QMouseEvent * )
|
|
{
|
|
if (m_scaleMin == m_scaleMax) return;
|
|
if (!m_mouseDown) return;
|
|
|
|
drawCursor( m_mpos );
|
|
m_mouseDown = false;
|
|
|
|
m_infoBox->hide();
|
|
}
|
|
|
|
void
|
|
DMMGraph::drawCursor( const QPoint & pos )
|
|
{
|
|
QPainter p(this);
|
|
p.setRasterOp( Qt::XorROP );
|
|
p.setPen( Qt::white );
|
|
p.drawLine( pos.x(), 1, pos.x(), height()-20-17 );
|
|
}
|
|
|
|
void
|
|
DMMGraph::fillInfoBox( const QPoint & pos )
|
|
{
|
|
int x = (int)qRound( (pos.x()-51)*m_xfactor + scrollbar->value() );
|
|
if (x < 0) x = 0;
|
|
int sec = x * m_sampleTime;
|
|
|
|
QTime t = m_graphStart.time().addSecs( sec );
|
|
QString tmpStr = t.toString();
|
|
|
|
if (x < m_pointer)
|
|
{
|
|
tmpStr += "\n";
|
|
|
|
QString tmpVal;
|
|
tmpVal.sprintf( "%g %s", (*m_array)[x], m_unit.latin1() );
|
|
|
|
tmpStr += tmpVal;
|
|
}
|
|
|
|
m_infoBox->setText( tmpStr );
|
|
m_infoBox->adjustSize();
|
|
}
|
|
|
|
void
|
|
DMMGraph::exportDataSLOT()
|
|
{
|
|
QString fn = QFileDialog::getSaveFileName( QString::null,
|
|
"All files (*.*)",
|
|
this );
|
|
|
|
if (!fn.isNull())
|
|
{
|
|
QFile file( fn );
|
|
file.open( IO_WriteOnly );
|
|
|
|
QTextStream ts( &file );
|
|
|
|
for (int i=0; i<m_pointer; i++)
|
|
{
|
|
QDateTime dt = m_graphStart.addSecs( i*m_sampleTime );
|
|
QString line;
|
|
line.sprintf( "%02d.%02d.%04d\t%02d:%02d:%02d\t%g\t%s\n",
|
|
dt.date().day(), dt.date().month(), dt.date().year(),
|
|
dt.time().hour(), dt.time().minute(), dt.time().second(),
|
|
(*m_array)[i],
|
|
m_unit.mid( 1, m_unit.length()-2 ).latin1() );
|
|
|
|
ts << line;
|
|
}
|
|
|
|
file.close();
|
|
}
|
|
}
|
|
|
|
void
|
|
DMMGraph::setThresholds( double falling, double raising )
|
|
{
|
|
m_fallingThreshold = falling;
|
|
m_raisingThreshold = raising;
|
|
}
|
|
|
|
void
|
|
DMMGraph::setScale( bool autoScale, double min, double max )
|
|
{
|
|
m_autoScale = autoScale;
|
|
|
|
if (!autoScale)
|
|
{
|
|
m_scaleMin = min;
|
|
m_scaleMax = max;
|
|
}
|
|
else
|
|
{
|
|
m_scaleMin = m_scaleMax = 0;
|
|
|
|
for (int i=0; i<m_pointer; i++)
|
|
{
|
|
double val = (*m_array)[i];
|
|
|
|
if (val > m_scaleMax*0.95) { m_scaleMax = val*1.2; }
|
|
if (val < m_scaleMin*0.95) { m_scaleMin = val*1.2; }
|
|
}
|
|
}
|
|
|
|
resizeEvent( 0 );
|
|
}
|