00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <qvmath.h>
00026 #include <iostream>
00027 #include "qvfunctionplot.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 QVFunctionPlot::QVFunctionPlot(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 QVFunctionPlot::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00045 {
00046 QVProcessingBlock* block;
00047 if((block = dynamic_cast<QVProcessingBlock*>(sourceContainer)) != NULL)
00048 {
00049 if ( block->isType< QList<double> >(sourcePropName) || block->isType< QVector<double> >(sourcePropName) )
00050 return QVPlot::linkUnspecifiedInputProperty(block, 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 QVFunctionPlot::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> QVFunctionPlot::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> QVFunctionPlot::getPropertyCurvOrders(QString propertyName) const
00087 {
00088 QList<int> order;
00089
00090
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
00096 order << i;
00097 return order;
00098 }
00099
00100 void QVFunctionPlot::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
00135 updateLegendItems();
00136 }
00137
00138 if (byTime) timer = startTimer(nStep * 10);
00139
00140 initied = true;
00141 }
00142
00143 void QVFunctionPlot::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
00178 updateLegendItems();
00179 }
00180 }
00181
00182 void QVFunctionPlot::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
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
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
00238 replot();
00239
00240 foreach(double * curve, curves)
00241 delete curve;
00242 }
00243
00244 void QVFunctionPlot::resizeEvent(QResizeEvent * e)
00245 {
00246 QVPlot::resizeEvent(e);
00247 maxAxisNumbers = e->size().width() / 50;
00248 }
00249
00250
00251