PARP Research Group University of Murcia, Spain


src/qvgui/qvhistogramplot.cpp

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008, 2009. 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 <qvmath.h>
00026 #include <iostream>
00027 #include <qvgui/qvhistogramplot.h>
00028 #include <qwt_interval_data.h>
00029 #include <qwt_scale_draw.h>
00030 #include <qwt_scale_div.h>
00031 #include <qwt_scale_engine.h>
00032 #include <QResizeEvent>
00033 
00035 QVHistogramPlot::QVHistogramPlot(const QString name, bool time, int step, double maxim, double minim, QWidget *parent):
00036         QVPlot(name, false, false, false, true, time, step, parent), histItem(), max(maxim), min(minim), maxAxisNumbers(10)
00037         {
00038         histItem.setColor(Qt::darkCyan);
00039         enableAxis(0,true);
00040         enableAxis(2,true);
00041         setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw());
00042         setAxisTitle(QwtPlot::xBottom, "Index");
00043         }
00044 
00045 bool QVHistogramPlot::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00046         {
00047         QVWorker* worker;
00048         if((worker = dynamic_cast<QVWorker*>(sourceContainer)) != NULL)
00049                 {
00050                 if ( worker->isType< QList<double> >(sourcePropName) || worker->isType< QVector<double> >(sourcePropName) )
00051                         return QVPlot::linkUnspecifiedInputProperty(worker, sourcePropName, linkType);
00052                 else
00053                         {
00054                         std::cerr << "Warning: a histogramplot can only be linked to a QList<double> or QVector<double> property." << std::endl;
00055                         return false;
00056                         }
00057                 }
00058         else
00059                 return false;
00060         }
00061 
00062 QStringList QVHistogramPlot::getPropertyCurvNames(QString propertyName) const
00063         {
00064         QStringList names;
00065 
00066         const int auxListSize = isType< QList<double> >(propertyName)? getPropertyValue< QList<double> >(propertyName).size():
00067                                 isType< QVector<double> >(propertyName)? getPropertyValue< QVector<double> >(propertyName).size(): -1;
00068 
00069         for (int i = 0; i < auxListSize; i++)
00070                 names << QString::number(i);
00071 
00072         return names;
00073         }
00074 
00075 QList<double> QVHistogramPlot::getPropertyCurvValues(QString propertyName) const
00076         {
00077         if (isType< QList<double> >(propertyName))
00078                 return getPropertyValue< QList<double> >(propertyName);
00079         else if (isType< QVector<double> >(propertyName))
00080                 return getPropertyValue< QVector<double> >(propertyName).toList();
00081         else
00082                 std::cout << "ERROR 34: Love unknown error codes?" << std::endl;
00083 
00084         return QList<double>();
00085         }
00086 
00087 QList<int> QVHistogramPlot::getPropertyCurvOrders(QString propertyName) const
00088         {
00089         QList<int> order;
00090         //const int auxListSize = getPropertyValue< QList<double> >(property).size();
00091         //QList<double> auxList = getPropertyValue< QList<double> >(property);
00092         const int auxListSize = isType< QList<double> >(propertyName)? getPropertyValue< QList<double> >(propertyName).size():
00093                                 isType< QVector<double> >(propertyName)? getPropertyValue< QVector<double> >(propertyName).size(): -1;
00094 
00095         for (int i = 1; i <= auxListSize; i++)
00096         //for (int i = 1; i <= auxList.size(); i++)
00097                 order << i;
00098         return order;
00099         }
00100 
00101 void QVHistogramPlot::init()
00102         {
00103         if (initied)
00104                 {
00105                 std::cerr << "Warning: a plot can't be initied more than one time." << std::endl;
00106                 return;
00107                 }
00108 
00109         histItem.attach(this);
00110 
00111         readInputProperties();
00112         for(int i = 0; i < linkCont.size(); i++)
00113                 for(int j = 0; j < linkCont[i].properties.size(); j++)
00114                         {
00115                         const QStringList curvNames = getPropertyCurvNames(linkCont[i].properties[j].name);
00116 
00117                         for(int k = curvNames.size()-1; k >= 0; k--)
00118                                 {
00119                                 QString finalName = curvNames.at(k) + QString(" (%1)").arg(linkCont[i].id);
00120 
00121                                 QwtPlotCurve * qwtpc = new QwtPlotCurve(finalName);
00122                                 if (byTime) linkCont[i].properties[j].curves.prepend(Curve(curvNames.at(k), qwtpc, 1));
00123                                 else        linkCont[i].properties[j].curves.prepend(Curve(curvNames.at(k), qwtpc, linkCont.size()+1));
00124                                 haveCurves = TRUE;
00125                                 }
00126                         }
00127 
00128         if (byTime) timer = startTimer(nStep * 10); // nStep * 10 ms
00129 
00130         initied = true;
00131         }
00132 
00133 void QVHistogramPlot::insertNewFlags(int cont, int prop)
00134         {
00135         const QStringList curvNames = getPropertyCurvNames(linkCont[cont].properties[prop].name);
00136         if ( (linkCont.size() > cont) && (linkCont[cont].properties.size() > prop) && (curvNames.size() > linkCont[cont].properties[prop].curves.size()) )
00137                 {
00138                 const QList<int> curvOrders = getPropertyCurvOrders(linkCont[cont].properties[prop].name);
00139                 for (int i = 0; i < curvOrders.size(); i++)
00140                         if (curvOrders.at(i) > linkCont[cont].properties[prop].curves.size())
00141                                 {
00142                                 QString finalName = curvNames.at(i) + QString(" (%1)").arg(linkCont[cont].id);
00143 
00144                                 QwtPlotCurve * qwtpc = new QwtPlotCurve(finalName);
00145                                 if (byTime) linkCont[cont].properties[prop].curves.insert(i, Curve(curvNames.at(i), qwtpc, 1));
00146                                 else        linkCont[cont].properties[prop].curves.insert(i, Curve(curvNames.at(i), qwtpc, linkCont.size()+1));
00147                                 haveCurves = TRUE;
00148                                 }
00149                 }
00150         }
00151 
00152 void QVHistogramPlot::advancePlot()
00153         {
00154         if (!haveCurves)
00155                 {
00156                 std::cerr << "QVPlot internal error: early call to advancePlot." << std::endl;
00157                 return;
00158                 }
00159 
00160         // update data
00161         int numValues = 0;
00162         for(int i = 0; i < linkCont.size(); i++)
00163                 for(int j = 0; j < linkCont[i].properties.size(); j++) {
00164                         for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00165                                 {
00166                                 // update the new value
00167                                 if (byTime)     linkCont[i].properties[j].curves[k].history[0] = linkCont[i].properties[j].curves[k].temp[0];
00168                                 else            linkCont[i].properties[j].curves[k].history[0] = linkCont[i].properties[j].curves[k].temp[(iterationIndex%(linkCont.size()+1))];
00169                                 }
00170                         if (numValues < linkCont[i].properties[j].curves.size()) numValues = linkCont[i].properties[j].curves.size();
00171                 }
00172 
00173         QwtArray<QwtDoubleInterval> intervals(numValues);
00174         QwtArray<double> values(numValues);
00175 
00176         // curve update
00177         for(int i = 0; i < linkCont.size(); i++)
00178                 for(int j = 0; j < linkCont[i].properties.size(); j++) {
00179                         for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00180                                 {
00181                                 if (values[k] < linkCont[i].properties[j].curves[k].history[0]) values[k] = linkCont[i].properties[j].curves[k].history[0];
00182                                 intervals[k] = QwtDoubleInterval(double(k)-0.5, double(k+1)-0.5);
00183                                 }
00184                 }
00185 
00186         // scroll bottom axis, scaled like an index
00187         int scaleShow = MAX(numValues/maxAxisNumbers, 1);
00188         setAxisScaleDiv(QwtPlot::xBottom, axisScaleEngine(QwtPlot::xBottom)->divideScale(-0.5, double(numValues)-0.5, 1, 1, scaleShow));
00189 
00190         histItem.setData(QwtIntervalData(intervals, values));
00191 
00192         // adjust left axis (using the visible values's maximum)
00193         if (max == 0)
00194                 {
00195                 for(int i = 0; i < linkCont.size(); i++)
00196                         for(int j = 0; j < linkCont[i].properties.size(); j++)
00197                                 for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00198                                         if (max < linkCont[i].properties[j].curves[k].history[0]) max = linkCont[i].properties[j].curves[k].history[0];
00199                 max = 1.1 *max;
00200                 setAxisScale(QwtPlot::yLeft, min, max);
00201                 max = 0;
00202                 }
00203         else setAxisScale(QwtPlot::yLeft, min, max);
00204 
00205         // and replot
00206         replot();
00207         }
00208 
00209 
00210 
00211 void QVHistogramPlot::resizeEvent(QResizeEvent * e)
00212         {
00213                 QVPlot::resizeEvent(e);
00214                 maxAxisNumbers = e->size().width() / 50;
00215         }
00216 



QVision framework. PARP research group, copyright 2007, 2008.