PARP Research Group University of Murcia, Spain


src/qvgui/qvhistogramplot2.cpp

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/qvhistogramplot2.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 QVHistogramPlot2::QVHistogramPlot2(const QString name, bool time, int step, QWidget *parent):
00036         QVPlot(name, false, false, false, true, time, step, parent), maxAxisNumbers(10)
00037         {
00038         enableAxis(0,true);
00039         enableAxis(2,true);
00040         setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw());
00041         setAxisTitle(QwtPlot::xBottom, "Index");
00042         }
00043 
00044 bool QVHistogramPlot2::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00045         {
00046         QVWorker* worker;
00047         if((worker = dynamic_cast<QVWorker*>(sourceContainer)) != NULL)
00048                 {
00049                 if ( worker->isType< QList<double> >(sourcePropName) || worker->isType< QVector<double> >(sourcePropName) )
00050                         return QVPlot::linkUnspecifiedInputProperty(worker, sourcePropName, linkType);
00051                 else
00052                         {
00053                         std::cerr << "Warning: a histogramplot can only be linked to a QList<double> or QVector<double> property." << std::endl;
00054                         return false;
00055                         }
00056                 }
00057         else
00058                 return false;
00059         }
00060 
00061 QStringList QVHistogramPlot2::getPropertyCurvNames(QString propertyName) const
00062         {
00063         QStringList names;
00064 
00065         const int auxListSize = isType< QList<double> >(propertyName)? getPropertyValue< QList<double> >(propertyName).size():
00066                                 isType< QVector<double> >(propertyName)? getPropertyValue< QVector<double> >(propertyName).size(): -1;
00067 
00068         for (int i = 0; i < auxListSize; i++)
00069                 names << QString::number(i);
00070 
00071         return names;
00072         }
00073 
00074 QList<double> QVHistogramPlot2::getPropertyCurvValues(QString propertyName) const
00075         {
00076         if (isType< QList<double> >(propertyName))
00077                 return getPropertyValue< QList<double> >(propertyName);
00078         else if (isType< QVector<double> >(propertyName))
00079                 return getPropertyValue< QVector<double> >(propertyName).toList();
00080         else
00081                 std::cout << "ERROR 34: Love unknown error codes?" << std::endl;
00082 
00083         return QList<double>();
00084         }
00085 
00086 QList<int> QVHistogramPlot2::getPropertyCurvOrders(QString propertyName) const
00087         {
00088         QList<int> order;
00089         //const int auxListSize = getPropertyValue< QList<double> >(property).size();
00090         //QList<double> auxList = getPropertyValue< QList<double> >(property);
00091         const int auxListSize = isType< QList<double> >(propertyName)? getPropertyValue< QList<double> >(propertyName).size():
00092                                 isType< QVector<double> >(propertyName)? getPropertyValue< QVector<double> >(propertyName).size(): -1;
00093 
00094         for (int i = 1; i <= auxListSize; i++)
00095         //for (int i = 1; i <= auxList.size(); i++)
00096                 order << i;
00097         return order;
00098         }
00099 
00100 void QVHistogramPlot2::init()
00101         {
00102         if (initied)
00103                 {
00104                 std::cerr << "Warning: a plot can't be initied more than one time." << std::endl;
00105                 return;
00106                 }
00107 
00108         readInputProperties();
00109         for(int i = 0; i < linkCont.size(); i++)
00110                 for(int j = 0; j < linkCont[i].properties.size(); j++)
00111                         {
00112                         const QStringList curvNames = getPropertyCurvNames(linkCont[i].properties[j].name);
00113 
00114                         for(int k = curvNames.size()-1; k >= 0; k--)
00115                                 {
00116                                 QString finalName = curvNames.at(k) + QString(" (%1)").arg(linkCont[i].id);
00117 
00118                                 QwtPlotCurve * qwtpc = NULL;
00119                                 if (k == 0) {
00120                                         qwtpc = new QwtPlotCurve(finalName);
00121                                         qwtpc->setRenderHint(QwtPlotItem::RenderAntialiased);
00122                                         QColor color = nextColor();
00123                                         qwtpc->setPen(color);
00124                                         if (doBrush) qwtpc->setBrush(color);
00125                                         qwtpc->setVisible(true);
00126                                         qwtpc->attach(this);
00127                                 }
00128 
00129                                 if (byTime) linkCont[i].properties[j].curves.prepend(Curve(finalName, qwtpc, 1));
00130                                 else        linkCont[i].properties[j].curves.prepend(Curve(finalName, qwtpc, linkCont.size()+1));
00131                                 haveCurves = TRUE;
00132                                 }
00133 
00134                         // and conect the legend items chechek signal
00135                         updateLegendItems();
00136                         }
00137 
00138         if (byTime) timer = startTimer(nStep * 10); // nStep * 10 ms
00139 
00140         initied = true;
00141         }
00142 
00143 void QVHistogramPlot2::insertNewFlags(int cont, int prop)
00144         {
00145         const QStringList curvNames = getPropertyCurvNames(linkCont[cont].properties[prop].name);
00146         if ( (linkCont.size() > cont) && (linkCont[cont].properties.size() > prop) && (curvNames.size() > linkCont[cont].properties[prop].curves.size()) )
00147                 {
00148                 const QList<int> curvOrders = getPropertyCurvOrders(linkCont[cont].properties[prop].name);
00149                 for (int i = 0; i < curvOrders.size(); i++)
00150                         if (curvOrders.at(i) > linkCont[cont].properties[prop].curves.size())
00151                                 {
00152                                 QString finalName = curvNames.at(i) + QString(" (%1)").arg(linkCont[cont].id);
00153 
00154                                 QwtPlotCurve * qwtpc = NULL;
00155                                 if (curvOrders.at(i) == 1) {
00156                                         qwtpc = new QwtPlotCurve(finalName);
00157                                         qwtpc->setRenderHint(QwtPlotItem::RenderAntialiased);
00158                                         QColor color = nextColor();
00159                                         qwtpc->setPen(color);
00160                                         if (doBrush) qwtpc->setBrush(color);
00161                                         qwtpc->setVisible(true);
00162                                 }
00163 
00164                                 if (byTime) linkCont[cont].properties[prop].curves.insert(i, Curve(finalName, qwtpc, 1));
00165                                 else        linkCont[cont].properties[prop].curves.insert(i, Curve(finalName, qwtpc, linkCont.size()+1));
00166                                 haveCurves = TRUE;
00167                                 }
00168 
00169                 for(int i = linkCont.size()-1; i >= 0; i--)
00170                         for(int j = linkCont[i].properties.size()-1; j >= 0; j--)
00171                                         if (linkCont[i].properties[j].curves.size() > 0)
00172                                         {
00173                                                 linkCont[i].properties[j].curves[0].plot->detach();
00174                                                 linkCont[i].properties[j].curves[0].plot->attach(this);
00175                                         }
00176 
00177                 // and reconect the legend items chechek signal
00178                 updateLegendItems();
00179                 }
00180         }
00181 
00182 void QVHistogramPlot2::advancePlot()
00183         {
00184         if (!haveCurves)
00185                 {
00186                 std::cerr << "QVPlot internal error: early call to advancePlot." << std::endl;
00187                 return;
00188                 }
00189 
00190         double max = 0;
00191 
00192         int maxSize = 0;
00193         for(int i = 0; i < linkCont.size(); i++)
00194                 for(int j = 0; j < linkCont[i].properties.size(); j++)
00195                         if (maxSize < linkCont[i].properties[j].curves.size()) maxSize = linkCont[i].properties[j].curves.size();
00196 
00197         QList<double *> curves;
00198         double curvePos[maxSize];
00199         for (int i = 0; i < maxSize; i++) curvePos[i] = i;
00200         QwtArray<QwtDoubleInterval> intervals(maxSize);
00201 
00202         // for each property
00203         for(int i = 0; i < linkCont.size(); i++)
00204                 for(int j = 0; j < linkCont[i].properties.size(); j++) {
00205                         double *tempCurve = new double[maxSize];
00206                         for (int k = 0; k < maxSize; k++) tempCurve[k] = 0;
00207                         curves.append(tempCurve);
00208                         
00209 
00210                         for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++) {
00211                                 if (byTime)     tempCurve[k] = linkCont[i].properties[j].curves[k].temp[0];
00212                                 else            tempCurve[k] = linkCont[i].properties[j].curves[k].temp[(iterationIndex%(linkCont.size()+1))];
00213                                 intervals[k] = QwtDoubleInterval(double(k)-0.5, double(k+1)-0.5);
00214                         }
00215 
00216                         // if is visible, update the plot values
00217                         if (linkCont[i].properties[j].curves.size() > 0) {
00218                                 if (linkCont[i].properties[j].curves[0].plot->style() != QwtPlotCurve::NoCurve) {
00219                                         for (int k = 0; k < linkCont[i].properties[j].curves.size(); k++) {
00220                                                 if (max < tempCurve[k]) max = tempCurve[k];
00221                                         }
00222                                         linkCont[i].properties[j].curves[0].plot->setRawData(curvePos, tempCurve, maxSize);
00223                                 }
00224                         }
00225                 }
00226 
00227         max = 1.1 *max;
00228 
00229 
00230         setAxisScale(QwtPlot::yLeft, 0, max);
00231         setAxisScale(QwtPlot::xBottom, maxSize, 0);
00232 
00233         int scaleShow = MAX(maxSize/maxAxisNumbers, 1);
00234         setAxisScaleDiv(QwtPlot::xBottom, axisScaleEngine(QwtPlot::xBottom)->divideScale(-0.5, double(maxSize)-0.5, 1, 1, scaleShow));
00235 
00236 
00237         // and replot
00238         replot();
00239 
00240         foreach(double * curve, curves)
00241                 delete curve;
00242         }
00243 
00244 void QVHistogramPlot2::resizeEvent(QResizeEvent * e)
00245         {
00246                 QVPlot::resizeEvent(e);
00247                 maxAxisNumbers = e->size().width() / 50;
00248         }
00249 
00250 
00251 



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