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/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
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 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);
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
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
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
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
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
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
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