PARP Research Group University of Murcia, Spain


src/qvgui/qvhistogramplot2.cpp

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



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