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 "qvhistogramplot.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 QVHistogramPlot::QVHistogramPlot(const QString name, bool time, int step, double maxim, double minim, QWidget *parent):
00036 QVPlot(name, false, false, false, true, time, step, parent), histItem(), max(maxim), min(minim), maxAxisNumbers(10)
00037 {
00038 histItem.setColor(Qt::darkCyan);
00039 enableAxis(0,true);
00040 enableAxis(2,true);
00041 setAxisScaleDraw(QwtPlot::xBottom, new QwtScaleDraw());
00042 setAxisTitle(QwtPlot::xBottom, "Index");
00043 }
00044
00045 bool QVHistogramPlot::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00046 {
00047 QVProcessingBlock* block;
00048 if((block = dynamic_cast<QVProcessingBlock*>(sourceContainer)) != NULL)
00049 {
00050 if ( block->isType< QList<double> >(sourcePropName) || block->isType< QVector<double> >(sourcePropName) )
00051 return QVPlot::linkUnspecifiedInputProperty(block, sourcePropName, linkType);
00052 else
00053 {
00054 std::cerr << "Warning: a histogramplot can only be linked to a QList<double> or QVector<double> property." << std::endl;
00055 return false;
00056 }
00057 }
00058 else
00059 return false;
00060 }
00061
00062 QStringList QVHistogramPlot::getPropertyCurvNames(QString propertyName) const
00063 {
00064 QStringList names;
00065
00066 const int auxListSize = isType< QList<double> >(propertyName)? getPropertyValue< QList<double> >(propertyName).size():
00067 isType< QVector<double> >(propertyName)? getPropertyValue< QVector<double> >(propertyName).size(): -1;
00068
00069 for (int i = 0; i < auxListSize; i++)
00070 names << QString::number(i);
00071
00072 return names;
00073 }
00074
00075 QList<double> QVHistogramPlot::getPropertyCurvValues(QString propertyName) const
00076 {
00077 if (isType< QList<double> >(propertyName))
00078 return getPropertyValue< QList<double> >(propertyName);
00079 else if (isType< QVector<double> >(propertyName))
00080 return getPropertyValue< QVector<double> >(propertyName).toList();
00081 else
00082 std::cout << "ERROR 34: Love unknown error codes?" << std::endl;
00083
00084 return QList<double>();
00085 }
00086
00087 QList<int> QVHistogramPlot::getPropertyCurvOrders(QString propertyName) const
00088 {
00089 QList<int> order;
00090
00091
00092 const int auxListSize = isType< QList<double> >(propertyName)? getPropertyValue< QList<double> >(propertyName).size():
00093 isType< QVector<double> >(propertyName)? getPropertyValue< QVector<double> >(propertyName).size(): -1;
00094
00095 for (int i = 1; i <= auxListSize; i++)
00096
00097 order << i;
00098 return order;
00099 }
00100
00101 void QVHistogramPlot::init()
00102 {
00103 if (initied)
00104 {
00105 std::cerr << "Warning: a plot can't be initied more than one time." << std::endl;
00106 return;
00107 }
00108
00109 histItem.attach(this);
00110
00111 readInputProperties();
00112 for(int i = 0; i < linkCont.size(); i++)
00113 for(int j = 0; j < linkCont[i].properties.size(); j++)
00114 {
00115 const QStringList curvNames = getPropertyCurvNames(linkCont[i].properties[j].name);
00116
00117 for(int k = curvNames.size()-1; k >= 0; k--)
00118 {
00119 QString finalName = curvNames.at(k) + QString(" (%1)").arg(linkCont[i].id);
00120
00121 QwtPlotCurve * qwtpc = new QwtPlotCurve(finalName);
00122 if (byTime) linkCont[i].properties[j].curves.prepend(Curve(curvNames.at(k), qwtpc, 1));
00123 else linkCont[i].properties[j].curves.prepend(Curve(curvNames.at(k), qwtpc, linkCont.size()+1));
00124 haveCurves = TRUE;
00125 }
00126 }
00127
00128 if (byTime) timer = startTimer(nStep * 10);
00129
00130 initied = true;
00131 }
00132
00133 void QVHistogramPlot::insertNewFlags(int cont, int prop)
00134 {
00135 const QStringList curvNames = getPropertyCurvNames(linkCont[cont].properties[prop].name);
00136 if ( (linkCont.size() > cont) && (linkCont[cont].properties.size() > prop) && (curvNames.size() > linkCont[cont].properties[prop].curves.size()) )
00137 {
00138 const QList<int> curvOrders = getPropertyCurvOrders(linkCont[cont].properties[prop].name);
00139 for (int i = 0; i < curvOrders.size(); i++)
00140 if (curvOrders.at(i) > linkCont[cont].properties[prop].curves.size())
00141 {
00142 QString finalName = curvNames.at(i) + QString(" (%1)").arg(linkCont[cont].id);
00143
00144 QwtPlotCurve * qwtpc = new QwtPlotCurve(finalName);
00145 if (byTime) linkCont[cont].properties[prop].curves.insert(i, Curve(curvNames.at(i), qwtpc, 1));
00146 else linkCont[cont].properties[prop].curves.insert(i, Curve(curvNames.at(i), qwtpc, linkCont.size()+1));
00147 haveCurves = TRUE;
00148 }
00149 }
00150 }
00151
00152 void QVHistogramPlot::advancePlot()
00153 {
00154 if (!haveCurves)
00155 {
00156 std::cerr << "QVPlot internal error: early call to advancePlot." << std::endl;
00157 return;
00158 }
00159
00160
00161 int numValues = 0;
00162 for(int i = 0; i < linkCont.size(); i++)
00163 for(int j = 0; j < linkCont[i].properties.size(); j++) {
00164 for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00165 {
00166
00167 if (byTime) linkCont[i].properties[j].curves[k].history[0] = linkCont[i].properties[j].curves[k].temp[0];
00168 else linkCont[i].properties[j].curves[k].history[0] = linkCont[i].properties[j].curves[k].temp[(iterationIndex%(linkCont.size()+1))];
00169 }
00170 if (numValues < linkCont[i].properties[j].curves.size()) numValues = linkCont[i].properties[j].curves.size();
00171 }
00172
00173 QwtArray<QwtDoubleInterval> intervals(numValues);
00174 QwtArray<double> values(numValues);
00175
00176
00177 for(int i = 0; i < linkCont.size(); i++)
00178 for(int j = 0; j < linkCont[i].properties.size(); j++) {
00179 for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00180 {
00181 if (values[k] < linkCont[i].properties[j].curves[k].history[0]) values[k] = linkCont[i].properties[j].curves[k].history[0];
00182 intervals[k] = QwtDoubleInterval(double(k)-0.5, double(k+1)-0.5);
00183 }
00184 }
00185
00186
00187 int scaleShow = MAX(numValues/maxAxisNumbers, 1);
00188 setAxisScaleDiv(QwtPlot::xBottom, axisScaleEngine(QwtPlot::xBottom)->divideScale(-0.5, double(numValues)-0.5, 1, 1, scaleShow));
00189
00190 histItem.setData(QwtIntervalData(intervals, values));
00191
00192
00193 if (max == 0)
00194 {
00195 for(int i = 0; i < linkCont.size(); i++)
00196 for(int j = 0; j < linkCont[i].properties.size(); j++)
00197 for(int k = 0; k < linkCont[i].properties[j].curves.size(); k++)
00198 if (max < linkCont[i].properties[j].curves[k].history[0]) max = linkCont[i].properties[j].curves[k].history[0];
00199 max = 1.1 *max;
00200 setAxisScale(QwtPlot::yLeft, min, max);
00201 max = 0;
00202 }
00203 else setAxisScale(QwtPlot::yLeft, min, max);
00204
00205
00206 replot();
00207 }
00208
00209
00210
00211 void QVHistogramPlot::resizeEvent(QResizeEvent * e)
00212 {
00213 QVPlot::resizeEvent(e);
00214 maxAxisNumbers = e->size().width() / 50;
00215 }
00216