##// END OF EJS Templates
Changed QCustomPlot data from QMap to QVector....
jeandet -
r3:d10d160ab523 default
parent child
Show More
@@ -13,8 +13,12 TEMPLATE = app
13
13
14 INCLUDEPATH += src/QCustomPlot src
14 INCLUDEPATH += src/QCustomPlot src
15
15
16 QMAKE_CXXFLAGS += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx
16 QMAKE_CXXFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx
17 QMAKE_LFLAGS += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx
17 QMAKE_LFLAGS_RELEASE += -O5 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx
18
19 QMAKE_CXXFLAGS_DEBUG += -O0 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx
20 QMAKE_LFLAGS_DEBUG += -O0 -fopenmp -march=corei7-avx -mtune=corei7-avx -mavx
21
18
22
19 SOURCES += src/main.cpp\
23 SOURCES += src/main.cpp\
20 src/mainwindow.cpp \
24 src/mainwindow.cpp \
This diff has been collapsed as it changes many lines, (609 lines changed) Show them Hide them
@@ -5256,7 +5256,7 void QCPAxis::rescale(bool onlyVisiblePl
5256 if (p.at(i)->keyAxis() == this)
5256 if (p.at(i)->keyAxis() == this)
5257 plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain);
5257 plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain);
5258 else
5258 else
5259 plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain);
5259 plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain);
5260 if (currentFoundRange)
5260 if (currentFoundRange)
5261 {
5261 {
5262 if (!haveRange)
5262 if (!haveRange)
@@ -9369,6 +9369,7 void QCustomPlot::setMultiSelectModifier
9369 mMultiSelectModifier = modifier;
9369 mMultiSelectModifier = modifier;
9370 }
9370 }
9371
9371
9372
9372 /*!
9373 /*!
9373 Sets the viewport of this QCustomPlot. The Viewport is the area that the top level layout
9374 Sets the viewport of this QCustomPlot. The Viewport is the area that the top level layout
9374 (QCustomPlot::plotLayout()) uses as its rect. Normally, the viewport is the entire widget rect.
9375 (QCustomPlot::plotLayout()) uses as its rect. Normally, the viewport is the entire widget rect.
@@ -14502,7 +14503,7 QCPGraph::QCPGraph(QCPAxis *keyAxis, QCP
14502 QCPAbstractPlottable(keyAxis, valueAxis)
14503 QCPAbstractPlottable(keyAxis, valueAxis)
14503 {
14504 {
14504 mData = new QCPDataMap;
14505 mData = new QCPDataMap;
14505
14506 mDataVector = new QVector<QCPData>();
14506 setPen(QPen(Qt::blue, 0));
14507 setPen(QPen(Qt::blue, 0));
14507 setErrorPen(QPen(Qt::black));
14508 setErrorPen(QPen(Qt::black));
14508 setBrush(Qt::NoBrush);
14509 setBrush(Qt::NoBrush);
@@ -14515,6 +14516,7 QCPGraph::QCPGraph(QCPAxis *keyAxis, QCP
14515 setErrorBarSkipSymbol(true);
14516 setErrorBarSkipSymbol(true);
14516 setChannelFillGraph(0);
14517 setChannelFillGraph(0);
14517 setAdaptiveSampling(true);
14518 setAdaptiveSampling(true);
14519 setUseFastVectors(false);
14518 }
14520 }
14519
14521
14520 QCPGraph::~QCPGraph()
14522 QCPGraph::~QCPGraph()
@@ -14569,6 +14571,15 void QCPGraph::setData(const QVector<dou
14569 }
14571 }
14570 }
14572 }
14571
14573
14574 void QCPGraph::setData(QVector<QCPData> *data)
14575 {
14576 if(data!=mDataVector)
14577 {
14578 delete mDataVector;
14579 this->mDataVector = data;
14580 }
14581 }
14582
14572 /*!
14583 /*!
14573 Replaces the current data with the provided points in \a key and \a value pairs. Additionally the
14584 Replaces the current data with the provided points in \a key and \a value pairs. Additionally the
14574 symmetrical value error of the data points are set to the values in \a valueError.
14585 symmetrical value error of the data points are set to the values in \a valueError.
@@ -14869,6 +14880,11 void QCPGraph::setAdaptiveSampling(bool
14869 mAdaptiveSampling = enabled;
14880 mAdaptiveSampling = enabled;
14870 }
14881 }
14871
14882
14883 void QCPGraph::setUseFastVectors(bool useFastVectors)
14884 {
14885 mUseFastVectors=useFastVectors;
14886 }
14887
14872 /*!
14888 /*!
14873 Adds the provided data points in \a dataMap to the current data.
14889 Adds the provided data points in \a dataMap to the current data.
14874
14890
@@ -15095,7 +15111,7 void QCPGraph::rescaleValueAxis(bool onl
15095 void QCPGraph::draw(QCPPainter *painter)
15111 void QCPGraph::draw(QCPPainter *painter)
15096 {
15112 {
15097 if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
15113 if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
15098 if (mKeyAxis.data()->range().size() <= 0 || mData->isEmpty()) return;
15114 if (mKeyAxis.data()->range().size() <= 0 || (mData->isEmpty() && mDataVector->isEmpty())) return;
15099 if (mLineStyle == lsNone && mScatterStyle.isNone()) return;
15115 if (mLineStyle == lsNone && mScatterStyle.isNone()) return;
15100
15116
15101 // allocate line and (if necessary) point vectors:
15117 // allocate line and (if necessary) point vectors:
@@ -15239,7 +15255,10 void QCPGraph::getLinePlotData(QVector<Q
15239 if (!linePixelData) { qDebug() << Q_FUNC_INFO << "null pointer passed as linePixelData"; return; }
15255 if (!linePixelData) { qDebug() << Q_FUNC_INFO << "null pointer passed as linePixelData"; return; }
15240
15256
15241 QVector<QCPData> lineData;
15257 QVector<QCPData> lineData;
15242 getPreparedData(&lineData, scatterData);
15258 if(mUseFastVectors)
15259 getPreparedDataVector(&lineData, scatterData);
15260 else
15261 getPreparedData(&lineData, scatterData);
15243 linePixelData->reserve(lineData.size()+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill
15262 linePixelData->reserve(lineData.size()+2); // added 2 to reserve memory for lower/upper fill base points that might be needed for fill
15244 linePixelData->resize(lineData.size());
15263 linePixelData->resize(lineData.size());
15245
15264
@@ -15850,6 +15869,190 void QCPGraph::getPreparedData(QVector<Q
15850 }
15869 }
15851 }
15870 }
15852
15871
15872
15873 void QCPGraph::getPreparedDataVector(QVector<QCPData> *lineData, QVector<QCPData> *scatterData) const
15874 {
15875 QCPAxis *keyAxis = mKeyAxis.data();
15876 QCPAxis *valueAxis = mValueAxis.data();
15877 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
15878 // get visible data range:
15879 QVector<QCPData>::const_iterator lower, upper; // note that upper is the actual upper point, and not 1 step after the upper point
15880 getVisibleDataBoundsVector(lower, upper);
15881 if (lower == mDataVector->constEnd() || upper == mDataVector->constEnd())
15882 return;
15883
15884 // count points in visible range, taking into account that we only need to count to the limit maxCount if using adaptive sampling:
15885 int maxCount = std::numeric_limits<int>::max();
15886 if (mAdaptiveSampling)
15887 {
15888 int keyPixelSpan = qAbs(keyAxis->coordToPixel((*lower).key)-keyAxis->coordToPixel((*upper).key));
15889 maxCount = 2*keyPixelSpan+2;
15890 }
15891 int dataCount = countDataInBoundsVector(lower, upper, maxCount);
15892
15893 if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average
15894 {
15895 if (lineData)
15896 {
15897 QVector<QCPData>::const_iterator it = lower;
15898 QVector<QCPData>::const_iterator upperEnd = upper+1;
15899 double minValue = (*it).value;
15900 double maxValue = (*it).value;
15901 QVector<QCPData>::const_iterator currentIntervalFirstPoint = it;
15902 int reversedFactor = keyAxis->rangeReversed() != (keyAxis->orientation()==Qt::Vertical) ? -1 : 1; // is used to calculate keyEpsilon pixel into the correct direction
15903 int reversedRound = keyAxis->rangeReversed() != (keyAxis->orientation()==Qt::Vertical) ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey
15904 double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel((*lower).key)+reversedRound));
15905 double lastIntervalEndKey = currentIntervalStartKey;
15906 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates
15907 bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes)
15908 int intervalDataCount = 1;
15909 ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect
15910 while (it != upperEnd)
15911 {
15912 if ((*it).key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary
15913 {
15914 if ((*it).value < minValue)
15915 minValue = (*it).value;
15916 else if ((*it).value > maxValue)
15917 maxValue = (*it).value;
15918 ++intervalDataCount;
15919 } else // new pixel interval started
15920 {
15921 if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster
15922 {
15923 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point
15924 lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.2, (*currentIntervalFirstPoint).value));
15925 lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue));
15926 lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue));
15927 if ((*it).key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point
15928 lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.8, (*(it-1)).value));
15929 } else
15930 lineData->append(QCPData((*currentIntervalFirstPoint).key, (*currentIntervalFirstPoint).value));
15931 lastIntervalEndKey = (*(it-1)).key;
15932 minValue = (*it).value;
15933 maxValue = (*it).value;
15934 currentIntervalFirstPoint = it;
15935 currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel((*it).key)+reversedRound));
15936 if (keyEpsilonVariable)
15937 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
15938 intervalDataCount = 1;
15939 }
15940 ++it;
15941 }
15942 // handle last interval:
15943 if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster
15944 {
15945 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point
15946 lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.2, (*currentIntervalFirstPoint).value));
15947 lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue));
15948 lineData->append(QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue));
15949 } else
15950 lineData->append(QCPData((*currentIntervalFirstPoint).key, (*currentIntervalFirstPoint).value));
15951 }
15952
15953 if (scatterData)
15954 {
15955 double valueMaxRange = valueAxis->range().upper;
15956 double valueMinRange = valueAxis->range().lower;
15957 QVector<QCPData>::const_iterator it = lower;
15958 QVector<QCPData>::const_iterator upperEnd = upper+1;
15959 double minValue = (*it).value;
15960 double maxValue = (*it).value;
15961 QVector<QCPData>::const_iterator minValueIt = it;
15962 QVector<QCPData>::const_iterator maxValueIt = it;
15963 QVector<QCPData>::const_iterator currentIntervalStart = it;
15964 int reversedFactor = keyAxis->rangeReversed() ? -1 : 1; // is used to calculate keyEpsilon pixel into the correct direction
15965 int reversedRound = keyAxis->rangeReversed() ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey
15966 double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel((*lower).key)+reversedRound));
15967 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates
15968 bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes)
15969 int intervalDataCount = 1;
15970 ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect
15971 while (it != upperEnd)
15972 {
15973 if ((*it).key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary
15974 {
15975 if ((*it).value < minValue && (*it).value > valueMinRange && (*it).value < valueMaxRange)
15976 {
15977 minValue = (*it).value;
15978 minValueIt = it;
15979 } else if ((*it).value > maxValue && (*it).value > valueMinRange && (*it).value < valueMaxRange)
15980 {
15981 maxValue = (*it).value;
15982 maxValueIt = it;
15983 }
15984 ++intervalDataCount;
15985 } else // new pixel started
15986 {
15987 if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them
15988 {
15989 // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot):
15990 double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue));
15991 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average
15992 QVector<QCPData>::const_iterator intervalIt = currentIntervalStart;
15993 int c = 0;
15994 while (intervalIt != it)
15995 {
15996 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && (*intervalIt).value > valueMinRange && (*intervalIt).value < valueMaxRange)
15997 scatterData->append((*intervalIt));
15998 ++c;
15999 ++intervalIt;
16000 }
16001 } else if ((*currentIntervalStart).value > valueMinRange && (*currentIntervalStart).value < valueMaxRange)
16002 scatterData->append((*currentIntervalStart));
16003 minValue = (*it).value;
16004 maxValue = (*it).value;
16005 currentIntervalStart = it;
16006 currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel((*it).key)+reversedRound));
16007 if (keyEpsilonVariable)
16008 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
16009 intervalDataCount = 1;
16010 }
16011 ++it;
16012 }
16013 // handle last interval:
16014 if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them
16015 {
16016 // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot):
16017 double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue));
16018 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average
16019 QVector<QCPData>::const_iterator intervalIt = currentIntervalStart;
16020 int c = 0;
16021 while (intervalIt != it)
16022 {
16023 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && (*intervalIt).value > valueMinRange && (*intervalIt).value < valueMaxRange)
16024 scatterData->append((*intervalIt));
16025 ++c;
16026 ++intervalIt;
16027 }
16028 } else if ((*currentIntervalStart).value > valueMinRange && (*currentIntervalStart).value < valueMaxRange)
16029 scatterData->append(*currentIntervalStart);
16030 }
16031 } else // don't use adaptive sampling algorithm, transfer points one-to-one from the map into the output parameters
16032 {
16033 QVector<QCPData> *dataVector = 0;
16034 if (lineData)
16035 {
16036 dataVector = lineData;
16037 }
16038 else if (scatterData)
16039 dataVector = scatterData;
16040 if (dataVector)
16041 {
16042 QVector<QCPData>::const_iterator it = lower;
16043 QVector<QCPData>::const_iterator upperEnd = upper+1;
16044 dataVector->reserve(dataCount+2); // +2 for possible fill end points
16045 while (it != upperEnd)
16046 {
16047 dataVector->append(*it);
16048 ++it;
16049 }
16050 }
16051 if (lineData && scatterData)
16052 *scatterData = *dataVector;
16053 }
16054 }
16055
15853 /*! \internal
16056 /*! \internal
15854
16057
15855 called by the scatter drawing function (\ref drawScatterPlot) to draw the error bars on one data
16058 called by the scatter drawing function (\ref drawScatterPlot) to draw the error bars on one data
@@ -15988,6 +16191,187 void QCPGraph::getVisibleDataBounds(QCPD
15988 upper = (highoutlier ? ubound : ubound-1); // data point range that will be actually drawn
16191 upper = (highoutlier ? ubound : ubound-1); // data point range that will be actually drawn
15989 }
16192 }
15990
16193
16194
16195
16196
16197 QVector<QCPData>::const_iterator __lowerBoundDico(QVector<QCPData>* vector,double key)
16198 {
16199 int DX=vector->size()/2;
16200 int pos=DX;
16201 if(key>=((*vector)[vector->length()-1].key))
16202 return vector->constEnd();
16203 if(key<=((*vector)[0].key))
16204 return vector->constBegin();
16205 while (DX>1)
16206 {
16207 DX=DX/2;
16208 if((*vector)[pos].key > key)
16209 {
16210 pos-=DX;
16211 }
16212 else
16213 {
16214 pos+=DX;
16215 }
16216 }
16217 return vector->constBegin()+pos+1;
16218 }
16219
16220
16221 QVector<QCPData>::const_iterator __upperBoundDico(QVector<QCPData>* vector,double key)
16222 {
16223 int DX=vector->size()/2;
16224 int pos=DX;
16225 if(key>=((*vector)[vector->length()-1].key))
16226 return vector->constEnd();
16227 if(key<=((*vector)[0].key))
16228 return vector->constBegin();
16229 while (DX>1)
16230 {
16231 DX=DX/2;
16232 if((*vector)[pos].key > key)
16233 {
16234 pos-=DX;
16235 }
16236 else
16237 {
16238 pos+=DX;
16239 }
16240 }
16241 if((*vector)[pos].key >= key)
16242 return vector->constBegin()+pos;
16243 return vector->constBegin()+pos+1;
16244 }
16245
16246 QVector<QCPData>::const_iterator __lowerBound(QVector<QCPData>* vector,double key)
16247 {
16248 if(vector->length())
16249 {
16250 double min=(*vector)[0].key,max=(*vector)[vector->length()-1].key;
16251 int speculated=(int)((key/(max-min))*(vector->length()-1));
16252 double speculatedKey=(*vector)[speculated].key;
16253 double prevKey;
16254 double nextKey;
16255 if(speculated>0)
16256 prevKey= (*vector)[speculated-1].key;
16257 else
16258 prevKey=speculatedKey;
16259 if(speculated<vector->count()-2)
16260 nextKey = (*vector)[speculated+1].key;
16261 else
16262 nextKey=speculated;
16263
16264 if(key>=max)
16265 return vector->constEnd();
16266 if(key<=min)
16267 return vector->constBegin();
16268
16269 while ((speculatedKey!=key) && !( (speculatedKey>key) && (prevKey<key) ) )
16270 {
16271 if(Q_UNLIKELY((speculatedKey>key) && (prevKey<key)))
16272 {
16273 break;
16274 }
16275 if(Q_UNLIKELY((speculatedKey<key) && (nextKey>key)))
16276 {
16277 speculated++;
16278 break;
16279 }
16280 if(speculatedKey > key)
16281 max=speculatedKey;
16282 else
16283 min=speculatedKey;
16284 if(speculated>0)
16285 prevKey= (*vector)[speculated-1].key;
16286 else
16287 prevKey=speculatedKey;
16288 if(speculated<vector->count()-2)
16289 nextKey = (*vector)[speculated+1].key;
16290 else
16291 nextKey=speculated;
16292 speculated=(int)((key/(max-min))*(vector->length()-1));
16293 speculatedKey=(*vector)[speculated].key;
16294 }
16295 if(speculatedKey==key)
16296 return vector->constBegin()+speculated+1;
16297 else
16298 return vector->constBegin()+speculated;
16299 }
16300 return vector->constBegin();
16301 }
16302
16303 QVector<QCPData>::const_iterator __upperBound(QVector<QCPData>* vector,double key)
16304 {
16305 if(vector->length())
16306 {
16307 double min=(*vector)[0].key,max=(*vector)[vector->length()-1].key;
16308 int speculated=(int)((key/(max-min))*(vector->length()-1));
16309 double speculatedKey=(*vector)[speculated].key;
16310 double prevKey;
16311 double nextKey;
16312 if(speculated>0)
16313 prevKey= (*vector)[speculated-1].key;
16314 else
16315 prevKey=speculatedKey;
16316 if(speculated<vector->count()-2)
16317 nextKey = (*vector)[speculated+1].key;
16318 else
16319 nextKey=speculated;
16320
16321 if(key>=max)
16322 return vector->constEnd();
16323 if(key<=min)
16324 return vector->constBegin();
16325
16326 while ((speculatedKey!=key) && !( (speculatedKey>key) && (prevKey<key) ) )
16327 {
16328 if(Q_UNLIKELY((speculatedKey>key) && (prevKey<key)))
16329 {
16330 break;
16331 }
16332 if(Q_UNLIKELY((speculatedKey<key) && (nextKey>key)))
16333 {
16334 speculated++;
16335 break;
16336 }
16337 if(speculatedKey > key)
16338 max=speculatedKey;
16339 else
16340 min=speculatedKey;
16341 if(speculated>0)
16342 prevKey= (*vector)[speculated-1].key;
16343 else
16344 prevKey=speculatedKey;
16345 if(speculated<vector->count()-2)
16346 nextKey = (*vector)[speculated+1].key;
16347 else
16348 nextKey=speculated;
16349 speculated=(int)((key/(max-min))*(vector->length()-1));
16350 speculatedKey=(*vector)[speculated].key;
16351 }
16352 return vector->constBegin()+speculated;
16353 }
16354 return vector->constEnd();
16355 }
16356
16357 void QCPGraph::getVisibleDataBoundsVector(QVector<QCPData>::const_iterator &lower, QVector<QCPData>::const_iterator &upper) const
16358 {
16359 if (!mKeyAxis) { qDebug() << Q_FUNC_INFO << "invalid key axis"; return; }
16360 if (mDataVector->isEmpty())
16361 {
16362 lower = mDataVector->constEnd();
16363 upper = mDataVector->constEnd();
16364 return;
16365 }
16366 QVector<QCPData>::const_iterator lbound = __lowerBoundDico(mDataVector,mKeyAxis.data()->range().lower);
16367 QVector<QCPData>::const_iterator ubound = __lowerBoundDico(mDataVector,mKeyAxis.data()->range().upper);
16368 bool lowoutlier = lbound != mDataVector->constBegin(); // indicates whether there exist points below axis range
16369 bool highoutlier = ubound != mDataVector->constEnd(); // indicates whether there exist points above axis range
16370
16371 lower = (lowoutlier ? lbound-1 : lbound); // data point range that will be actually drawn
16372 upper = (highoutlier ? ubound : ubound-1); // data point range that will be actually drawn
16373 }
16374
15991 /*! \internal
16375 /*! \internal
15992
16376
15993 Counts the number of data points between \a lower and \a upper (including them), up to a maximum
16377 Counts the number of data points between \a lower and \a upper (including them), up to a maximum
@@ -16012,6 +16396,20 int QCPGraph::countDataInBounds(const QC
16012 return count;
16396 return count;
16013 }
16397 }
16014
16398
16399 int QCPGraph::countDataInBoundsVector(const QVector<QCPData>::const_iterator &lower, const QVector<QCPData>::const_iterator &upper, int maxCount) const
16400 {
16401 if (upper == mDataVector->constEnd() && lower == mDataVector->constEnd())
16402 return 0;
16403 QVector<QCPData>::const_iterator it = lower;
16404 int count = 1;
16405 while (it != upper && count < maxCount)
16406 {
16407 ++it;
16408 ++count;
16409 }
16410 return count;
16411 }
16412
16015 /*! \internal
16413 /*! \internal
16016
16414
16017 The line data vector generated by e.g. getLinePlotData contains only the line that connects the
16415 The line data vector generated by e.g. getLinePlotData contains only the line that connects the
@@ -16497,6 +16895,8 QCPRange QCPGraph::getKeyRange(bool &fou
16497 {
16895 {
16498 // just call the specialized version which takes an additional argument whether error bars
16896 // just call the specialized version which takes an additional argument whether error bars
16499 // should also be taken into consideration for range calculation. We set this to true here.
16897 // should also be taken into consideration for range calculation. We set this to true here.
16898 if(mUseFastVectors)
16899 return getKeyRangeVector(foundRange, inSignDomain, true);
16500 return getKeyRange(foundRange, inSignDomain, true);
16900 return getKeyRange(foundRange, inSignDomain, true);
16501 }
16901 }
16502
16902
@@ -16505,6 +16905,8 QCPRange QCPGraph::getValueRange(bool &f
16505 {
16905 {
16506 // just call the specialized version which takes an additional argument whether error bars
16906 // just call the specialized version which takes an additional argument whether error bars
16507 // should also be taken into consideration for range calculation. We set this to true here.
16907 // should also be taken into consideration for range calculation. We set this to true here.
16908 if(mUseFastVectors)
16909 return getValueRangeVector(foundRange, inSignDomain, true);
16508 return getValueRange(foundRange, inSignDomain, true);
16910 return getValueRange(foundRange, inSignDomain, true);
16509 }
16911 }
16510
16912
@@ -16614,6 +17016,106 QCPRange QCPGraph::getKeyRange(bool &fou
16614 return range;
17016 return range;
16615 }
17017 }
16616
17018
17019 QCPRange QCPGraph::getKeyRangeVector(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const
17020 {
17021 QCPRange range;
17022 bool haveLower = false;
17023 bool haveUpper = false;
17024
17025 double current, currentErrorMinus, currentErrorPlus;
17026
17027 if (inSignDomain == sdBoth) // range may be anywhere
17028 {
17029 QVector<QCPData>::const_iterator it = mDataVector->constBegin();
17030 while (it != mDataVector->constEnd())
17031 {
17032 current = (*it).key;
17033 currentErrorMinus = (includeErrors ? (*it).keyErrorMinus : 0);
17034 currentErrorPlus = (includeErrors ? (*it).keyErrorPlus : 0);
17035 if (current-currentErrorMinus < range.lower || !haveLower)
17036 {
17037 range.lower = current-currentErrorMinus;
17038 haveLower = true;
17039 }
17040 if (current+currentErrorPlus > range.upper || !haveUpper)
17041 {
17042 range.upper = current+currentErrorPlus;
17043 haveUpper = true;
17044 }
17045 ++it;
17046 }
17047 } else if (inSignDomain == sdNegative) // range may only be in the negative sign domain
17048 {
17049 QVector<QCPData>::const_iterator it = mDataVector->constBegin();
17050 while (it != mDataVector->constEnd())
17051 {
17052 current = (*it).key;
17053 currentErrorMinus = (includeErrors ? (*it).keyErrorMinus : 0);
17054 currentErrorPlus = (includeErrors ? (*it).keyErrorPlus : 0);
17055 if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus < 0)
17056 {
17057 range.lower = current-currentErrorMinus;
17058 haveLower = true;
17059 }
17060 if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus < 0)
17061 {
17062 range.upper = current+currentErrorPlus;
17063 haveUpper = true;
17064 }
17065 if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to geht that point.
17066 {
17067 if ((current < range.lower || !haveLower) && current < 0)
17068 {
17069 range.lower = current;
17070 haveLower = true;
17071 }
17072 if ((current > range.upper || !haveUpper) && current < 0)
17073 {
17074 range.upper = current;
17075 haveUpper = true;
17076 }
17077 }
17078 ++it;
17079 }
17080 } else if (inSignDomain == sdPositive) // range may only be in the positive sign domain
17081 {
17082 QVector<QCPData>::const_iterator it = mDataVector->constBegin();
17083 while (it != mDataVector->constEnd())
17084 {
17085 current = (*it).key;
17086 currentErrorMinus = (includeErrors ? (*it).keyErrorMinus : 0);
17087 currentErrorPlus = (includeErrors ? (*it).keyErrorPlus : 0);
17088 if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus > 0)
17089 {
17090 range.lower = current-currentErrorMinus;
17091 haveLower = true;
17092 }
17093 if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus > 0)
17094 {
17095 range.upper = current+currentErrorPlus;
17096 haveUpper = true;
17097 }
17098 if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to get that point.
17099 {
17100 if ((current < range.lower || !haveLower) && current > 0)
17101 {
17102 range.lower = current;
17103 haveLower = true;
17104 }
17105 if ((current > range.upper || !haveUpper) && current > 0)
17106 {
17107 range.upper = current;
17108 haveUpper = true;
17109 }
17110 }
17111 ++it;
17112 }
17113 }
17114
17115 foundRange = haveLower && haveUpper;
17116 return range;
17117 }
17118
16617 /*! \overload
17119 /*! \overload
16618
17120
16619 Allows to specify whether the error bars should be included in the range calculation.
17121 Allows to specify whether the error bars should be included in the range calculation.
@@ -16720,6 +17222,105 QCPRange QCPGraph::getValueRange(bool &f
16720 return range;
17222 return range;
16721 }
17223 }
16722
17224
17225 QCPRange QCPGraph::getValueRangeVector(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const
17226 {
17227 QCPRange range;
17228 bool haveLower = false;
17229 bool haveUpper = false;
17230
17231 double current, currentErrorMinus, currentErrorPlus;
17232
17233 if (inSignDomain == sdBoth) // range may be anywhere
17234 {
17235 QVector<QCPData>::const_iterator it = mDataVector->constBegin();
17236 while (it != mDataVector->constEnd())
17237 {
17238 current = (*it).value;
17239 currentErrorMinus = (includeErrors ? (*it).valueErrorMinus : 0);
17240 currentErrorPlus = (includeErrors ? (*it).valueErrorPlus : 0);
17241 if (current-currentErrorMinus < range.lower || !haveLower)
17242 {
17243 range.lower = current-currentErrorMinus;
17244 haveLower = true;
17245 }
17246 if (current+currentErrorPlus > range.upper || !haveUpper)
17247 {
17248 range.upper = current+currentErrorPlus;
17249 haveUpper = true;
17250 }
17251 ++it;
17252 }
17253 } else if (inSignDomain == sdNegative) // range may only be in the negative sign domain
17254 {
17255 QVector<QCPData>::const_iterator it = mDataVector->constBegin();
17256 while (it != mDataVector->constEnd())
17257 {
17258 current = (*it).value;
17259 currentErrorMinus = (includeErrors ? (*it).valueErrorMinus : 0);
17260 currentErrorPlus = (includeErrors ? (*it).valueErrorPlus : 0);
17261 if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus < 0)
17262 {
17263 range.lower = current-currentErrorMinus;
17264 haveLower = true;
17265 }
17266 if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus < 0)
17267 {
17268 range.upper = current+currentErrorPlus;
17269 haveUpper = true;
17270 }
17271 if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to get that point.
17272 {
17273 if ((current < range.lower || !haveLower) && current < 0)
17274 {
17275 range.lower = current;
17276 haveLower = true;
17277 }
17278 if ((current > range.upper || !haveUpper) && current < 0)
17279 {
17280 range.upper = current;
17281 haveUpper = true;
17282 }
17283 }
17284 ++it;
17285 }
17286 } else if (inSignDomain == sdPositive) // range may only be in the positive sign domain
17287 {
17288 QVector<QCPData>::const_iterator it = mDataVector->constBegin();
17289 while (it != mDataVector->constEnd())
17290 {
17291 current = (*it).value;
17292 currentErrorMinus = (includeErrors ? (*it).valueErrorMinus : 0);
17293 currentErrorPlus = (includeErrors ? (*it).valueErrorPlus : 0);
17294 if ((current-currentErrorMinus < range.lower || !haveLower) && current-currentErrorMinus > 0)
17295 {
17296 range.lower = current-currentErrorMinus;
17297 haveLower = true;
17298 }
17299 if ((current+currentErrorPlus > range.upper || !haveUpper) && current+currentErrorPlus > 0)
17300 {
17301 range.upper = current+currentErrorPlus;
17302 haveUpper = true;
17303 }
17304 if (includeErrors) // in case point is in valid sign domain but errobars stretch beyond it, we still want to geht that point.
17305 {
17306 if ((current < range.lower || !haveLower) && current > 0)
17307 {
17308 range.lower = current;
17309 haveLower = true;
17310 }
17311 if ((current > range.upper || !haveUpper) && current > 0)
17312 {
17313 range.upper = current;
17314 haveUpper = true;
17315 }
17316 }
17317 ++it;
17318 }
17319 }
17320
17321 foundRange = haveLower && haveUpper;
17322 return range;
17323 }
16723
17324
16724 ////////////////////////////////////////////////////////////////////////////////////////////////////
17325 ////////////////////////////////////////////////////////////////////////////////////////////////////
16725 //////////////////// QCPCurveData
17326 //////////////////// QCPCurveData
@@ -1862,6 +1862,7 protected:
1862 QCPLayer *mCurrentLayer;
1862 QCPLayer *mCurrentLayer;
1863 QCP::PlottingHints mPlottingHints;
1863 QCP::PlottingHints mPlottingHints;
1864 Qt::KeyboardModifier mMultiSelectModifier;
1864 Qt::KeyboardModifier mMultiSelectModifier;
1865 bool mUseFastVectors;
1865
1866
1866 // non-property members:
1867 // non-property members:
1867 QPixmap mPaintBuffer;
1868 QPixmap mPaintBuffer;
@@ -2538,10 +2539,12 public:
2538 bool errorBarSkipSymbol() const { return mErrorBarSkipSymbol; }
2539 bool errorBarSkipSymbol() const { return mErrorBarSkipSymbol; }
2539 QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); }
2540 QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); }
2540 bool adaptiveSampling() const { return mAdaptiveSampling; }
2541 bool adaptiveSampling() const { return mAdaptiveSampling; }
2542 bool useFastVectors() const { return mUseFastVectors; }
2541
2543
2542 // setters:
2544 // setters:
2543 void setData(QCPDataMap *data, bool copy=false);
2545 void setData(QCPDataMap *data, bool copy=false);
2544 void setData(const QVector<double> &key, const QVector<double> &value);
2546 void setData(const QVector<double> &key, const QVector<double> &value);
2547 void setData(QVector<QCPData> *data);
2545 void setDataKeyError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyError);
2548 void setDataKeyError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyError);
2546 void setDataKeyError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyErrorMinus, const QVector<double> &keyErrorPlus);
2549 void setDataKeyError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyErrorMinus, const QVector<double> &keyErrorPlus);
2547 void setDataValueError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &valueError);
2550 void setDataValueError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &valueError);
@@ -2556,6 +2559,7 public:
2556 void setErrorBarSkipSymbol(bool enabled);
2559 void setErrorBarSkipSymbol(bool enabled);
2557 void setChannelFillGraph(QCPGraph *targetGraph);
2560 void setChannelFillGraph(QCPGraph *targetGraph);
2558 void setAdaptiveSampling(bool enabled);
2561 void setAdaptiveSampling(bool enabled);
2562 void setUseFastVectors(bool useFastVectors);
2559
2563
2560 // non-property methods:
2564 // non-property methods:
2561 void addData(const QCPDataMap &dataMap);
2565 void addData(const QCPDataMap &dataMap);
@@ -2580,6 +2584,7 public:
2580 protected:
2584 protected:
2581 // property members:
2585 // property members:
2582 QCPDataMap *mData;
2586 QCPDataMap *mData;
2587 QVector<QCPData>* mDataVector;
2583 QPen mErrorPen;
2588 QPen mErrorPen;
2584 LineStyle mLineStyle;
2589 LineStyle mLineStyle;
2585 QCPScatterStyle mScatterStyle;
2590 QCPScatterStyle mScatterStyle;
@@ -2588,6 +2593,7 protected:
2588 bool mErrorBarSkipSymbol;
2593 bool mErrorBarSkipSymbol;
2589 QPointer<QCPGraph> mChannelFillGraph;
2594 QPointer<QCPGraph> mChannelFillGraph;
2590 bool mAdaptiveSampling;
2595 bool mAdaptiveSampling;
2596 bool mUseFastVectors;
2591
2597
2592 // reimplemented virtual methods:
2598 // reimplemented virtual methods:
2593 virtual void draw(QCPPainter *painter);
2599 virtual void draw(QCPPainter *painter);
@@ -2595,8 +2601,9 protected:
2595 virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2601 virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2596 virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2602 virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2597 virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface
2603 virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface
2604 virtual QCPRange getKeyRangeVector(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface
2598 virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface
2605 virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface
2599
2606 virtual QCPRange getValueRangeVector(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const;
2600 // introduced virtual methods:
2607 // introduced virtual methods:
2601 virtual void drawFill(QCPPainter *painter, QVector<QPointF> *lineData) const;
2608 virtual void drawFill(QCPPainter *painter, QVector<QPointF> *lineData) const;
2602 virtual void drawScatterPlot(QCPPainter *painter, QVector<QCPData> *scatterData) const;
2609 virtual void drawScatterPlot(QCPPainter *painter, QVector<QCPData> *scatterData) const;
@@ -2605,6 +2612,7 protected:
2605
2612
2606 // non-virtual methods:
2613 // non-virtual methods:
2607 void getPreparedData(QVector<QCPData> *lineData, QVector<QCPData> *scatterData) const;
2614 void getPreparedData(QVector<QCPData> *lineData, QVector<QCPData> *scatterData) const;
2615 void getPreparedDataVector(QVector<QCPData> *lineData, QVector<QCPData> *scatterData) const;
2608 void getPlotData(QVector<QPointF> *lineData, QVector<QCPData> *scatterData) const;
2616 void getPlotData(QVector<QPointF> *lineData, QVector<QCPData> *scatterData) const;
2609 void getScatterPlotData(QVector<QCPData> *scatterData) const;
2617 void getScatterPlotData(QVector<QCPData> *scatterData) const;
2610 void getLinePlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2618 void getLinePlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
@@ -2614,7 +2622,9 protected:
2614 void getImpulsePlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2622 void getImpulsePlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2615 void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const;
2623 void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const;
2616 void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const;
2624 void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const;
2625 void getVisibleDataBoundsVector(QVector<QCPData>::const_iterator &lower, QVector<QCPData>::const_iterator &upper) const;
2617 int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const;
2626 int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const;
2627 int countDataInBoundsVector(const QVector<QCPData>::const_iterator &lower, const QVector<QCPData>::const_iterator &upper, int maxCount) const;
2618 void addFillBasePoints(QVector<QPointF> *lineData) const;
2628 void addFillBasePoints(QVector<QPointF> *lineData) const;
2619 void removeFillBasePoints(QVector<QPointF> *lineData) const;
2629 void removeFillBasePoints(QVector<QPointF> *lineData) const;
2620 QPointF lowerFillBasePoint(double lowerKey) const;
2630 QPointF lowerFillBasePoint(double lowerKey) const;
@@ -43,7 +43,6 SocExplorerPlot::SocExplorerPlot(QWidget
43 this->m_plot->setNoAntialiasingOnDrag(true);
43 this->m_plot->setNoAntialiasingOnDrag(true);
44 this->show();
44 this->show();
45 this->m_plot->legend->setVisible(true);
45 this->m_plot->legend->setVisible(true);
46
47 }
46 }
48
47
49 SocExplorerPlot::~SocExplorerPlot()
48 SocExplorerPlot::~SocExplorerPlot()
@@ -117,6 +116,11 void SocExplorerPlot::setAdaptativeSampl
117 this->m_plot->graph(graphIndex)->setAdaptiveSampling(enable);
116 this->m_plot->graph(graphIndex)->setAdaptiveSampling(enable);
118 }
117 }
119
118
119 void SocExplorerPlot::setUseFastVector(int graphIndex, bool enable)
120 {
121 this->m_plot->graph(graphIndex)->setUseFastVectors(enable);
122 }
123
120 int SocExplorerPlot::addGraph()
124 int SocExplorerPlot::addGraph()
121 {
125 {
122 this->m_plot->addGraph();
126 this->m_plot->addGraph();
@@ -192,6 +196,16 void SocExplorerPlot::setGraphData(int g
192 this->m_plot->replot();
196 this->m_plot->replot();
193 }
197 }
194
198
199 void SocExplorerPlot::setGraphData(int graphIndex,QVector<QCPData> *data, bool replot)
200 {
201 if((graphIndex<this->m_plot->graphCount()))// && (x.at(0).type()==QVariant::Double))
202 {
203 this->m_plot->graph(graphIndex)->setData(data);
204 }
205 if(replot)
206 this->m_plot->replot();
207 }
208
195 void SocExplorerPlot::addGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y)
209 void SocExplorerPlot::addGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y)
196 {
210 {
197 if((graphIndex<this->m_plot->graphCount()) && (x.count()==y.count()))// && (x.at(0).type()==QVariant::Double))
211 if((graphIndex<this->m_plot->graphCount()) && (x.count()==y.count()))// && (x.at(0).type()==QVariant::Double))
@@ -43,12 +43,14 public:
43 void setLegendFont(QFont font);
43 void setLegendFont(QFont font);
44 void setLegendSelectedFont(QFont font);
44 void setLegendSelectedFont(QFont font);
45 void setAdaptativeSampling(int graphIndex,bool enable);
45 void setAdaptativeSampling(int graphIndex,bool enable);
46 void setUseFastVector(int graphIndex,bool enable);
46 int addGraph();
47 int addGraph();
47 bool removeGraph(int graphIndex);
48 bool removeGraph(int graphIndex);
48 void removeAllGraphs();
49 void removeAllGraphs();
49 void setGraphName(int graphIndex,QString name);
50 void setGraphName(int graphIndex,QString name);
50 void setGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y);
51 void setGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y);
51 void setGraphData(int graphIndex, QCPDataMap* data,bool copy = true,bool replot=true);
52 void setGraphData(int graphIndex, QCPDataMap* data,bool copy = true,bool replot=true);
53 void setGraphData(int graphIndex, QVector<QCPData> *data, bool replot);
52 void addGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y);
54 void addGraphData(int graphIndex, QList<QVariant> x, QList<QVariant> y);
53 void addGraphData(int graphIndex, QVariant x, QVariant y);
55 void addGraphData(int graphIndex, QVariant x, QVariant y);
54 void setGraphPen(int graphIndex,QPen pen);
56 void setGraphPen(int graphIndex,QPen pen);
@@ -36,11 +36,13 MainWindow::MainWindow(int OMP_THREADS,
36
36
37 connect(this->ui->addViewerQpb,SIGNAL(clicked()),this,SLOT(addFolderView()));
37 connect(this->ui->addViewerQpb,SIGNAL(clicked()),this,SLOT(addFolderView()));
38 connect(&this->fileReader,SIGNAL(dataReady(QCPDataMap*,QCPDataMap*,QCPDataMap*)),this,SLOT(dataReady(QCPDataMap*,QCPDataMap*,QCPDataMap*)));
38 connect(&this->fileReader,SIGNAL(dataReady(QCPDataMap*,QCPDataMap*,QCPDataMap*)),this,SLOT(dataReady(QCPDataMap*,QCPDataMap*,QCPDataMap*)));
39 connect(&this->fileReader,SIGNAL(dataReady(QVector<QCPData>*,QVector<QCPData>*,QVector<QCPData>*)),this,SLOT(dataReady(QVector<QCPData>*,QVector<QCPData>*,QVector<QCPData>*)));
39 connect(this->ui->calendar,SIGNAL(activated(QDate)),this,SLOT(downloadData(QDate)));
40 connect(this->ui->calendar,SIGNAL(activated(QDate)),this,SLOT(downloadData(QDate)));
40 for(int i=0;i<3;i++)
41 for(int i=0;i<3;i++)
41 {
42 {
42 this->ui->Plot->addGraph();
43 this->ui->Plot->addGraph();
43 this->ui->Plot->setAdaptativeSampling(i,true);
44 this->ui->Plot->setAdaptativeSampling(i,true);
45 this->ui->Plot->setUseFastVector(i,true);
44 }
46 }
45 QPen pen = this->ui->Plot->getGraphPen(0);
47 QPen pen = this->ui->Plot->getGraphPen(0);
46 pen.setColor(Qt::blue);
48 pen.setColor(Qt::blue);
@@ -124,6 +126,23 void MainWindow::dataReady(QCPDataMap *c
124 this->ui->Plot->replot();
126 this->ui->Plot->replot();
125 }
127 }
126
128
129 void MainWindow::dataReady(QVector<QCPData> *ch1, QVector<QCPData> *ch2, QVector<QCPData> *ch3)
130 {
131 for(int i=0;i<OMP_THREADS;i++)
132 {
133 progressThreadIds[i]=-1;
134 }
135 this->progressWidget->hide();
136 this->ui->Plot->setGraphName(0,"MAG_X");
137 this->ui->Plot->setGraphName(1,"MAG_Y");
138 this->ui->Plot->setGraphName(2,"MAG_Z");
139 this->ui->Plot->setGraphData(0,ch1,false);
140 this->ui->Plot->setGraphData(1,ch2,false);
141 this->ui->Plot->setGraphData(2,ch3,false);
142 this->ui->Plot->rescaleAxis();
143 this->ui->Plot->replot();
144 }
145
127 void MainWindow::downloadData(const QDate & date )
146 void MainWindow::downloadData(const QDate & date )
128 {
147 {
129 QDate tmpDate;
148 QDate tmpDate;
@@ -49,6 +49,7 public slots:
49 void itemDoubleClicked(QListWidgetItem *item);
49 void itemDoubleClicked(QListWidgetItem *item);
50 void plotFile(const QString& File);
50 void plotFile(const QString& File);
51 void dataReady(QCPDataMap *ch1,QCPDataMap *ch2,QCPDataMap *ch3);
51 void dataReady(QCPDataMap *ch1,QCPDataMap *ch2,QCPDataMap *ch3);
52 void dataReady(QVector<QCPData> *ch1,QVector<QCPData> *ch2,QVector<QCPData> *ch3);
52 void downloadData(const QDate &date);
53 void downloadData(const QDate &date);
53 void updateProgress(int threadId,int percentProgress);
54 void updateProgress(int threadId,int percentProgress);
54 void addFolderView();
55 void addFolderView();
@@ -129,9 +129,12 void ThemisDataFile::run()
129 {
129 {
130 FILE* dataFile;
130 FILE* dataFile;
131 dataFile = fopen(fileName.toStdString().c_str(),"r");
131 dataFile = fopen(fileName.toStdString().c_str(),"r");
132 QCPDataMap *ch1=new QCPDataMap();
132 // QCPDataMap *ch1=new QCPDataMap();
133 QCPDataMap *ch2=new QCPDataMap();
133 // QCPDataMap *ch2=new QCPDataMap();
134 QCPDataMap *ch3=new QCPDataMap();
134 // QCPDataMap *ch3=new QCPDataMap();
135 QVector<QCPData> *ch1=new QVector<QCPData>();
136 QVector<QCPData> *ch2=new QVector<QCPData>();
137 QVector<QCPData> *ch3=new QVector<QCPData>();
135 QElapsedTimer timr;
138 QElapsedTimer timr;
136
139
137 double _x=0.0;
140 double _x=0.0;
@@ -157,19 +160,24 void ThemisDataFile::run()
157 timr.start();
160 timr.start();
158 for(int i=0;i<(FileSize/(58));i++)
161 for(int i=0;i<(FileSize/(58));i++)
159 {
162 {
160 // _x= i;
163 _x= i;
161 _x= __decodeTimeFromEpoch((i*58),(unsigned char*)line);
164 //_x= __decodeTimeFromEpoch((i*58),(unsigned char*)line);
162 data1.key=_x;
165 data1.key=_x;
163 data2.key=_x;
166 data2.key=_x;
164 data3.key=_x;
167 data3.key=_x;
165 data1.value=__decodeVal(((i*58)+27),(unsigned char*)line);
168 data1.value=__decodeVal(((i*58)+27),(unsigned char*)line);
166 data2.value=__decodeVal(((i*58)+38),(unsigned char*)line);
169 data2.value=__decodeVal(((i*58)+38),(unsigned char*)line);
167 data3.value=__decodeVal(((i*58)+49),(unsigned char*)line);
170 data3.value=__decodeVal(((i*58)+49),(unsigned char*)line);
168 ch1->insertMulti(_x,data1);
171
169 ch2->insertMulti(_x,data2);
172 //ch1->insertMulti(_x,data1);
170 ch3->insertMulti(_x,data3);
173 //ch2->insertMulti(_x,data2);
174 //ch3->insertMulti(_x,data3);
175 // x->append(_x);
176 ch1->append(data1);
177 ch2->append(data2);
178 ch3->append(data3);
171 curLine++;
179 curLine++;
172 if(lastLineUpdate++>8000)
180 if(lastLineUpdate++>20000)
173 {
181 {
174 lastLineUpdate=0;
182 lastLineUpdate=0;
175 int test=(curLine *100/ (lineCnt));
183 int test=(curLine *100/ (lineCnt));
@@ -35,6 +35,7 public:
35 void run();
35 void run();
36 signals:
36 signals:
37 void dataReady(QCPDataMap *ch1,QCPDataMap *ch2,QCPDataMap *ch3);
37 void dataReady(QCPDataMap *ch1,QCPDataMap *ch2,QCPDataMap *ch3);
38 void dataReady(QVector<QCPData> *ch1,QVector<QCPData> *ch2,QVector<QCPData> *ch3);
38 void updateProgress(int percentProgress);
39 void updateProgress(int percentProgress);
39 void updateProgress(int threadId,int percentProgress);
40 void updateProgress(int threadId,int percentProgress);
40 public slots:
41 public slots:
General Comments 0
You need to be logged in to leave comments. Login now