src/qvgui/qvcpuplot.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #include <qlayout.h>
00026 #include <qlabel.h>
00027 #include <QTime>
00028 #include <QDebug>
00029 #include <QThread>
00030 #include <qwt_plot_layout.h>
00031 #include <qwt_scale_draw.h>
00032 #include <qwt_scale_widget.h>
00033 #include <qwt_legend.h>
00034 #include <qwt_legend_item.h>
00035 #include <qwt_plot_canvas.h>
00036 
00037 #include <qvgui/qvcpuplot.h>
00038 
00039 QColor  colors[10] = {
00040                 Qt::red,
00041                 Qt::green,
00042                 Qt::blue,
00043                 Qt::cyan,
00044                 Qt::magenta,
00045                 Qt::darkRed,
00046                 Qt::darkGreen,
00047                 Qt::darkBlue,
00048                 Qt::darkCyan,
00049                 Qt::darkMagenta
00050                 };
00051 
00053 // auxiliar classes functionality
00054 QVCpuPlot::CpuPieMarker::CpuPieMarker(unsigned int nFlags, QwtPlotCurve **curves): nCpuFlags(nFlags), cpuCurve(curves)
00055         {
00056         setZ(1000);
00057         setRenderHint(QwtPlotItem::RenderAntialiased, true);
00058         }
00059 
00060 int QVCpuPlot::CpuPieMarker::rtti() const
00061         {
00062         return QwtPlotItem::Rtti_PlotUserItem;
00063         }
00064 
00065 void QVCpuPlot::CpuPieMarker::draw(QPainter *p, const QwtScaleMap &, const QwtScaleMap &, const QRect &rect) const
00066         {
00067         const QVCpuPlot *cpuPlot = (QVCpuPlot *)plot();
00068         const int margin = 5;
00069 
00070         QRect pieRect;
00071         pieRect.setX(rect.x() + margin);
00072         pieRect.setY(rect.y() + margin);
00073 
00074         int diameter = ( (rect.height() > rect.width()) ? rect.width(): rect.height() ) / 4;
00075         pieRect.setHeight(diameter);
00076         pieRect.setWidth(diameter);
00077 
00078         int angle = (int)(5760 * 0.75);
00079 
00080         double sum = 0;
00081         for ( unsigned int i = 0; i < nCpuFlags; i++ )
00082                 sum += cpuPlot->curveValue(i);
00083 
00084         for ( unsigned int i = 0; i < nCpuFlags; i++ )
00085                 {
00086                 const QwtPlotCurve *curve = cpuCurve[i];
00087                 if ( curve->dataSize() > 0 )
00088                         {
00089                         const int value = (int)(5760 * cpuPlot->curveValue(i) / sum);
00090                         p->save();
00091                         p->setBrush(QBrush(curve->pen().color(), Qt::SolidPattern));
00092                         if ( value != 0 )
00093                                 p->drawPie(pieRect, -angle, -value);
00094                         p->restore();
00095 
00096                         angle += value;
00097                         }
00098                 }
00099         }
00100 
00102 
00103 QVCpuPlot::QVCpuPlot(CpuStat *cpuStat, bool decorations, QWidget *parent):
00104         QwtPlot(parent), dataCount(0), timer(this)
00105         {
00106         this->cpuStat = cpuStat;
00107         this->decorations = decorations;
00108         nFlags = 0;
00109         setAutoReplot(false);
00110 
00111         for ( int i = 0; i < MAX_HISTORY; i++ )
00112                 timeData[MAX_HISTORY - 1 - i] = i;
00113 
00114         startTimer(1000); // 1 second
00115 
00117         plotLayout()->setAlignCanvasToScales(true);
00118 
00119         if (decorations)
00120                 {
00121                 QwtLegend *legend = new QwtLegend;
00122                 legend->setItemMode(QwtLegend::CheckableItem);
00123                 insertLegend(legend, QwtPlot::RightLegend);
00124                 }
00125         else
00126                 {
00127                 enableAxis(0,false);
00128                 enableAxis(1,false);
00129                 enableAxis(2,false);
00130                 }
00131 
00132         class TimeScaleDraw: public QwtScaleDraw
00133                 {
00134                 public:
00135                         TimeScaleDraw(): baseTime() { }
00136                         virtual QwtText label(double v) const   { return baseTime.addSecs((int)v - 60).toString();      }
00137                 private:
00138                         QTime baseTime;
00139                 };
00140 
00141         setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw());
00142         setAxisScale(QwtPlot::xBottom, 0, MAX_HISTORY);
00143         setAxisLabelRotation(QwtPlot::xBottom, -50.0);
00144         setAxisLabelAlignment(QwtPlot::xBottom, Qt::AlignLeft | Qt::AlignBottom);
00145 
00146         /*
00147         In situations, when there is a label at the most right position of the
00148         scale, additional space is needed to display the overlapping part
00149         of the label would be taken by reducing the width of scale and canvas.
00150         To avoid this "jumping canvas" effect, we add a permanent margin.
00151         We don't need to do the same for the left border, because there
00152         is enough space for the overlapping label below the left scale.
00153         */
00154 
00155         QwtScaleWidget *scaleWidget = axisWidget(QwtPlot::xBottom);
00156         const int fmh = QFontMetrics(scaleWidget->font()).height();
00157         scaleWidget->setMinBorderDist(0, fmh / 2);
00158 
00159         setAxisTitle(QwtPlot::yLeft, "Cpu Usage [msecs]");
00160         setAxisScale(QwtPlot::yLeft, 0, 100);
00161         }
00162 
00163 void QVCpuPlot::initPlot()
00164         {
00165         QStringList timeFlags = cpuStat->getFlagNames();
00166         nFlags = timeFlags.size();
00167         data = new  double*[nFlags]();
00168         curve = new QwtPlotCurve*[nFlags]();
00169 
00170         CpuPieMarker *pie = new CpuPieMarker(nFlags, curve);
00171         pie->attach(this);
00172 
00173         for (int n = nFlags-1; n >=0; n--)
00174                 {
00175                 data[n] = new double[MAX_HISTORY];
00176                 curve[n] = new QwtPlotCurve(timeFlags.at(n));
00177                 curve[n]->setRenderHint(QwtPlotItem::RenderAntialiased);
00178                 QColor color = colors[n%10];
00179                 //color.setAlpha(60);
00180                 curve[n]->setPen(color);
00181                 curve[n]->setBrush(color);
00182                 curve[n]->setVisible(true);
00183                 curve[n]->attach(this);
00184                 }
00185 
00186         cpuStat->updateStats();
00187         double * statistics = cpuStat->getLastMeans();
00188         for ( int c = 0; c < nFlags; c++ )      
00189                 {
00190                 data[c][0] = statistics[c];
00191                 for ( int i = 1; i < MAX_HISTORY; i++ )
00192                         data[c][i] = statistics[c];
00193                 }
00194         }
00195 
00196 void QVCpuPlot::timerEvent(QTimerEvent *)       { this->update(); }
00197 
00198 void QVCpuPlot::update()
00199         {
00200         if (nFlags == 0)
00201                 {
00202                 if (cpuStat->isActive()) initPlot();
00203                 return;
00204                 }
00205 
00206         // update data
00207         cpuStat->updateStats();
00208         double * statistics = cpuStat->getLastMeans();
00209 
00210         for ( int i = dataCount; i > 0; i-- )
00211                 {
00212                 if ( i < MAX_HISTORY ) data[0][i] = data[0][i-1];
00213                 data[0][0] = statistics[0];
00214                 for ( int c = 1; c < nFlags; c++ )
00215                         {
00216                         if ( i < MAX_HISTORY ) data[c][i] = data[c][i-1];
00217                         data[c][0] = statistics[c] + data[c-1][0];
00218                         }
00219                 }
00220 
00221         // increments
00222         if ( dataCount < MAX_HISTORY ) dataCount++;
00223         //qDebug() << "iterate 3!...";
00224         for ( int j = 0; j < MAX_HISTORY; j++ )
00225                 timeData[j]++;
00226 
00227         setAxisScale(QwtPlot::xBottom, timeData[MAX_HISTORY - 1], timeData[0]);
00228 
00229         // curve update
00230         for ( int c = 0; c < nFlags; c++ )
00231                 curve[c]->setRawData(timeData, data[c], dataCount);
00232 
00233         // widget update
00234         double max = 0;
00235         for ( int c = 0; c < nFlags; c++ )
00236                 for ( int j = 0; j < MAX_HISTORY; j++ )
00237                         if (max < data[c][j]) max = data[c][j];
00238         max = 1.1 *max;
00239         setAxisScale(QwtPlot::yLeft, 0, max);
00240         replot();
00241         };
00242 

Generated on Thu Mar 13 19:18:16 2008 for QVision by  doxygen 1.5.3