PARP Research Group University of Murcia, Spain


src/qvgui/qvhistogramplot.cpp

Go to the documentation of this file.
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/qvhistogramplot.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 QVHistogramPlot::QVHistogramPlot(const QString name, bool time, int step, double maxim, double minim, QWidget *parent):
00035         QVPlot(name, false, false, false, true, time, step, parent), histItem(), max(maxim), min(minim), maxAxisNumbers(10)
00036         {
00037         histItem.setColor(Qt::darkCyan);
00038         enableAxis(0,true);
00039         enableAxis(2,true);
00040         setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw());
00041         setAxisTitle(QwtPlot::xBottom, "Index");
00042         }
00043 
00044 bool QVHistogramPlot::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 QVHistogramPlot::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> QVHistogramPlot::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> QVHistogramPlot::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 QVHistogramPlot::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         histItem.attach(this);
00109 
00110         readInputProperties();
00111         for(int i = 0; i < linkCont.size(); i++)
00112                 for(int j = 0; j < linkCont[i].properties.size(); j++)
00113                         {
00114                         const QStringList curvNames = getPropertyCurvNames(linkCont[i].properties[j].name);
00115 
00116                         for(int k = curvNames.size()-1; k >= 0; k--)
00117                                 {
00118                                 QString finalName = curvNames.at(k) + QString(" (%1)").arg(linkCont[i].id);
00119 
00120                                 QwtPlotCurve * qwtpc = new QwtPlotCurve(finalName);
00121                                 if (byTime) linkCont[i].properties[j].curves.prepend(Curve(curvNames.at(k), qwtpc, 1));
00122                                 else        linkCont[i].properties[j].curves.prepend(Curve(curvNames.at(k), qwtpc, linkCont.size()+1));
00123                                 haveCurves = TRUE;
00124                                 }
00125                         }
00126 
00127         if (byTime) timer = startTimer(nStep * 10); // nStep * 10 ms
00128 
00129         initied = true;
00130         }
00131 
00132 void QVHistogramPlot::insertNewFlags(int cont, int prop)
00133         {
00134         const QStringList curvNames = getPropertyCurvNames(linkCont[cont].properties[prop].name);
00135         if ( (linkCont.size() > cont) && (linkCont[cont].properties.size() > prop) && (curvNames.size() > linkCont[cont].properties[prop].curves.size()) )
00136                 {
00137                 const QList<int> curvOrders = getPropertyCurvOrders(linkCont[cont].properties[prop].name);
00138                 for (int i = 0; i < curvOrders.size(); i++)
00139                         if (curvOrders.at(i) > linkCont[cont].properties[prop].curves.size())
00140                                 {
00141                                 QString finalName = curvNames.at(i) + QString(" (%1)").arg(linkCont[cont].id);
00142 
00143                                 QwtPlotCurve * qwtpc = new QwtPlotCurve(finalName);
00144                                 if (byTime) linkCont[cont].properties[prop].curves.insert(i, Curve(curvNames.at(i), qwtpc, 1));
00145                                 else        linkCont[cont].properties[prop].curves.insert(i, Curve(curvNames.at(i), qwtpc, linkCont.size()+1));
00146                                 haveCurves = TRUE;
00147                                 }
00148                 }
00149         }
00150 
00151 void QVHistogramPlot::advancePlot()
00152         {
00153         if (!haveCurves)
00154                 {
00155                 std::cerr << "QVPlot internal error: early call to advancePlot." << std::endl;
00156                 return;
00157                 }
00158 
00159         // update data
00160         int numValues = 0;
00161         for(int i = 0; i < linkCont.size(); i++)
00162                 for(int j = 0; j < linkCont[i].properties.size(); j++) {
00163                         for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00164                                 {
00165                                 // update the new value
00166                                 if (byTime)     linkCont[i].properties[j].curves[k].history[0] = linkCont[i].properties[j].curves[k].temp[0];
00167                                 else            linkCont[i].properties[j].curves[k].history[0] = linkCont[i].properties[j].curves[k].temp[(iterationIndex%(linkCont.size()+1))];
00168                                 }
00169                         if (numValues < linkCont[i].properties[j].curves.size()) numValues = linkCont[i].properties[j].curves.size();
00170                 }
00171 
00172         QwtArray<QwtDoubleInterval> intervals(numValues);
00173         QwtArray<double> values(numValues);
00174 
00175         // curve update
00176         for(int i = 0; i < linkCont.size(); i++)
00177                 for(int j = 0; j < linkCont[i].properties.size(); j++) {
00178                         for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00179                                 {
00180                                 if (values[k] < linkCont[i].properties[j].curves[k].history[0]) values[k] = linkCont[i].properties[j].curves[k].history[0];
00181                                 intervals[k] = QwtDoubleInterval(double(k)-0.5, double(k+1)-0.5);
00182                                 }
00183                 }
00184 
00185         // scroll bottom axis, scaled like an index
00186         int scaleShow = MAX(numValues/maxAxisNumbers, 1);
00187         setAxisScaleDiv(QwtPlot::xBottom, axisScaleEngine(QwtPlot::xBottom)->divideScale(-0.5, double(numValues)-0.5, 1, 1, scaleShow));
00188 
00189         histItem.setData(QwtIntervalData(intervals, values));
00190 
00191         // adjust left axis (using the visible values's maximum)
00192         if (max == 0)
00193                 {
00194                 for(int i = 0; i < linkCont.size(); i++)
00195                         for(int j = 0; j < linkCont[i].properties.size(); j++)
00196                                 for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00197                                         if (max < linkCont[i].properties[j].curves[k].history[0]) max = linkCont[i].properties[j].curves[k].history[0];
00198                 max = 1.1 *max;
00199                 setAxisScale(QwtPlot::yLeft, min, max);
00200                 max = 0;
00201                 }
00202         else setAxisScale(QwtPlot::yLeft, min, max);
00203 
00204         // and replot
00205         replot();
00206         }
00207 
00208 
00209 
00210 void QVHistogramPlot::resizeEvent(QResizeEvent * e)
00211         {
00212                 QVPlot::resizeEvent(e);
00213                 maxAxisNumbers = e->size().width() / 50;
00214         }
00215 



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