MCPcopy Create free account
hub / github.com/collin80/SavvyCAN / getOptimizedLineData

Method getOptimizedLineData

qcustomplot.cpp:20906–20984  ·  view source on GitHub ↗

! \internal Returns via \a lineData the data points that need to be visualized for this graph when plotting graph lines, taking into consideration the currently visible axis ranges and, if \ref setAdaptiveSampling is enabled, local point densities. The considered data can be restricted further by \a begin and \a end, e.g. to only plot a certain segment of the data (see \ref getDataSegme

Source from the content-addressed store, hash-verified

20904 \see getOptimizedScatterData
20905*/
20906void QCPGraph::getOptimizedLineData(QVector<QCPGraphData> *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const
20907{
20908 if (!lineData) return;
20909 QCPAxis *keyAxis = mKeyAxis.data();
20910 QCPAxis *valueAxis = mValueAxis.data();
20911 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
20912 if (begin == end) return;
20913
20914 int dataCount = end-begin;
20915 int maxCount = (std::numeric_limits<int>::max)();
20916 if (mAdaptiveSampling)
20917 {
20918 double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key));
20919 if (2*keyPixelSpan+2 < static_cast<double>((std::numeric_limits<int>::max)()))
20920 maxCount = 2*keyPixelSpan+2;
20921 }
20922
20923 if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average
20924 {
20925 QCPGraphDataContainer::const_iterator it = begin;
20926 double minValue = it->value;
20927 double maxValue = it->value;
20928 QCPGraphDataContainer::const_iterator currentIntervalFirstPoint = it;
20929 int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction
20930 int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey
20931 double currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(begin->key)+reversedRound));
20932 double lastIntervalEndKey = currentIntervalStartKey;
20933 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates
20934 bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes)
20935 int intervalDataCount = 1;
20936 ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect
20937 while (it != end)
20938 {
20939 if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary
20940 {
20941 if (it->value < minValue)
20942 minValue = it->value;
20943 else if (it->value > maxValue)
20944 maxValue = it->value;
20945 ++intervalDataCount;
20946 } else // new pixel interval started
20947 {
20948 if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster
20949 {
20950 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point
20951 lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value));
20952 lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.25, minValue));
20953 lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.75, maxValue));
20954 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
20955 lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.8, (it-1)->value));
20956 } else
20957 lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value));
20958 lastIntervalEndKey = (it-1)->key;
20959 minValue = it->value;
20960 maxValue = it->value;
20961 currentIntervalFirstPoint = it;
20962 currentIntervalStartKey = keyAxis->pixelToCoord((int)(keyAxis->coordToPixel(it->key)+reversedRound));
20963 if (keyEpsilonVariable)

Callers

nothing calls this directly

Calls 5

coordToPixelMethod · 0.80
pixelToCoordMethod · 0.80
appendMethod · 0.80
dataMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected