00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00089
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
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
00134 updateLegendItems();
00135 }
00136
00137 if (byTime) timer = startTimer(nStep * 10);
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
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
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
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
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