151 if (!qFuzzyIsNull(vLengthSqr)) {
152 double mu = v.
dot(*
this - start) / vLengthSqr;
154 return (*
this - start).lengthSquared();
156 return (*
this - end).lengthSquared();
158 return ((start + mu * v) - *
this).lengthSquared();
160 return (*
this - start).lengthSquared();
252 : QPainter(), mModes(pmDefault), mIsAntialiasing(false) {
266 : QPainter(device), mModes(pmDefault), mIsAntialiasing(false) {
268 QT_VERSION_CHECK(5, 0, \
272 if (isActive()) setRenderHint(QPainter::NonCosmeticDefaultPen);
283 QPainter::setPen(pen);
295 QPainter::setPen(
color);
307 QPainter::setPen(penStyle);
322 QPainter::drawLine(line);
324 QPainter::drawLine(line.toLine());
335 setRenderHint(QPainter::Antialiasing, enabled);
345 translate(-0.5, -0.5);
368 bool result = QPainter::begin(device);
370 QT_VERSION_CHECK(5, 0, \
374 if (
result) setRenderHint(QPainter::NonCosmeticDefaultPen);
385 if (!enabled &&
mModes.testFlag(mode))
387 else if (enabled && !
mModes.testFlag(mode))
418 qDebug() << Q_FUNC_INFO <<
"Unbalanced save/restore";
427 if (qFuzzyIsNull(pen().widthF())) {
534 double devicePixelRatio)
535 : mSize(
size), mDevicePixelRatio(devicePixelRatio), mInvalidated(true) {}
590 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
594 qDebug() << Q_FUNC_INFO
595 <<
"Device pixel ratios not supported for Qt versions before "
619 double devicePixelRatio)
629 result->setRenderHint(QPainter::Antialiasing);
635 if (painter && painter->isActive())
636 painter->drawPixmap(0, 0,
mBuffer);
638 qDebug() << Q_FUNC_INFO <<
"invalid or inactive painter passed";
648 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
652 qDebug() << Q_FUNC_INFO
653 <<
"Device pixel ratios not supported for Qt versions before "
663 #ifdef QCP_OPENGL_PBUFFER
690 QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(
const QSize &
size,
691 double devicePixelRatio,
695 mMultisamples(qMax(0, multisamples)) {
696 QCPPaintBufferGlPbuffer::reallocateBuffer();
699 QCPPaintBufferGlPbuffer::~QCPPaintBufferGlPbuffer() {
700 if (mGlPBuffer)
delete mGlPBuffer;
704 QCPPainter *QCPPaintBufferGlPbuffer::startPainting() {
705 if (!mGlPBuffer->isValid()) {
706 qDebug() << Q_FUNC_INFO
707 <<
"OpenGL frame buffer object doesn't exist, "
708 "reallocateBuffer was not called?";
713 result->setRenderHint(QPainter::Antialiasing);
718 void QCPPaintBufferGlPbuffer::draw(
QCPPainter *painter)
const {
719 if (!painter || !painter->isActive()) {
720 qDebug() << Q_FUNC_INFO <<
"invalid or inactive painter passed";
723 if (!mGlPBuffer->isValid()) {
724 qDebug() << Q_FUNC_INFO
725 <<
"OpenGL pbuffer isn't valid, reallocateBuffer was not "
729 painter->drawImage(0, 0, mGlPBuffer->toImage());
733 void QCPPaintBufferGlPbuffer::clear(
const QColor &
color) {
734 if (mGlPBuffer->isValid()) {
735 mGlPBuffer->makeCurrent();
738 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
739 mGlPBuffer->doneCurrent();
741 qDebug() << Q_FUNC_INFO
742 <<
"OpenGL pbuffer invalid or context not current";
746 void QCPPaintBufferGlPbuffer::reallocateBuffer() {
747 if (mGlPBuffer)
delete mGlPBuffer;
751 format.setSamples(mMultisamples);
752 mGlPBuffer =
new QGLPixelBuffer(mSize,
format);
756 #ifdef QCP_OPENGL_FBO
783 QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(
785 double devicePixelRatio,
786 QWeakPointer<QOpenGLContext> glContext,
787 QWeakPointer<QOpenGLPaintDevice> glPaintDevice)
789 mGlContext(glContext),
790 mGlPaintDevice(glPaintDevice),
792 QCPPaintBufferGlFbo::reallocateBuffer();
795 QCPPaintBufferGlFbo::~QCPPaintBufferGlFbo() {
796 if (mGlFrameBuffer)
delete mGlFrameBuffer;
800 QCPPainter *QCPPaintBufferGlFbo::startPainting() {
801 if (mGlPaintDevice.isNull()) {
802 qDebug() << Q_FUNC_INFO <<
"OpenGL paint device doesn't exist";
805 if (!mGlFrameBuffer) {
806 qDebug() << Q_FUNC_INFO
807 <<
"OpenGL frame buffer object doesn't exist, "
808 "reallocateBuffer was not called?";
812 if (QOpenGLContext::currentContext() != mGlContext.data())
813 mGlContext.data()->makeCurrent(mGlContext.data()->surface());
814 mGlFrameBuffer->bind();
816 result->setRenderHint(QPainter::Antialiasing);
821 void QCPPaintBufferGlFbo::donePainting() {
822 if (mGlFrameBuffer && mGlFrameBuffer->isBound())
823 mGlFrameBuffer->release();
825 qDebug() << Q_FUNC_INFO
826 <<
"Either OpenGL frame buffer not valid or was not bound";
830 void QCPPaintBufferGlFbo::draw(
QCPPainter *painter)
const {
831 if (!painter || !painter->isActive()) {
832 qDebug() << Q_FUNC_INFO <<
"invalid or inactive painter passed";
835 if (!mGlFrameBuffer) {
836 qDebug() << Q_FUNC_INFO
837 <<
"OpenGL frame buffer object doesn't exist, "
838 "reallocateBuffer was not called?";
841 painter->drawImage(0, 0, mGlFrameBuffer->toImage());
845 void QCPPaintBufferGlFbo::clear(
const QColor &
color) {
846 if (mGlContext.isNull()) {
847 qDebug() << Q_FUNC_INFO <<
"OpenGL context doesn't exist";
850 if (!mGlFrameBuffer) {
851 qDebug() << Q_FUNC_INFO
852 <<
"OpenGL frame buffer object doesn't exist, "
853 "reallocateBuffer was not called?";
857 if (QOpenGLContext::currentContext() != mGlContext.data())
858 mGlContext.data()->makeCurrent(mGlContext.data()->surface());
859 mGlFrameBuffer->bind();
861 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
862 mGlFrameBuffer->release();
866 void QCPPaintBufferGlFbo::reallocateBuffer() {
868 if (mGlFrameBuffer) {
869 if (mGlFrameBuffer->isBound()) mGlFrameBuffer->release();
870 delete mGlFrameBuffer;
874 if (mGlContext.isNull()) {
875 qDebug() << Q_FUNC_INFO <<
"OpenGL context doesn't exist";
878 if (mGlPaintDevice.isNull()) {
879 qDebug() << Q_FUNC_INFO <<
"OpenGL paint device doesn't exist";
884 mGlContext.data()->makeCurrent(mGlContext.data()->surface());
885 QOpenGLFramebufferObjectFormat frameBufferFormat;
886 frameBufferFormat.setSamples(mGlContext.data()->format().samples());
887 frameBufferFormat.setAttachment(
888 QOpenGLFramebufferObject::CombinedDepthStencil);
889 mGlFrameBuffer =
new QOpenGLFramebufferObject(mSize * mDevicePixelRatio,
891 if (mGlPaintDevice.data()->size() != mSize * mDevicePixelRatio)
892 mGlPaintDevice.data()->setSize(mSize * mDevicePixelRatio);
893 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
894 mGlPaintDevice.data()->setDevicePixelRatio(mDevicePixelRatio);
1000 : QObject(parentPlot),
1001 mParentPlot(parentPlot),
1024 qDebug() << Q_FUNC_INFO
1025 <<
"The parent plot's mCurrentLayer will be a dangling "
1026 "pointer. Should have been set to a valid layer or 0 "
1081 painter->setClipRect(child->
clipRect().translated(0, -1));
1083 child->
draw(painter);
1100 if (painter->isActive())
1103 qDebug() << Q_FUNC_INFO
1104 <<
"paint buffer returned inactive painter";
1108 qDebug() << Q_FUNC_INFO <<
"paint buffer returned zero painter";
1110 qDebug() << Q_FUNC_INFO
1111 <<
"no valid paint buffer associated with this layer";
1136 qDebug() << Q_FUNC_INFO
1137 <<
"no valid paint buffer associated with this layer";
1163 qDebug() << Q_FUNC_INFO <<
"layerable is already child of this layer"
1164 <<
reinterpret_cast<quintptr
>(layerable);
1181 qDebug() << Q_FUNC_INFO <<
"layerable is not child of this layer"
1182 <<
reinterpret_cast<quintptr
>(layerable);
1301 QString targetLayer,
1306 mParentLayerable(parentLayerable),
1308 mAntialiased(true) {
1310 if (targetLayer.isEmpty())
1313 qDebug() << Q_FUNC_INFO <<
"setting QCPlayerable initial layer to"
1314 << targetLayer <<
"failed.";
1353 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
1359 qDebug() << Q_FUNC_INFO <<
"there is no layer with name" << layerName;
1436 bool onlySelectable,
1437 QVariant *details)
const {
1439 Q_UNUSED(onlySelectable)
1464 qDebug() << Q_FUNC_INFO
1465 <<
"called with mParentPlot already initialized";
1469 if (!
parentPlot) qDebug() << Q_FUNC_INFO <<
"called with parentPlot zero";
1501 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
1505 qDebug() << Q_FUNC_INFO <<
"layer" <<
layer->
name()
1506 <<
"is not in same QCustomPlot as this layerable";
1528 bool localAntialiased,
1627 const QVariant &details,
1628 bool *selectionStateChanged) {
1632 Q_UNUSED(selectionStateChanged)
1648 Q_UNUSED(selectionStateChanged)
1681 const QVariant &details) {
1720 const QPointF &startPos) {
1756 const QVariant &details) {
1937 result.expand(otherRange);
1953 result.expand(includeCoord);
1967 if (lowerBound > upperBound) qSwap(lowerBound, upperBound);
1970 if (
result.lower < lowerBound) {
1971 result.lower = lowerBound;
1973 if (
result.upper > upperBound ||
1974 qFuzzyCompare(
size(), upperBound - lowerBound))
1975 result.upper = upperBound;
1976 }
else if (
result.upper > upperBound) {
1977 result.upper = upperBound;
1979 if (
result.lower < lowerBound ||
1980 qFuzzyCompare(
size(), upperBound - lowerBound))
1981 result.lower = lowerBound;
2002 double rangeFac = 1
e-3;
2009 if (sanitizedRange.
lower == 0.0 && sanitizedRange.
upper != 0.0) {
2011 if (rangeFac < sanitizedRange.
upper * rangeFac)
2012 sanitizedRange.
lower = rangeFac;
2014 sanitizedRange.
lower = sanitizedRange.
upper * rangeFac;
2016 else if (sanitizedRange.
lower != 0.0 && sanitizedRange.
upper == 0.0) {
2018 if (-rangeFac > sanitizedRange.
lower * rangeFac)
2019 sanitizedRange.
upper = -rangeFac;
2021 sanitizedRange.
upper = sanitizedRange.
lower * rangeFac;
2022 }
else if (sanitizedRange.
lower < 0 && sanitizedRange.
upper > 0) {
2025 if (-sanitizedRange.
lower > sanitizedRange.
upper) {
2027 if (-rangeFac > sanitizedRange.
lower * rangeFac)
2028 sanitizedRange.
upper = -rangeFac;
2030 sanitizedRange.
upper = sanitizedRange.
lower * rangeFac;
2033 if (rangeFac < sanitizedRange.
upper * rangeFac)
2034 sanitizedRange.
lower = rangeFac;
2036 sanitizedRange.
lower = sanitizedRange.
upper * rangeFac;
2041 return sanitizedRange;
2051 return sanitizedRange;
2220 if (mEnd <= other.mBegin)
2232 return QCPDataRange(qMin(mBegin, other.mBegin), qMax(mEnd, other.mEnd));
2261 return !((mBegin > other.mBegin && mBegin >= other.mEnd) ||
2262 (mEnd <= other.mBegin && mEnd < other.mEnd));
2272 return mBegin <= other.mBegin && mEnd >= other.mEnd;
2353 mDataRanges.append(range);
2364 if (mDataRanges.size() != other.mDataRanges.size())
return false;
2365 for (
int i = 0; i < mDataRanges.size(); ++i) {
2366 if (mDataRanges.at(i) != other.mDataRanges.at(i))
return false;
2376 mDataRanges << other.mDataRanges;
2410 while (i < mDataRanges.size()) {
2411 const int thisBegin = mDataRanges.at(i).begin();
2412 const int thisEnd = mDataRanges.at(i).end();
2413 if (thisBegin >= other.
end())
2427 mDataRanges.removeAt(i);
2430 mDataRanges[i].setBegin(other.
end());
2433 if (thisEnd <= other.
end())
2436 mDataRanges[i].setEnd(other.
begin());
2439 mDataRanges[i].setEnd(other.
begin());
2440 mDataRanges.insert(i + 1,
2459 for (
int i = 0; i < mDataRanges.size(); ++i)
2460 result += mDataRanges.at(i).length();
2473 if (index >= 0 && index < mDataRanges.size()) {
2474 return mDataRanges.at(index);
2476 qDebug() << Q_FUNC_INFO <<
"index out of range:" << index;
2491 mDataRanges.last().end());
2527 for (
int i = mDataRanges.size() - 1; i >= 0; --i) {
2528 if (mDataRanges.at(i).isEmpty()) mDataRanges.removeAt(i);
2530 if (mDataRanges.isEmpty())
return;
2533 std::sort(mDataRanges.begin(), mDataRanges.end(), lessThanDataRangeBegin);
2537 while (i < mDataRanges.size()) {
2538 if (mDataRanges.at(i - 1).end() >=
2539 mDataRanges.at(i).begin())
2543 mDataRanges[i - 1].setEnd(
2544 qMax(mDataRanges.at(i - 1).end(), mDataRanges.at(i).end()));
2545 mDataRanges.removeAt(i);
2566 mDataRanges.clear();
2576 if (!mDataRanges.isEmpty()) {
2577 if (mDataRanges.size() > 1)
2578 mDataRanges = QList<QCPDataRange>() << mDataRanges.first();
2579 if (mDataRanges.first().length() > 1)
2580 mDataRanges.first().setEnd(mDataRanges.first().begin() + 1);
2585 if (!
isEmpty()) mDataRanges = QList<QCPDataRange>() <<
span();
2604 if (other.
isEmpty())
return false;
2608 while (thisIndex < mDataRanges.size() &&
2609 otherIndex < other.mDataRanges.size()) {
2610 if (mDataRanges.at(thisIndex).contains(
2611 other.mDataRanges.at(otherIndex)))
2634 for (
int i = 0; i < mDataRanges.size(); ++i)
2635 result.addDataRange(mDataRanges.at(i).intersection(other),
false);
2670 if (mDataRanges.first().begin() != fullRange.
begin())
2675 for (
int i = 1; i < mDataRanges.size(); ++i)
2677 mDataRanges.at(i).begin()),
2680 if (mDataRanges.last().end() != fullRange.
end())
2782 mPen(QBrush(Qt::gray), 0, Qt::DashLine),
2783 mBrush(Qt::NoBrush),
2801 qDebug() << Q_FUNC_INFO <<
"called with axis zero";
2899 painter->setBrush(
mBrush);
2900 painter->drawRect(
mRect);
2962 : QObject(parentPlot), mParentPlot(parentPlot) {
2976 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement *>> it(
mChildren);
2977 while (it.hasNext()) {
2979 if (!it.value().isEmpty())
return false;
2991 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement *>> it(
mChildren);
2992 while (it.hasNext()) {
2994 const QList<QCPLayoutElement *>
elements = it.value();
2995 for (
int i =
elements.size() - 1; i >= 0; --i)
3018 for (
int i = 0; i <
elements.size(); ++i) {
3019 if (!
elements.at(i)->autoMargins().testFlag(side))
continue;
3021 elements.at(i)->calculateAutoMargin(side),
3039 qDebug() << Q_FUNC_INFO
3040 <<
"element is already child of this margin group side"
3041 <<
reinterpret_cast<quintptr
>(element);
3053 if (!
mChildren[side].removeOne(element))
3054 qDebug() << Q_FUNC_INFO
3055 <<
"element is not child of this margin group side"
3056 <<
reinterpret_cast<quintptr
>(element);
3141 mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX),
3142 mSizeConstraintRect(scrInnerRect),
3144 mOuterRect(0, 0, 0, 0),
3145 mMargins(0, 0, 0, 0),
3146 mMinimumMargins(0, 0, 0, 0),
3153 if (qobject_cast<QCPLayout *>(
3320 QVector<QCP::MarginSide> sideVector;
3326 for (
int i = 0; i < sideVector.size(); ++i) {
3366 QList<QCP::MarginSide> allMarginSides =
3439 return QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
3451 return QList<QCPLayoutElement *>();
3467 bool onlySelectable,
3468 QVariant *details)
const {
3471 if (onlySelectable)
return -1;
3477 qDebug() << Q_FUNC_INFO <<
"parent plot not defined";
3627 for (
int i = 0; i < elCount; ++i) {
3635 QList<QCPLayoutElement *>
result;
3636 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
3641 for (
int i = 0; i < c; ++i) {
3688 if (
take(element)) {
3719 if (QWidget *w = qobject_cast<QWidget *>(parent()))
3720 w->updateGeometry();
3721 else if (
QCPLayout *l = qobject_cast<QCPLayout *>(parent()))
3722 l->sizeConstraintsChanged();
3758 el->setParent(
this);
3762 qDebug() << Q_FUNC_INFO <<
"Null element passed";
3784 qDebug() << Q_FUNC_INFO <<
"Null element passed";
3823 QVector<int> minSizes,
3824 QVector<double> stretchFactors,
3825 int totalSize)
const {
3826 if (maxSizes.size() != minSizes.size() ||
3827 minSizes.size() != stretchFactors.size()) {
3828 qDebug() << Q_FUNC_INFO
3829 <<
"Passed vector sizes aren't equal:" << maxSizes << minSizes
3831 return QVector<int>();
3833 if (stretchFactors.isEmpty())
return QVector<int>();
3834 int sectionCount = stretchFactors.size();
3835 QVector<double> sectionSizes(sectionCount);
3839 for (
int i = 0; i < sectionCount; ++i) minSizeSum += minSizes.at(i);
3840 if (totalSize < minSizeSum) {
3843 for (
int i = 0; i < sectionCount; ++i) {
3844 stretchFactors[i] = minSizes.at(i);
3849 QList<int> minimumLockedSections;
3850 QList<int> unfinishedSections;
3851 for (
int i = 0; i < sectionCount; ++i) unfinishedSections.append(i);
3852 double freeSize = totalSize;
3854 int outerIterations = 0;
3855 while (!unfinishedSections.isEmpty() &&
3862 int innerIterations = 0;
3863 while (!unfinishedSections.isEmpty() &&
3872 double nextMax = 1e12;
3873 for (
int i = 0; i < unfinishedSections.size(); ++i) {
3874 int secId = unfinishedSections.at(i);
3876 (maxSizes.at(secId) - sectionSizes.at(secId)) /
3877 stretchFactors.at(secId);
3878 if (hitsMaxAt < nextMax) {
3879 nextMax = hitsMaxAt;
3887 double stretchFactorSum = 0;
3888 for (
int i = 0; i < unfinishedSections.size(); ++i)
3889 stretchFactorSum += stretchFactors.at(unfinishedSections.at(i));
3890 double nextMaxLimit = freeSize / stretchFactorSum;
3895 for (
int i = 0; i < unfinishedSections.size(); ++i) {
3896 sectionSizes[unfinishedSections.at(i)] +=
3897 nextMax * stretchFactors.at(unfinishedSections.at(
3899 freeSize -= nextMax *
3900 stretchFactors.at(unfinishedSections.at(i));
3902 unfinishedSections.removeOne(
3908 for (
int i = 0; i < unfinishedSections.size(); ++i)
3909 sectionSizes[unfinishedSections.at(i)] +=
3911 stretchFactors.at(unfinishedSections.at(
3913 unfinishedSections.clear();
3916 if (innerIterations == sectionCount * 2)
3917 qDebug() << Q_FUNC_INFO
3918 <<
"Exceeded maximum expected inner iteration count, "
3919 "layouting aborted. Input was:"
3920 << maxSizes << minSizes << stretchFactors << totalSize;
3924 bool foundMinimumViolation =
false;
3925 for (
int i = 0; i < sectionSizes.size(); ++i) {
3926 if (minimumLockedSections.contains(i))
continue;
3927 if (sectionSizes.at(i) <
3930 sectionSizes[i] = minSizes.at(i);
3931 foundMinimumViolation =
true;
3933 minimumLockedSections.append(i);
3936 if (foundMinimumViolation) {
3937 freeSize = totalSize;
3938 for (
int i = 0; i < sectionCount; ++i) {
3939 if (!minimumLockedSections.contains(
3942 unfinishedSections.append(i);
3944 freeSize -= sectionSizes.at(
3950 for (
int i = 0; i < unfinishedSections.size(); ++i)
3951 sectionSizes[unfinishedSections.at(i)] = 0;
3954 if (outerIterations == sectionCount * 2)
3955 qDebug() << Q_FUNC_INFO
3956 <<
"Exceeded maximum expected outer iteration count, "
3957 "layouting aborted. Input was:"
3958 << maxSizes << minSizes << stretchFactors << totalSize;
3960 QVector<int>
result(sectionCount);
3961 for (
int i = 0; i < sectionCount; ++i)
3962 result[i] = qRound(sectionSizes.at(i));
3985 if (minOuter.width() > 0 &&
3987 minOuter.rwidth() += el->
margins().left() + el->
margins().right();
3988 if (minOuter.height() > 0 &&
3990 minOuter.rheight() += el->
margins().top() + el->
margins().bottom();
3993 minOuter.width() > 0 ? minOuter.width() : minOuterHint.width(),
3994 minOuter.height() > 0 ? minOuter.height() : minOuterHint.height());
4017 if (maxOuter.width() < QWIDGETSIZE_MAX &&
4019 maxOuter.rwidth() += el->
margins().left() + el->
margins().right();
4020 if (maxOuter.height() < QWIDGETSIZE_MAX &&
4022 maxOuter.rheight() += el->
margins().top() + el->
margins().bottom();
4024 return QSize(maxOuter.width() < QWIDGETSIZE_MAX ? maxOuter.width()
4025 : maxOuterHint.width(),
4026 maxOuter.height() < QWIDGETSIZE_MAX ? maxOuter.height()
4027 : maxOuterHint.height());
4079 : mColumnSpacing(5), mRowSpacing(5), mWrap(0), mFillOrder(foColumnsFirst) {}
4098 if (row >= 0 && row <
mElements.size()) {
4099 if (column >= 0 && column <
mElements.first().size()) {
4103 qDebug() << Q_FUNC_INFO
4104 <<
"Requested cell is empty. Row:" << row
4105 <<
"Column:" << column;
4107 qDebug() << Q_FUNC_INFO <<
"Invalid column. Row:" << row
4108 <<
"Column:" << column;
4110 qDebug() << Q_FUNC_INFO <<
"Invalid row. Row:" << row
4111 <<
"Column:" << column;
4138 qDebug() << Q_FUNC_INFO
4139 <<
"There is already an element in the specified row/column:"
4209 qDebug() << Q_FUNC_INFO
4210 <<
"Invalid stretch factor, must be positive:" << factor;
4212 qDebug() << Q_FUNC_INFO <<
"Invalid column:" << column;
4234 qDebug() << Q_FUNC_INFO
4235 <<
"Invalid stretch factor, must be positive:"
4241 qDebug() << Q_FUNC_INFO
4242 <<
"Column count not equal to passed stretch factor count:"
4260 if (row >= 0 && row <
rowCount()) {
4264 qDebug() << Q_FUNC_INFO
4265 <<
"Invalid stretch factor, must be positive:" << factor;
4267 qDebug() << Q_FUNC_INFO <<
"Invalid row:" << row;
4289 qDebug() << Q_FUNC_INFO
4290 <<
"Invalid stretch factor, must be positive:"
4296 qDebug() << Q_FUNC_INFO
4297 <<
"Row count not equal to passed stretch factor count:"
4366 QVector<QCPLayoutElement *> tempElements;
4368 tempElements.reserve(elCount);
4369 for (
int i = 0; i < elCount; ++i) {
4378 for (
int i = 0; i < tempElements.size(); ++i)
4401 mElements.append(QList<QCPLayoutElement *>());
4405 int newColCount = qMax(
columnCount(), newColumnCount);
4406 for (
int i = 0; i <
rowCount(); ++i) {
4429 if (newIndex < 0) newIndex = 0;
4433 QList<QCPLayoutElement *> newRow;
4455 if (newIndex < 0) newIndex = 0;
4459 for (
int row = 0; row <
rowCount(); ++row)
4479 if (row >= 0 && row <
rowCount()) {
4488 qDebug() << Q_FUNC_INFO <<
"row index out of bounds:" << row;
4490 qDebug() << Q_FUNC_INFO <<
"column index out of bounds:" << column;
4517 if (nCols == 0 || nRows == 0)
return;
4519 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
4525 column = index / nRows;
4526 row = index % nRows;
4530 row = index / nCols;
4531 column = index % nCols;
4539 QVector<int> minColWidths, minRowHeights, maxColWidths, maxRowHeights;
4547 mRect.width() - totalColSpacing);
4548 QVector<int> rowHeights =
getSectionSizes(maxRowHeights, minRowHeights,
4550 mRect.height() - totalRowSpacing);
4553 int yOffset =
mRect.top();
4554 for (
int row = 0; row <
rowCount(); ++row) {
4555 if (row > 0) yOffset += rowHeights.at(row - 1) +
mRowSpacing;
4556 int xOffset =
mRect.left();
4560 mElements.at(row).at(col)->setOuterRect(
4561 QRect(xOffset, yOffset, colWidths.at(col),
4562 rowHeights.at(row)));
4600 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
4614 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
4616 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
4622 QList<QCPLayoutElement *>
result;
4624 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
4629 for (
int i = 0; i < elCount; ++i) {
4642 for (
int row =
rowCount() - 1; row >= 0; --row) {
4643 bool hasElements =
false;
4662 for (
int col =
columnCount() - 1; col >= 0; --col) {
4663 bool hasElements =
false;
4664 for (
int row = 0; row <
rowCount(); ++row) {
4672 for (
int row = 0; row <
rowCount(); ++row)
4680 QVector<int> minColWidths, minRowHeights;
4683 for (
int i = 0; i < minColWidths.size(); ++i)
4684 result.rwidth() += minColWidths.at(i);
4685 for (
int i = 0; i < minRowHeights.size(); ++i)
4686 result.rheight() += minRowHeights.at(i);
4696 QVector<int> maxColWidths, maxRowHeights;
4700 for (
int i = 0; i < maxColWidths.size(); ++i)
4702 qMin(
result.width() + maxColWidths.at(i), QWIDGETSIZE_MAX));
4703 for (
int i = 0; i < maxRowHeights.size(); ++i)
4705 qMin(
result.height() + maxRowHeights.at(i), QWIDGETSIZE_MAX));
4710 if (
result.height() > QWIDGETSIZE_MAX)
result.setHeight(QWIDGETSIZE_MAX);
4711 if (
result.width() > QWIDGETSIZE_MAX)
result.setWidth(QWIDGETSIZE_MAX);
4729 QVector<int> *minRowHeights)
const {
4731 *minRowHeights = QVector<int>(
rowCount(), 0);
4732 for (
int row = 0; row <
rowCount(); ++row) {
4736 if (minColWidths->at(col) < minSize.width())
4737 (*minColWidths)[col] = minSize.width();
4738 if (minRowHeights->at(row) < minSize.height())
4739 (*minRowHeights)[row] = minSize.height();
4759 QVector<int> *maxRowHeights)
const {
4760 *maxColWidths = QVector<int>(
columnCount(), QWIDGETSIZE_MAX);
4761 *maxRowHeights = QVector<int>(
rowCount(), QWIDGETSIZE_MAX);
4762 for (
int row = 0; row <
rowCount(); ++row) {
4766 if (maxColWidths->at(col) > maxSize.width())
4767 (*maxColWidths)[col] = maxSize.width();
4768 if (maxRowHeights->at(row) > maxSize.height())
4769 (*maxRowHeights)[row] = maxSize.height();
4829 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
4843 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
4844 #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
4860 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
4876 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
4892 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
4913 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
4918 for (
int i = 0; i <
mElements.size(); ++i) {
4929 if (
insetRect.size().width() < finalMinSize.width())
4930 insetRect.setWidth(finalMinSize.width());
4931 if (
insetRect.size().height() < finalMinSize.height())
4932 insetRect.setHeight(finalMinSize.height());
4933 if (
insetRect.size().width() > finalMaxSize.width())
4934 insetRect.setWidth(finalMaxSize.width());
4935 if (
insetRect.size().height() > finalMaxSize.height())
4936 insetRect.setHeight(finalMaxSize.height());
4940 if (al.testFlag(Qt::AlignLeft))
4942 else if (al.testFlag(Qt::AlignRight))
4946 finalMinSize.width() *
4948 if (al.testFlag(Qt::AlignTop))
4950 else if (al.testFlag(Qt::AlignBottom))
4954 finalMinSize.height() *
4966 if (index >= 0 && index <
mElements.size())
4982 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
4996 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
4998 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
5014 bool onlySelectable,
5015 QVariant *details)
const {
5017 if (onlySelectable)
return -1;
5019 for (
int i = 0; i <
mElements.size(); ++i) {
5023 if (
mElements.at(i)->realVisibility() &&
5024 mElements.at(i)->selectTest(pos, onlySelectable) >= 0)
5049 mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4));
5052 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
5077 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
5115 : mStyle(esNone), mWidth(8), mLength(10), mInverted(false) {}
5124 : mStyle(style), mWidth(
width), mLength(length), mInverted(inverted) {}
5245 QPen penBackup = painter->pen();
5246 QBrush brushBackup = painter->brush();
5247 QPen miterPen = penBackup;
5248 miterPen.setJoinStyle(Qt::MiterJoin);
5249 QBrush brush(painter->pen().color(), Qt::SolidPattern);
5255 (pos - lengthVec + widthVec).toPointF(),
5256 (pos - lengthVec - widthVec).toPointF()};
5257 painter->
setPen(miterPen);
5258 painter->setBrush(brush);
5259 painter->drawConvexPolygon(
points, 3);
5260 painter->setBrush(brushBackup);
5261 painter->
setPen(penBackup);
5266 (pos - lengthVec + widthVec).toPointF(),
5267 (pos - lengthVec * 0.8).toPointF(),
5268 (pos - lengthVec - widthVec).toPointF()};
5269 painter->
setPen(miterPen);
5270 painter->setBrush(brush);
5271 painter->drawConvexPolygon(
points, 4);
5272 painter->setBrush(brushBackup);
5273 painter->
setPen(penBackup);
5277 QPointF
points[3] = {(pos - lengthVec + widthVec).toPointF(),
5279 (pos - lengthVec - widthVec).toPointF()};
5280 painter->
setPen(miterPen);
5281 painter->drawPolyline(
points, 3);
5282 painter->
setPen(penBackup);
5286 painter->setBrush(brush);
5288 painter->setBrush(brushBackup);
5293 QPointF
points[4] = {(pos - widthVecPerp + widthVec).toPointF(),
5294 (pos - widthVecPerp - widthVec).toPointF(),
5295 (pos + widthVecPerp - widthVec).toPointF(),
5296 (pos + widthVecPerp + widthVec).toPointF()};
5297 painter->
setPen(miterPen);
5298 painter->setBrush(brush);
5299 painter->drawConvexPolygon(
points, 4);
5300 painter->setBrush(brushBackup);
5301 painter->
setPen(penBackup);
5306 QPointF
points[4] = {(pos - widthVecPerp).toPointF(),
5307 (pos - widthVec).toPointF(),
5308 (pos + widthVecPerp).toPointF(),
5309 (pos + widthVec).toPointF()};
5310 painter->
setPen(miterPen);
5311 painter->setBrush(brush);
5312 painter->drawConvexPolygon(
points, 4);
5313 painter->setBrush(brushBackup);
5314 painter->
setPen(penBackup);
5318 painter->
drawLine((pos + widthVec).toPointF(),
5319 (pos - widthVec).toPointF());
5327 if (qFuzzyIsNull(painter->pen().widthF()) &&
5331 painter->
drawLine((pos + widthVec +
5343 lengthVec * 0.2 * (
mInverted ? -1 : 1) +
5345 qMax(1.0f, (
float)painter->pen().widthF()) *
5349 lengthVec * 0.2 * (
mInverted ? -1 : 1) +
5351 qMax(1.0f, (
float)painter->pen().widthF()) *
5368 double angle)
const {
5450 : mTickStepStrategy(tssReadability), mTickCount(5), mTickOrigin(0) {}
5475 qDebug() << Q_FUNC_INFO
5476 <<
"tick count must be greater than zero:" <<
count;
5507 const QLocale &locale,
5510 QVector<double> &ticks,
5511 QVector<double> *subTicks,
5512 QVector<QString> *tickLabels) {
5522 if (ticks.size() > 0) {
5526 *subTicks = QVector<double>();
5567 double epsilon = 0.01;
5570 double fracPart = modf(
getMantissa(tickStep), &intPartf);
5574 if (fracPart < epsilon || 1.0 - fracPart < epsilon) {
5575 if (1.0 - fracPart < epsilon) ++intPart;
5607 if (qAbs(fracPart - 0.5) < epsilon)
5660 const QLocale &locale,
5663 return locale.toString(tick, formatChar.toLatin1(), precision);
5678 int subTickCount,
const QVector<double> &ticks) {
5680 if (subTickCount <= 0 || ticks.size() < 2)
return result;
5682 result.reserve((ticks.size() - 1) * subTickCount);
5683 for (
int i = 1; i < ticks.size(); ++i) {
5684 double subTickStep =
5685 (ticks.at(i) - ticks.at(i - 1)) / (
double)(subTickCount + 1);
5686 for (
int k = 1; k <= subTickCount; ++k)
5687 result.append(ticks.at(i - 1) + k * subTickStep);
5716 qint64 lastStep =
ceil(
5719 int tickcount = lastStep - firstStep + 1;
5720 if (tickcount < 0) tickcount = 0;
5721 result.resize(tickcount);
5722 for (
int i = 0; i < tickcount; ++i)
5738 const QLocale &locale,
5742 result.reserve(ticks.size());
5743 for (
int i = 0; i < ticks.size(); ++i)
5757 QVector<double> &ticks,
5758 bool keepOneOutlier)
const {
5759 bool lowFound =
false;
5760 bool highFound =
false;
5764 for (
int i = 0; i < ticks.size(); ++i) {
5765 if (ticks.at(i) >= range.
lower) {
5771 for (
int i = ticks.size() - 1; i >= 0; --i) {
5772 if (ticks.at(i) <= range.
upper) {
5779 if (highFound && lowFound) {
5780 int trimFront = qMax(0, lowIndex - (keepOneOutlier ? 1 : 0));
5782 qMax(0, ticks.size() - (keepOneOutlier ? 2 : 1) - highIndex);
5783 if (trimFront > 0 || trimBack > 0)
5784 ticks = ticks.mid(trimFront, ticks.size() - trimFront - trimBack);
5797 const QVector<double> &candidates)
const {
5798 if (candidates.size() == 1)
return candidates.first();
5799 QVector<double>::const_iterator it = std::lower_bound(
5800 candidates.constBegin(), candidates.constEnd(), target);
5801 if (it == candidates.constEnd())
5803 else if (it == candidates.constBegin())
5806 return target - *(it - 1) < *it - target ? *(it - 1) : *it;
5818 const double mag = qPow(10.0, qFloor(qLn(input) / qLn(10.0)));
5819 if (magnitude) *magnitude = mag;
5832 const double mantissa =
getMantissa(input, &magnitude);
5835 return pickClosest(mantissa, QVector<double>() << 1.0 << 2.0 << 2.5
5842 if (mantissa <= 5.0)
5843 return (
int)(mantissa * 2) / 2.0 *
5846 return (
int)(mantissa / 2.0) * 2.0 *
5908 : mDateTimeFormat(QLatin1String(
"hh:mm:ss\ndd.MM.yy")),
5909 mDateTimeSpec(Qt::LocalTime),
5910 mDateStrategy(dsNone) {
5996 }
else if (
result < 86400 * 30.4375 * 12)
6001 << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5 * 60
6002 << 5 * 60 << 10 * 60 << 15 * 60 << 30 * 60
6004 << 3600 * 2 << 3600 * 3 << 3600 * 6 << 3600 * 12
6006 << 86400 * 2 << 86400 * 5 << 86400 * 7 << 86400 * 14
6007 << 86400 * 30.4375 << 86400 * 30.4375 * 2
6008 << 86400 * 30.4375 * 3 << 86400 * 30.4375 * 6
6009 << 86400 * 30.4375 *
6012 if (
result > 86400 * 30.4375 - 1)
6014 else if (
result > 3600 * 24 - 1)
6019 const double secondsPerYear =
6020 86400 * 30.4375 * 12;
6036 switch (qRound(tickStep))
6082 case (
int)(86400 * 30.4375 + 0.5):
6085 case (
int)(86400 * 30.4375 * 2 + 0.5):
6088 case (
int)(86400 * 30.4375 * 3 + 0.5):
6091 case (
int)(86400 * 30.4375 * 6 + 0.5):
6094 case (
int)(86400 * 30.4375 * 12 + 0.5):
6110 const QLocale &locale,
6114 Q_UNUSED(formatChar)
6135 QDateTime tickDateTime;
6136 for (
int i = 0; i <
result.size(); ++i) {
6138 tickDateTime.setTime(uniformDateTime.time());
6145 QDateTime tickDateTime;
6146 for (
int i = 0; i <
result.size(); ++i) {
6148 tickDateTime.setTime(uniformDateTime.time());
6149 int thisUniformDay =
6150 uniformDateTime.date().day() <=
6151 tickDateTime.date().daysInMonth()
6152 ? uniformDateTime.date().day()
6153 : tickDateTime.date()
6158 if (thisUniformDay - tickDateTime.date().day() <
6162 tickDateTime = tickDateTime.addMonths(1);
6163 else if (thisUniformDay - tickDateTime.date().day() >
6167 tickDateTime = tickDateTime.addMonths(-1);
6168 tickDateTime.setDate(QDate(tickDateTime.date().year(),
6169 tickDateTime.date().month(),
6190 #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
6191 return QDateTime::fromTime_t(key).addMSecs((key - (qint64)key) * 1000);
6193 return QDateTime::fromMSecsSinceEpoch(key * 1000.0);
6210 #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
6211 return dateTime.toTime_t() + dateTime.time().msec() / 1000.0;
6213 return dateTime.toMSecsSinceEpoch() / 1000.0;
6226 #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
6227 return QDateTime(date).toTime_t();
6228 #elif QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
6229 return QDateTime(date, QTime()).toMSecsSinceEpoch() / 1000.0;
6231 return QDateTime(date).toMSecsSinceEpoch() / 1000.0;
6289 : mTimeFormat(QLatin1String(
"%h:%m:%s")),
6290 mSmallestUnit(tuSeconds),
6291 mBiggestUnit(tuHours) {
6334 bool hasSmallest =
false;
6386 }
else if (
result < 3600 * 24)
6390 QVector<double> availableSteps;
6394 availableSteps << 2.5;
6397 availableSteps << 2;
6402 availableSteps << 2.5 * 60;
6405 availableSteps << 2 * 60;
6407 availableSteps << 5 * 60 << 10 * 60 << 15 * 60 << 30 * 60;
6410 availableSteps << 1 * 3600 << 2 * 3600 << 3 * 3600 << 6 * 3600
6411 << 12 * 3600 << 24 * 3600;
6418 const double secondsPerDay = 3600 * 24;
6479 const QLocale &locale,
6483 Q_UNUSED(formatChar)
6485 bool negative = tick < 0;
6486 if (negative) tick *= -1;
6487 double values[
tuDays + 1];
6489 double restValues[
tuDays + 1];
6512 if (negative)
result.prepend(QLatin1Char(
'-'));
6525 QString valueStr = QString::number(value);
6527 valueStr.prepend(QLatin1Char(
'0'));
6568 : mTickStep(1.0), mScaleStrategy(ssNone) {}
6584 qDebug() << Q_FUNC_INFO
6585 <<
"tick step must be greater than zero:" << step;
6639 (
int)(qLn(exactStep) / qLn(
mTickStep) + 0.5));
6721 const QVector<QString> &labels) {
6735 qDebug() << Q_FUNC_INFO
6736 <<
"sub tick count can't be negative:" << subTicks;
6771 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
6790 const QVector<QString> &labels) {
6791 if (positions.size() != labels.size())
6792 qDebug() << Q_FUNC_INFO
6793 <<
"passed unequal length vectors for positions and labels:"
6794 << positions.size() << labels.size();
6795 int n = qMin(positions.size(), labels.size());
6796 for (
int i = 0; i < n; ++i)
mTicks.insert(positions.at(i), labels.at(i));
6829 const QLocale &locale,
6833 Q_UNUSED(formatChar)
6835 return mTicks.value(tick);
6852 QMap<double, QString>::const_iterator start =
6854 QMap<double, QString>::const_iterator end =
mTicks.upperBound(range.
upper);
6857 if (start !=
mTicks.constBegin()) --start;
6858 if (end !=
mTicks.constEnd()) ++end;
6859 for (QMap<double, QString>::const_iterator it = start; it != end; ++it)
6898 : mPiSymbol(QLatin1String(
" ") + QChar(0x03C0)),
6901 mFractionStyle(fsUnicodeFractions),
6983 const QLocale &locale,
6986 double tickInPis = tick /
mPiValue;
6994 int denominator = 1000;
6995 int numerator = qRound(tickInPis * denominator);
6997 if (qAbs(numerator) == 1 && denominator == 1)
6998 return (numerator < 0 ? QLatin1String(
"-") : QLatin1String(
"")) +
7000 else if (numerator == 0)
7001 return QLatin1String(
"0");
7005 if (qFuzzyIsNull(tickInPis))
7006 return QLatin1String(
"0");
7007 else if (qFuzzyCompare(qAbs(tickInPis), 1.0))
7008 return (tickInPis < 0 ? QLatin1String(
"-") : QLatin1String(
"")) +
7024 if (numerator == 0 || denominator == 0)
return;
7026 int num = numerator;
7027 int denom = denominator;
7030 int oldDenom = denom;
7031 denom = num % denom;
7051 int denominator)
const {
7052 if (denominator == 0) {
7053 qDebug() << Q_FUNC_INFO <<
"called with zero denominator";
7059 qDebug() << Q_FUNC_INFO
7060 <<
"shouldn't be called with fraction style fsDecimal";
7061 return QString::number(numerator / (
double)denominator);
7063 int sign = numerator * denominator < 0 ? -1 : 1;
7064 numerator = qAbs(numerator);
7065 denominator = qAbs(denominator);
7067 if (denominator == 1) {
7068 return QString::number(sign * numerator);
7070 int integerPart = numerator / denominator;
7071 int remainder = numerator % denominator;
7072 if (remainder == 0) {
7073 return QString::number(sign * integerPart);
7076 return QString(QLatin1String(
"%1%2%3/%4"))
7077 .arg(sign == -1 ? QLatin1String(
"-")
7078 : QLatin1String(
""))
7079 .arg(integerPart > 0
7080 ? (QStringLiteral(
"%1 ").arg(
7081 QString::number(integerPart)))
7082 : QLatin1String(
""))
7086 return QString(QLatin1String(
"%1%2%3"))
7087 .arg(sign == -1 ? QLatin1String(
"-")
7088 : QLatin1String(
""))
7089 .arg(integerPart > 0 ? QString::number(integerPart)
7090 : QLatin1String(
""))
7120 if (number == 0)
return QString(QChar(0x2070));
7123 while (number > 0) {
7124 const int digit = number % 10;
7127 result.prepend(QChar(0x00B9));
7131 result.prepend(QChar(0x00B2));
7135 result.prepend(QChar(0x00B3));
7139 result.prepend(QChar(0x2070 + digit));
7154 if (number == 0)
return QString(QChar(0x2080));
7157 while (number > 0) {
7158 result.prepend(QChar(0x2080 + number % 10));
7203 mLogBaseLnInv(1.0 / qLn(mLogBase)) {}
7214 qDebug() << Q_FUNC_INFO
7215 <<
"log base has to be greater than zero:" << base;
7233 qDebug() << Q_FUNC_INFO
7234 <<
"sub tick count can't be negative:" << subTicks;
7283 double currentTick =
7284 qPow(newLogBase, qFloor(qLn(range.
lower) / qLn(newLogBase)));
7285 result.append(currentTick);
7286 while (currentTick < range.
upper &&
7290 currentTick *= newLogBase;
7291 result.append(currentTick);
7293 }
else if (range.
lower < 0 && range.
upper < 0)
7299 double currentTick =
7300 -qPow(newLogBase, qCeil(qLn(-range.
lower) / qLn(newLogBase)));
7301 result.append(currentTick);
7302 while (currentTick < range.
upper &&
7306 currentTick /= newLogBase;
7307 result.append(currentTick);
7312 qDebug() << Q_FUNC_INFO
7313 <<
"Invalid range for logarithmic plot: " << range.
lower
7314 <<
".." << range.
upper;
7350 :
QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis),
7351 mParentAxis(parentAxis) {
7354 setParent(parentAxis);
7355 setPen(QPen(QColor(200, 200, 200), 0, Qt::DotLine));
7430 qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
7446 qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
7454 int zeroLineIndex = -1;
7462 for (
int i = 0; i < tickCount; ++i) {
7477 for (
int i = 0; i < tickCount; ++i) {
7478 if (i == zeroLineIndex)
7486 int zeroLineIndex = -1;
7494 for (
int i = 0; i < tickCount; ++i) {
7509 for (
int i = 0; i < tickCount; ++i) {
7510 if (i == zeroLineIndex)
7527 qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
7699 :
QCPLayerable(parent->parentPlot(), QString(), parent),
7704 mOrientation(orientation(
type)),
7705 mSelectableParts(spAxis | spTickLabels | spAxisLabel),
7706 mSelectedParts(spNone),
7707 mBasePen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
7708 mSelectedBasePen(QPen(Qt::
blue, 2)),
7711 mLabelFont(mParentPlot->font()),
7713 QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)),
7714 mLabelColor(Qt::
black),
7715 mSelectedLabelColor(Qt::
blue),
7718 mTickLabelFont(mParentPlot->font()),
7719 mSelectedTickLabelFont(QFont(mTickLabelFont.family(),
7720 mTickLabelFont.pointSize(),
7722 mTickLabelColor(Qt::
black),
7723 mSelectedTickLabelColor(Qt::
blue),
7724 mNumberPrecision(6),
7725 mNumberFormatChar(
'g'),
7726 mNumberBeautifulPowers(true),
7730 mTickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
7731 mSelectedTickPen(QPen(Qt::
blue, 2)),
7732 mSubTickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
7733 mSelectedSubTickPen(QPen(Qt::
blue, 2)),
7736 mRangeReversed(false),
7737 mScaleType(stLinear),
7740 mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())),
7742 mCachedMarginValid(false),
7791 result.append(QLatin1Char(
'b'));
7952 Qt::AlignmentFlag alignment) {
7953 if (alignment == Qt::AlignLeft)
7955 else if (alignment == Qt::AlignRight)
8028 qDebug() << Q_FUNC_INFO <<
"can not set 0 as axis ticker";
8102 if (!qFuzzyIsNull(degrees -
mAxisPainter->tickLabelRotation)) {
8103 mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0);
8156 if (formatCode.isEmpty()) {
8157 qDebug() << Q_FUNC_INFO <<
"Passed formatCode is empty";
8163 QString allowedFormatChars(QLatin1String(
"eEfgG"));
8164 if (allowedFormatChars.contains(formatCode.at(0))) {
8167 qDebug() << Q_FUNC_INFO
8168 <<
"Invalid number format code (first char not in 'eEfgG'):"
8172 if (formatCode.length() < 2) {
8179 if (formatCode.at(1) == QLatin1Char(
'b') &&
8184 qDebug() << Q_FUNC_INFO
8185 <<
"Invalid number format code (second char not 'b' or first "
8186 "char neither 'e' nor 'g'):"
8190 if (formatCode.length() < 3) {
8196 if (formatCode.at(2) == QLatin1Char(
'c')) {
8198 }
else if (formatCode.at(2) == QLatin1Char(
'd')) {
8201 qDebug() << Q_FUNC_INFO
8202 <<
"Invalid number format code (third char neither 'c' nor "
8580 qDebug() << Q_FUNC_INFO
8581 <<
"Center of scaling operation doesn't lie in same "
8582 "logarithmic sign domain as range:"
8604 int otherPixelSize, ownPixelSize;
8616 double newRangeSize = ratio * otherAxis->
range().
size() * ownPixelSize /
8617 (double)otherPixelSize;
8628 QList<QCPAbstractPlottable *> p =
plottables();
8630 bool haveRange =
false;
8631 for (
int i = 0; i < p.size(); ++i) {
8632 if (!p.at(i)->realVisibility() && onlyVisiblePlottables)
continue;
8634 bool currentFoundRange;
8638 if (p.at(i)->keyAxis() ==
this)
8640 p.at(i)->getKeyRange(currentFoundRange, signDomain);
8643 p.at(i)->getValueRange(currentFoundRange, signDomain);
8644 if (currentFoundRange) {
8646 newRange = plottableRange;
8648 newRange.
expand(plottableRange);
8659 double center = (newRange.
lower + newRange.
upper) *
8753 else if (value <= 0.0 &&
8790 else if (value <= 0.0 &&
8826 if (
mAxisPainter->axisSelectionBox().contains(pos.toPoint()))
8828 else if (
mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint()))
8830 else if (
mAxisPainter->labelSelectionBox().contains(pos.toPoint()))
8838 bool onlySelectable,
8839 QVariant *details)
const {
8845 if (details) details->setValue(part);
8857 QList<QCPAbstractPlottable *>
result;
8874 QList<QCPGraph *>
result;
8893 QList<QCPAbstractItem *>
result;
8897 QList<QCPItemPosition *> positions =
8899 for (
int posId = 0; posId < positions.size(); ++posId) {
8900 if (positions.at(posId)->keyAxis() ==
this ||
8901 positions.at(posId)->valueAxis() ==
this) {
8927 qDebug() << Q_FUNC_INFO <<
"Invalid margin side passed:" << (int)side;
8950 qDebug() << Q_FUNC_INFO <<
"invalid axis type";
8959 const QVariant &details,
8960 bool *selectionStateChanged) {
8966 if (selectionStateChanged)
8975 if (selectionStateChanged)
9005 if (
event->buttons() & Qt::LeftButton) {
9033 const double startPixel =
9034 orientation() == Qt::Horizontal ? startPos.x() : startPos.y();
9035 const double currentPixel =
orientation() == Qt::Horizontal
9109 const double wheelSteps =
9111 const double factor =
9146 QVector<double> subTickPositions;
9148 QVector<double> tickPositions;
9309 QVector<double> tickPositions;
9364 QCPAxisPainterPrivate::QCPAxisPainterPrivate(
QCustomPlot *parentPlot)
9366 basePen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
9370 tickLabelPadding(0),
9371 tickLabelRotation(0),
9372 tickLabelSide(
QCPAxis::lsOutside),
9373 substituteExponent(true),
9374 numberMultiplyCross(false),
9378 subTickLengthOut(0),
9379 tickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
9380 subTickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
9382 abbreviateDecimalPowers(false),
9383 reversedEndings(false),
9384 mParentPlot(parentPlot),
9388 QCPAxisPainterPrivate::~QCPAxisPainterPrivate() {}
9397 void QCPAxisPainterPrivate::draw(
QCPPainter *painter) {
9398 QByteArray newHash = generateLabelParameterHash();
9399 if (newHash != mLabelParameterHash) {
9400 mLabelCache.clear();
9401 mLabelParameterHash = newHash;
9436 painter->
setPen(basePen);
9438 baseLine.setPoints(
origin + QPointF(xCor, yCor),
9439 origin + QPointF(axisRect.width() + xCor, yCor));
9441 baseLine.setPoints(
origin + QPointF(xCor, yCor),
9442 origin + QPointF(xCor, -axisRect.height() + yCor));
9443 if (reversedEndings)
9444 baseLine = QLineF(baseLine.p2(),
9450 if (!tickPositions.isEmpty()) {
9451 painter->
setPen(tickPen);
9457 for (
int i = 0; i < tickPositions.size(); ++i)
9459 QLineF(tickPositions.at(i) + xCor,
9460 origin.y() - tickLengthOut * tickDir + yCor,
9461 tickPositions.at(i) + xCor,
9462 origin.y() + tickLengthIn * tickDir + yCor));
9464 for (
int i = 0; i < tickPositions.size(); ++i)
9466 QLineF(
origin.x() - tickLengthOut * tickDir + xCor,
9467 tickPositions.at(i) + yCor,
9468 origin.x() + tickLengthIn * tickDir + xCor,
9469 tickPositions.at(i) + yCor));
9474 if (!subTickPositions.isEmpty()) {
9475 painter->
setPen(subTickPen);
9482 for (
int i = 0; i < subTickPositions.size(); ++i)
9484 QLineF(subTickPositions.at(i) + xCor,
9485 origin.y() - subTickLengthOut * tickDir + yCor,
9486 subTickPositions.at(i) + xCor,
9487 origin.y() + subTickLengthIn * tickDir + yCor));
9489 for (
int i = 0; i < subTickPositions.size(); ++i)
9491 QLineF(
origin.x() - subTickLengthOut * tickDir + xCor,
9492 subTickPositions.at(i) + yCor,
9493 origin.x() + subTickLengthIn * tickDir + xCor,
9494 subTickPositions.at(i) + yCor));
9497 margin += qMax(0, qMax(tickLengthOut, subTickLengthOut));
9503 painter->setBrush(QBrush(basePen.color()));
9504 QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy());
9506 lowerEnding.draw(painter,
9509 lowerEnding.realLength() *
9510 (lowerEnding.inverted() ? -1 : 1),
9513 upperEnding.draw(painter,
9516 upperEnding.realLength() *
9517 (upperEnding.inverted() ? -1 : 1),
9526 oldClipRect = painter->clipRegion().boundingRect();
9527 painter->setClipRect(axisRect);
9529 QSize tickLabelsSize(0, 0);
9531 if (!tickLabels.isEmpty()) {
9533 painter->setFont(tickLabelFont);
9534 painter->
setPen(QPen(tickLabelColor));
9535 const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size());
9536 int distanceToAxis = margin;
9539 -(qMax(tickLengthIn, subTickLengthIn) + tickLabelPadding);
9540 for (
int i = 0; i < maxLabelIndex; ++i)
9541 placeTickLabel(painter, tickPositions.at(i), distanceToAxis,
9542 tickLabels.at(i), &tickLabelsSize);
9545 ? tickLabelsSize.height()
9546 : tickLabelsSize.width();
9552 if (!label.isEmpty()) {
9553 margin += labelPadding;
9554 painter->setFont(labelFont);
9555 painter->
setPen(QPen(labelColor));
9556 labelBounds = painter->fontMetrics().boundingRect(
9557 0, 0, 0, 0, Qt::TextDontClip, label);
9559 QTransform oldTransform = painter->transform();
9560 painter->translate((
origin.x() - margin - labelBounds.height()),
9562 painter->rotate(-90);
9563 painter->drawText(0, 0, axisRect.height(), labelBounds.height(),
9564 Qt::TextDontClip | Qt::AlignCenter, label);
9565 painter->setTransform(oldTransform);
9567 QTransform oldTransform = painter->transform();
9568 painter->translate((
origin.x() + margin + labelBounds.height()),
9569 origin.y() - axisRect.height());
9570 painter->rotate(90);
9571 painter->drawText(0, 0, axisRect.height(), labelBounds.height(),
9572 Qt::TextDontClip | Qt::AlignCenter, label);
9573 painter->setTransform(oldTransform);
9575 painter->drawText(
origin.x(),
9576 origin.y() - margin - labelBounds.height(),
9577 axisRect.width(), labelBounds.height(),
9578 Qt::TextDontClip | Qt::AlignCenter, label);
9580 painter->drawText(
origin.x(),
origin.y() + margin, axisRect.width(),
9581 labelBounds.height(),
9582 Qt::TextDontClip | Qt::AlignCenter, label);
9586 int selectionTolerance = 0;
9588 selectionTolerance = mParentPlot->selectionTolerance();
9590 qDebug() << Q_FUNC_INFO <<
"mParentPlot is null";
9591 int selAxisOutSize =
9592 qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance);
9593 int selAxisInSize = selectionTolerance;
9594 int selTickLabelSize;
9595 int selTickLabelOffset;
9598 ? tickLabelsSize.height()
9599 : tickLabelsSize.width());
9600 selTickLabelOffset =
9601 qMax(tickLengthOut, subTickLengthOut) + tickLabelPadding;
9604 ? tickLabelsSize.height()
9605 : tickLabelsSize.width());
9606 selTickLabelOffset =
9607 -(qMax(tickLengthIn, subTickLengthIn) + tickLabelPadding);
9609 int selLabelSize = labelBounds.height();
9610 int selLabelOffset =
9611 qMax(tickLengthOut, subTickLengthOut) +
9613 ? tickLabelPadding + selTickLabelSize
9617 mAxisSelectionBox.setCoords(
origin.x() - selAxisOutSize, axisRect.top(),
9618 origin.x() + selAxisInSize,
9620 mTickLabelsSelectionBox.setCoords(
9621 origin.x() - selTickLabelOffset - selTickLabelSize,
9622 axisRect.top(),
origin.x() - selTickLabelOffset,
9624 mLabelSelectionBox.setCoords(
9625 origin.x() - selLabelOffset - selLabelSize, axisRect.top(),
9626 origin.x() - selLabelOffset, axisRect.bottom());
9628 mAxisSelectionBox.setCoords(
origin.x() - selAxisInSize, axisRect.top(),
9629 origin.x() + selAxisOutSize,
9631 mTickLabelsSelectionBox.setCoords(
9632 origin.x() + selTickLabelOffset + selTickLabelSize,
9633 axisRect.top(),
origin.x() + selTickLabelOffset,
9635 mLabelSelectionBox.setCoords(
9636 origin.x() + selLabelOffset + selLabelSize, axisRect.top(),
9637 origin.x() + selLabelOffset, axisRect.bottom());
9639 mAxisSelectionBox.setCoords(
9640 axisRect.left(),
origin.y() - selAxisOutSize, axisRect.right(),
9641 origin.y() + selAxisInSize);
9642 mTickLabelsSelectionBox.setCoords(
9644 origin.y() - selTickLabelOffset - selTickLabelSize,
9645 axisRect.right(),
origin.y() - selTickLabelOffset);
9646 mLabelSelectionBox.setCoords(
9647 axisRect.left(),
origin.y() - selLabelOffset - selLabelSize,
9648 axisRect.right(),
origin.y() - selLabelOffset);
9650 mAxisSelectionBox.setCoords(axisRect.left(),
origin.y() - selAxisInSize,
9652 origin.y() + selAxisOutSize);
9653 mTickLabelsSelectionBox.setCoords(
9655 origin.y() + selTickLabelOffset + selTickLabelSize,
9656 axisRect.right(),
origin.y() + selTickLabelOffset);
9657 mLabelSelectionBox.setCoords(
9658 axisRect.left(),
origin.y() + selLabelOffset + selLabelSize,
9659 axisRect.right(),
origin.y() + selLabelOffset);
9661 mAxisSelectionBox = mAxisSelectionBox.normalized();
9662 mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized();
9663 mLabelSelectionBox = mLabelSelectionBox.normalized();
9679 if (!tickPositions.isEmpty())
9680 result += qMax(0, qMax(tickLengthOut, subTickLengthOut));
9684 QSize tickLabelsSize(0, 0);
9685 if (!tickLabels.isEmpty()) {
9686 for (
int i = 0; i < tickLabels.size(); ++i)
9687 getMaxTickLabelSize(tickLabelFont, tickLabels.at(i),
9690 ? tickLabelsSize.height()
9691 : tickLabelsSize.width();
9692 result += tickLabelPadding;
9698 if (!label.isEmpty()) {
9699 QFontMetrics fontMetrics(labelFont);
9701 bounds = fontMetrics.boundingRect(
9703 Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, label);
9704 result += bounds.height() + labelPadding;
9717 void QCPAxisPainterPrivate::clearCache() { mLabelCache.clear(); }
9727 QByteArray QCPAxisPainterPrivate::generateLabelParameterHash()
const {
9729 result.append(QByteArray::number(mParentPlot->bufferDevicePixelRatio()));
9730 result.append(QByteArray::number(tickLabelRotation));
9731 result.append(QByteArray::number((
int)tickLabelSide));
9732 result.append(QByteArray::number((
int)substituteExponent));
9733 result.append(QByteArray::number((
int)numberMultiplyCross));
9734 result.append(tickLabelColor.name().toLatin1() +
9735 QByteArray::number(tickLabelColor.alpha(), 16));
9736 result.append(tickLabelFont.toString().toLatin1());
9761 void QCPAxisPainterPrivate::placeTickLabel(
QCPPainter *painter,
9764 const QString &text,
9765 QSize *tickLabelsSize) {
9768 if (text.isEmpty())
return;
9770 QPointF labelAnchor;
9773 labelAnchor = QPointF(axisRect.left() - distanceToAxis -
offset,
9777 labelAnchor = QPointF(axisRect.right() + distanceToAxis +
offset,
9786 axisRect.bottom() + distanceToAxis +
offset);
9790 !painter->
modes().testFlag(
9793 CachedLabel *cachedLabel =
9794 mLabelCache.take(text);
9797 cachedLabel =
new CachedLabel;
9798 TickLabelData labelData = getTickLabelData(painter->font(), text);
9799 cachedLabel->offset = getTickLabelDrawOffset(labelData) +
9800 labelData.rotatedTotalBounds.topLeft();
9801 if (!qFuzzyCompare(1.0, mParentPlot->bufferDevicePixelRatio())) {
9802 cachedLabel->pixmap =
9803 QPixmap(labelData.rotatedTotalBounds.size() *
9804 mParentPlot->bufferDevicePixelRatio());
9805 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
9806 #ifdef QCP_DEVICEPIXELRATIO_FLOAT
9807 cachedLabel->pixmap.setDevicePixelRatio(
9808 mParentPlot->devicePixelRatioF());
9810 cachedLabel->pixmap.setDevicePixelRatio(
9811 mParentPlot->devicePixelRatio());
9815 cachedLabel->pixmap =
9816 QPixmap(labelData.rotatedTotalBounds.size());
9817 cachedLabel->pixmap.fill(Qt::transparent);
9818 QCPPainter cachePainter(&cachedLabel->pixmap);
9819 cachePainter.setPen(painter->pen());
9821 &cachePainter, -labelData.rotatedTotalBounds.topLeft().x(),
9822 -labelData.rotatedTotalBounds.topLeft().y(), labelData);
9826 bool labelClippedByBorder =
false;
9829 labelClippedByBorder =
9830 labelAnchor.x() + cachedLabel->offset.x() +
9831 cachedLabel->pixmap.width() /
9833 ->bufferDevicePixelRatio() >
9834 viewportRect.right() ||
9835 labelAnchor.x() + cachedLabel->offset.x() <
9836 viewportRect.left();
9838 labelClippedByBorder =
9839 labelAnchor.y() + cachedLabel->offset.y() +
9840 cachedLabel->pixmap.height() /
9842 ->bufferDevicePixelRatio() >
9843 viewportRect.bottom() ||
9844 labelAnchor.y() + cachedLabel->offset.y() <
9847 if (!labelClippedByBorder) {
9848 painter->drawPixmap(labelAnchor + cachedLabel->offset,
9849 cachedLabel->pixmap);
9850 finalSize = cachedLabel->pixmap.size() /
9851 mParentPlot->bufferDevicePixelRatio();
9853 mLabelCache.insert(text,
9858 TickLabelData labelData = getTickLabelData(painter->font(), text);
9859 QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData);
9862 bool labelClippedByBorder =
false;
9865 labelClippedByBorder =
9867 (labelData.rotatedTotalBounds.width() +
9868 labelData.rotatedTotalBounds.left()) >
9869 viewportRect.right() ||
9871 labelData.rotatedTotalBounds.left() <
9872 viewportRect.left();
9874 labelClippedByBorder =
9876 (labelData.rotatedTotalBounds.height() +
9877 labelData.rotatedTotalBounds.top()) >
9878 viewportRect.bottom() ||
9879 finalPosition.y() + labelData.rotatedTotalBounds.top() <
9882 if (!labelClippedByBorder) {
9883 drawTickLabel(painter, finalPosition.x(), finalPosition.y(),
9885 finalSize = labelData.rotatedTotalBounds.size();
9890 if (finalSize.width() > tickLabelsSize->width())
9891 tickLabelsSize->setWidth(finalSize.width());
9892 if (finalSize.height() > tickLabelsSize->height())
9893 tickLabelsSize->setHeight(finalSize.height());
9906 void QCPAxisPainterPrivate::drawTickLabel(
9910 const TickLabelData &labelData)
const {
9912 QTransform oldTransform = painter->transform();
9913 QFont oldFont = painter->font();
9916 painter->translate(
x,
y);
9917 if (!qFuzzyIsNull(tickLabelRotation)) painter->rotate(tickLabelRotation);
9920 if (!labelData.expPart
9923 painter->setFont(labelData.baseFont);
9924 painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart);
9925 if (!labelData.suffixPart.isEmpty())
9926 painter->drawText(labelData.baseBounds.width() + 1 +
9927 labelData.expBounds.width(),
9928 0, 0, 0, Qt::TextDontClip, labelData.suffixPart);
9929 painter->setFont(labelData.expFont);
9930 painter->drawText(labelData.baseBounds.width() + 1, 0,
9931 labelData.expBounds.width(),
9932 labelData.expBounds.height(), Qt::TextDontClip,
9935 painter->setFont(labelData.baseFont);
9936 painter->drawText(0, 0, labelData.totalBounds.width(),
9937 labelData.totalBounds.height(),
9938 Qt::TextDontClip | Qt::AlignHCenter,
9939 labelData.basePart);
9943 painter->setTransform(oldTransform);
9944 painter->setFont(oldFont);
9956 QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(
9957 const QFont &font,
const QString &text)
const {
9961 bool useBeautifulPowers =
false;
9966 if (substituteExponent) {
9967 ePos = text.indexOf(QLatin1Char(
'e'));
9968 if (ePos > 0 && text.at(ePos - 1).isDigit()) {
9970 while (eLast + 1 < text.size() &&
9971 (text.at(eLast + 1) == QLatin1Char(
'+') ||
9972 text.at(eLast + 1) == QLatin1Char(
'-') ||
9973 text.at(eLast + 1).isDigit()))
9977 useBeautifulPowers =
true;
9984 if (
result.baseFont.pointSizeF() >
9987 result.baseFont.setPointSizeF(
9988 result.baseFont.pointSizeF() +
9992 if (useBeautifulPowers) {
9995 result.basePart = text.left(ePos);
9997 text.mid(eLast + 1);
10000 if (abbreviateDecimalPowers &&
result.basePart == QLatin1String(
"1"))
10001 result.basePart = QLatin1String(
"10");
10003 result.basePart += (numberMultiplyCross ? QString(QChar(215))
10004 : QString(QChar(183))) +
10005 QLatin1String(
"10");
10006 result.expPart = text.mid(ePos + 1, eLast - ePos);
10008 while (
result.expPart.length() > 2 &&
10012 result.expPart.remove(1, 1);
10013 if (!
result.expPart.isEmpty() &&
10014 result.expPart.at(0) == QLatin1Char(
'+'))
10015 result.expPart.remove(0, 1);
10018 if (
result.expFont.pointSize() > 0)
10019 result.expFont.setPointSize(
result.expFont.pointSize() * 0.75);
10021 result.expFont.setPixelSize(
result.expFont.pixelSize() * 0.75);
10025 .boundingRect(0, 0, 0, 0, Qt::TextDontClip,
10028 .boundingRect(0, 0, 0, 0, Qt::TextDontClip,
10030 if (!
result.suffixPart.isEmpty())
10032 QFontMetrics(
result.baseFont)
10033 .boundingRect(0, 0, 0, 0, Qt::TextDontClip,
10037 result.expBounds.width() +
result.suffixBounds.width() + 2,
10045 QFontMetrics(
result.baseFont)
10046 .boundingRect(0, 0, 0, 0,
10047 Qt::TextDontClip | Qt::AlignHCenter,
10050 result.totalBounds.moveTopLeft(QPoint(
10057 if (!qFuzzyIsNull(tickLabelRotation)) {
10058 QTransform transform;
10059 transform.rotate(tickLabelRotation);
10060 result.rotatedTotalBounds =
10061 transform.mapRect(
result.rotatedTotalBounds);
10078 QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(
10079 const TickLabelData &labelData)
const {
10091 bool doRotation = !qFuzzyIsNull(tickLabelRotation);
10093 qFuzzyCompare(qAbs(tickLabelRotation),
10096 double radians = tickLabelRotation / 180.0 *
M_PI;
10104 if (tickLabelRotation > 0) {
10105 x = -qCos(radians) * labelData.totalBounds.width();
10106 y = flip ? -labelData.totalBounds.width() / 2.0
10107 : -qSin(radians) * labelData.totalBounds.width() -
10109 labelData.totalBounds.height() /
10112 x = -qCos(-radians) * labelData.totalBounds.width() -
10113 qSin(-radians) * labelData.totalBounds.height();
10114 y = flip ? +labelData.totalBounds.width() / 2.0
10115 : +qSin(-radians) * labelData.totalBounds.width() -
10117 labelData.totalBounds.height() /
10121 x = -labelData.totalBounds.width();
10122 y = -labelData.totalBounds.height() / 2.0;
10131 if (tickLabelRotation > 0) {
10132 x = +qSin(radians) * labelData.totalBounds.height();
10133 y = flip ? -labelData.totalBounds.width() / 2.0
10134 : -qCos(radians) * labelData.totalBounds.height() /
10138 y = flip ? +labelData.totalBounds.width() / 2.0
10139 : -qCos(-radians) * labelData.totalBounds.height() /
10144 y = -labelData.totalBounds.height() / 2.0;
10153 if (tickLabelRotation > 0) {
10154 x = -qCos(radians) * labelData.totalBounds.width() +
10155 qSin(radians) * labelData.totalBounds.height() / 2.0;
10156 y = -qSin(radians) * labelData.totalBounds.width() -
10157 qCos(radians) * labelData.totalBounds.height();
10159 x = -qSin(-radians) * labelData.totalBounds.height() / 2.0;
10160 y = -qCos(-radians) * labelData.totalBounds.height();
10163 x = -labelData.totalBounds.width() / 2.0;
10164 y = -labelData.totalBounds.height();
10173 if (tickLabelRotation > 0) {
10174 x = +qSin(radians) * labelData.totalBounds.height() / 2.0;
10177 x = -qCos(-radians) * labelData.totalBounds.width() -
10178 qSin(-radians) * labelData.totalBounds.height() / 2.0;
10179 y = +qSin(-radians) * labelData.totalBounds.width();
10182 x = -labelData.totalBounds.width() / 2.0;
10187 return QPointF(
x,
y);
10198 void QCPAxisPainterPrivate::getMaxTickLabelSize(
const QFont &font,
10199 const QString &text,
10200 QSize *tickLabelsSize)
const {
10205 mLabelCache.contains(
10208 const CachedLabel *cachedLabel = mLabelCache.object(text);
10209 finalSize = cachedLabel->pixmap.size() /
10210 mParentPlot->bufferDevicePixelRatio();
10213 TickLabelData labelData = getTickLabelData(font, text);
10214 finalSize = labelData.rotatedTotalBounds.size();
10218 if (finalSize.width() > tickLabelsSize->width())
10219 tickLabelsSize->setWidth(finalSize.width());
10220 if (finalSize.height() > tickLabelsSize->height())
10221 tickLabelsSize->setHeight(finalSize.height());
10328 mBrush(Qt::NoBrush),
10329 mPenDefined(false) {}
10342 mBrush(Qt::NoBrush),
10343 mPenDefined(false) {}
10351 const QColor &
color,
10356 mBrush(Qt::NoBrush),
10357 mPenDefined(true) {}
10365 const QColor &
color,
10366 const QColor &fill,
10371 mBrush(QBrush(fill)),
10372 mPenDefined(true) {}
10392 const QBrush &brush,
10398 mPenDefined(pen.style() != Qt::NoPen) {}
10408 mBrush(Qt::NoBrush),
10410 mPenDefined(false) {}
10424 const QBrush &brush,
10430 mCustomPath(customPath),
10431 mPenDefined(pen.style() != Qt::NoPen) {}
10438 ScatterProperties properties) {
10439 if (properties.testFlag(
spPen)) {
10445 if (properties.testFlag(
spShape)) {
10539 const QPen &defaultPen)
const {
10541 painter->setBrush(
mBrush);
10561 double w =
mSize / 2.0;
10566 painter->
drawLine(QPointF(
x,
y), QPointF(
x + 0.0001,
y));
10570 painter->
drawLine(QLineF(
x - w,
y - w,
x + w,
y + w));
10571 painter->
drawLine(QLineF(
x - w,
y + w,
x + w,
y - w));
10580 painter->drawEllipse(QPointF(
x,
y), w, w);
10584 QBrush b = painter->brush();
10585 painter->setBrush(painter->pen().color());
10586 painter->drawEllipse(QPointF(
x,
y), w, w);
10587 painter->setBrush(b);
10591 painter->drawRect(QRectF(
x - w,
y - w,
mSize,
mSize));
10595 QPointF lineArray[4] = {QPointF(
x - w,
y), QPointF(
x,
y - w),
10596 QPointF(
x + w,
y), QPointF(
x,
y + w)};
10597 painter->drawPolygon(lineArray, 4);
10603 painter->
drawLine(QLineF(
x - w * 0.707,
y - w * 0.707,
10604 x + w * 0.707,
y + w * 0.707));
10605 painter->
drawLine(QLineF(
x - w * 0.707,
y + w * 0.707,
10606 x + w * 0.707,
y - w * 0.707));
10610 QPointF lineArray[3] = {QPointF(
x - w,
y + 0.755 * w),
10611 QPointF(
x + w,
y + 0.755 * w),
10612 QPointF(
x,
y - 0.977 * w)};
10613 painter->drawPolygon(lineArray, 3);
10617 QPointF lineArray[3] = {QPointF(
x - w,
y - 0.755 * w),
10618 QPointF(
x + w,
y - 0.755 * w),
10619 QPointF(
x,
y + 0.977 * w)};
10620 painter->drawPolygon(lineArray, 3);
10624 painter->drawRect(QRectF(
x - w,
y - w,
mSize,
mSize));
10625 painter->
drawLine(QLineF(
x - w,
y - w,
x + w * 0.95,
y + w * 0.95));
10626 painter->
drawLine(QLineF(
x - w,
y + w * 0.95,
x + w * 0.95,
y - w));
10630 painter->drawRect(QRectF(
x - w,
y - w,
mSize,
mSize));
10636 painter->drawEllipse(QPointF(
x,
y), w, w);
10637 painter->
drawLine(QLineF(
x - w * 0.707,
y - w * 0.707,
10638 x + w * 0.670,
y + w * 0.670));
10639 painter->
drawLine(QLineF(
x - w * 0.707,
y + w * 0.670,
10640 x + w * 0.670,
y - w * 0.707));
10644 painter->drawEllipse(QPointF(
x,
y), w, w);
10650 painter->drawEllipse(QPointF(
x,
y), w, w);
10652 painter->
drawLine(QLineF(
x,
y,
x - w * 0.707,
y + w * 0.707));
10653 painter->
drawLine(QLineF(
x,
y,
x + w * 0.707,
y + w * 0.707));
10657 const double widthHalf =
mPixmap.width() * 0.5;
10658 const double heightHalf =
mPixmap.height() * 0.5;
10659 #if QT_VERSION < QT_VERSION_CHECK(4, 8, 0)
10660 const QRectF clipRect =
10661 painter->clipRegion().boundingRect().adjusted(
10662 -widthHalf, -heightHalf, widthHalf, heightHalf);
10664 const QRectF clipRect = painter->clipBoundingRect().adjusted(
10665 -widthHalf, -heightHalf, widthHalf, heightHalf);
10667 if (clipRect.contains(
x,
y))
10668 painter->drawPixmap(
x - widthHalf,
y - heightHalf,
mPixmap);
10672 QTransform oldTransform = painter->transform();
10673 painter->translate(
x,
y);
10676 painter->setTransform(oldTransform);
10726 : mPen(QColor(80, 80, 255), 2.5),
10727 mBrush(Qt::NoBrush),
10756 QCPScatterStyle::ScatterProperties usedProperties) {
10770 const QCPScatterStyle::ScatterProperties &properties) {
10789 painter->setBrush(
mBrush);
10837 Q_UNUSED(selection)
10857 qDebug() << Q_FUNC_INFO
10858 <<
"This selection decorator is already registered with "
11100 :
QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()),
11102 mAntialiasedFill(true),
11103 mAntialiasedScatters(true),
11105 mBrush(Qt::NoBrush),
11107 mValueAxis(valueAxis),
11109 mSelectionDecorator(0) {
11111 qDebug() << Q_FUNC_INFO
11112 <<
"Parent plot of keyAxis is not the same as that of "
11115 qDebug() << Q_FUNC_INFO
11116 <<
"keyAxis and valueAxis must be orthogonal to each other.";
11304 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
11323 double value)
const {
11327 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
11352 double &value)
const {
11356 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
11375 double &value)
const {
11408 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
11427 double center = (newRange.
lower + newRange.
upper) *
11457 bool inKeyRange)
const {
11461 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
11481 double center = (newRange.
lower + newRange.
upper) *
11516 qDebug() << Q_FUNC_INFO <<
"passed legend is null";
11520 qDebug() << Q_FUNC_INFO
11521 <<
"passed legend isn't in the same QCustomPlot as this "
11559 qDebug() << Q_FUNC_INFO <<
"passed legend is null";
11585 return mKeyAxis.data()->axisRect()->rect() &
11653 const QVariant &details,
11654 bool *selectionStateChanged) {
11682 if (selectionStateChanged)
11683 *selectionStateChanged =
mSelection != selectionBefore;
11692 if (selectionStateChanged)
11693 *selectionStateChanged =
mSelection != selectionBefore;
11750 const QString &
name,
11753 mParentPlot(parentPlot),
11754 mParentItem(parentItem),
11755 mAnchorId(anchorId) {}
11784 qDebug() << Q_FUNC_INFO <<
"no valid anchor id set:" <<
mAnchorId;
11788 qDebug() << Q_FUNC_INFO <<
"no parent item set";
11805 qDebug() << Q_FUNC_INFO <<
"provided pos is child already"
11806 <<
reinterpret_cast<quintptr
>(pos);
11817 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child"
11818 <<
reinterpret_cast<quintptr
>(pos);
11833 qDebug() << Q_FUNC_INFO <<
"provided pos is child already"
11834 <<
reinterpret_cast<quintptr
>(pos);
11845 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child"
11846 <<
reinterpret_cast<quintptr
>(pos);
11927 const QString &
name)
11929 mPositionTypeX(ptAbsolute),
11930 mPositionTypeY(ptAbsolute),
11934 mParentAnchorY(0) {}
12009 bool retainPixelPosition =
true;
12012 retainPixelPosition =
false;
12015 retainPixelPosition =
false;
12039 bool retainPixelPosition =
true;
12042 retainPixelPosition =
false;
12045 retainPixelPosition =
false;
12080 bool keepPixelPosition) {
12083 return successX && successY;
12095 bool keepPixelPosition) {
12098 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor"
12104 while (currentParent) {
12109 if (currentParentPos ==
this) {
12110 qDebug() << Q_FUNC_INFO
12111 <<
"can't create recursive parent-child-relationship"
12115 currentParent = currentParentPos->parentAnchorX();
12122 qDebug() << Q_FUNC_INFO
12123 <<
"can't set parent to be an anchor which itself "
12124 "depends on this position"
12145 if (keepPixelPosition)
12161 bool keepPixelPosition) {
12164 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor"
12170 while (currentParent) {
12175 if (currentParentPos ==
this) {
12176 qDebug() << Q_FUNC_INFO
12177 <<
"can't create recursive parent-child-relationship"
12181 currentParent = currentParentPos->parentAnchorY();
12188 qDebug() << Q_FUNC_INFO
12189 <<
"can't set parent to be an anchor which itself "
12190 "depends on this position"
12211 if (keepPixelPosition)
12286 qDebug() << Q_FUNC_INFO
12287 <<
"Item position type x is ptAxisRectRatio, but no "
12288 "axis rect was defined";
12295 mValueAxis.data()->orientation() == Qt::Horizontal)
12298 qDebug() << Q_FUNC_INFO
12299 <<
"Item position type x is ptPlotCoords, but no axes "
12329 qDebug() << Q_FUNC_INFO
12330 <<
"Item position type y is ptAxisRectRatio, but no "
12331 "axis rect was defined";
12338 mValueAxis.data()->orientation() == Qt::Vertical)
12341 qDebug() << Q_FUNC_INFO
12342 <<
"Item position type y is ptPlotCoords, but no axes "
12406 qDebug() << Q_FUNC_INFO
12407 <<
"Item position type x is ptAxisRectRatio, but no "
12408 "axis rect was defined";
12415 mValueAxis.data()->orientation() == Qt::Horizontal)
12418 qDebug() << Q_FUNC_INFO
12419 <<
"Item position type x is ptPlotCoords, but no axes "
12446 qDebug() << Q_FUNC_INFO
12447 <<
"Item position type y is ptAxisRectRatio, but no "
12448 "axis rect was defined";
12455 mValueAxis.data()->orientation() == Qt::Vertical)
12458 qDebug() << Q_FUNC_INFO
12459 <<
"Item position type y is ptPlotCoords, but no axes "
12659 mClipToAxisRect(false),
12665 if (rects.size() > 0) {
12758 for (
int i = 0; i <
mPositions.size(); ++i) {
12761 qDebug() << Q_FUNC_INFO <<
"position with name not found:" <<
name;
12776 for (
int i = 0; i <
mAnchors.size(); ++i) {
12779 qDebug() << Q_FUNC_INFO <<
"anchor with name not found:" <<
name;
12793 for (
int i = 0; i <
mAnchors.size(); ++i) {
12850 const QPointF &pos,
12851 bool filledRect)
const {
12855 QList<QLineF> lines;
12856 lines << QLineF(rect.topLeft(), rect.topRight())
12857 << QLineF(rect.bottomLeft(), rect.bottomRight())
12858 << QLineF(rect.topLeft(), rect.bottomLeft())
12859 << QLineF(rect.topRight(), rect.bottomRight());
12860 double minDistSqr = (std::numeric_limits<double>::max)();
12861 for (
int i = 0; i < lines.size(); ++i) {
12863 lines.at(i).p1(), lines.at(i).p2());
12864 if (distSqr < minDistSqr) minDistSqr = distSqr;
12866 result = qSqrt(minDistSqr);
12870 if (rect.contains(pos))
12889 qDebug() << Q_FUNC_INFO
12890 <<
"called on item which shouldn't have any anchors (this method "
12891 "not reimplemented). anchorId"
12914 qDebug() << Q_FUNC_INFO
12915 <<
"anchor/position with name exists already:" <<
name;
12924 return newPosition;
12952 qDebug() << Q_FUNC_INFO
12953 <<
"anchor/position with name exists already:" <<
name;
12963 const QVariant &details,
12964 bool *selectionStateChanged) {
12970 if (selectionStateChanged)
12971 *selectionStateChanged =
mSelected != selBefore;
12980 if (selectionStateChanged)
12981 *selectionStateChanged =
mSelected != selBefore;
13341 mBufferDevicePixelRatio(1.0),
13343 mAutoAddPlottableToLegend(true),
13347 mSelectionTolerance(8),
13348 mNoAntialiasingOnDrag(false),
13349 mBackgroundBrush(Qt::
white, Qt::SolidPattern),
13350 mBackgroundScaled(true),
13351 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
13354 mMultiSelectModifier(Qt::ControlModifier),
13358 mMouseHasMoved(false),
13359 mMouseEventLayerable(0),
13360 mMouseSignalLayerable(0),
13361 mReplotting(false),
13362 mReplotQueued(false),
13363 mOpenGlMultisamples(16),
13364 mOpenGlAntialiasedElementsBackup(
QCP::
aeNone),
13365 mOpenGlCacheLabelsBackup(true) {
13366 setAttribute(Qt::WA_NoMousePropagation);
13367 setAttribute(Qt::WA_OpaquePaintEvent);
13368 setFocusPolicy(Qt::ClickFocus);
13369 setMouseTracking(
true);
13370 QLocale currentLocale = locale();
13371 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
13372 setLocale(currentLocale);
13373 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
13374 #ifdef QCP_DEVICEPIXELRATIO_FLOAT
13410 Qt::AlignRight | Qt::AlignTop);
13413 defaultAxisRect->
setLayer(QLatin1String(
"background"));
13469 const QCP::AntialiasedElements &antialiasedElements) {
13519 const QCP::AntialiasedElements ¬AntialiasedElements) {
13540 else if (enabled &&
13748 disconnect(
mSelectionRect, SIGNAL(accepted(QRect, QMouseEvent *)),
13751 disconnect(
mSelectionRect, SIGNAL(accepted(QRect, QMouseEvent *)),
13838 #ifdef QCUSTOMPLOT_USE_OPENGL
13853 qDebug() << Q_FUNC_INFO
13854 <<
"Failed to enable OpenGL, continuing plotting without "
13855 "hardware acceleration.";
13872 qDebug() << Q_FUNC_INFO
13873 <<
"QCustomPlot can't use OpenGL because QCUSTOMPLOT_USE_OPENGL "
13874 "was not defined during compilation (add 'DEFINES += "
13875 "QCUSTOMPLOT_USE_OPENGL' to your qmake .pro file)";
13917 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
13924 qDebug() << Q_FUNC_INFO
13925 <<
"Device pixel ratios not supported for Qt versions before "
13982 Qt::AspectRatioMode mode) {
14027 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
14057 qDebug() << Q_FUNC_INFO <<
"plottable not in list:"
14058 <<
reinterpret_cast<quintptr
>(
plottable);
14081 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
14118 QList<QCPAbstractPlottable *>
result;
14139 bool onlySelectable)
const {
14141 double resultDistance =
14147 if (onlySelectable &&
14156 .contains(pos.toPoint()))
14161 if (currentDistance >= 0 && currentDistance < resultDistance) {
14163 resultDistance = currentDistance;
14168 return resultPlottable;
14187 if (index >= 0 && index <
mGraphs.size()) {
14190 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
14223 if (!keyAxis) keyAxis =
xAxis;
14224 if (!valueAxis) valueAxis =
yAxis;
14225 if (!keyAxis || !valueAxis) {
14226 qDebug() << Q_FUNC_INFO
14227 <<
"can't use default QCustomPlot xAxis or yAxis, because at "
14228 "least one is invalid (has been deleted)";
14232 qDebug() << Q_FUNC_INFO
14233 <<
"passed keyAxis or valueAxis doesn't have this QCustomPlot "
14239 newGraph->
setName(QLatin1String(
"Graph ") +
14240 QString::number(
mGraphs.size()));
14264 if (index >= 0 && index <
mGraphs.size())
14302 QList<QCPGraph *>
result;
14318 if (index >= 0 && index <
mItems.size()) {
14319 return mItems.at(index);
14321 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
14334 if (!
mItems.isEmpty()) {
14353 qDebug() << Q_FUNC_INFO
14354 <<
"item not in list:" <<
reinterpret_cast<quintptr
>(
item);
14364 if (index >= 0 && index <
mItems.size())
14367 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
14400 QList<QCPAbstractItem *>
result;
14421 bool onlySelectable)
const {
14423 double resultDistance =
14429 if (onlySelectable &&
14442 if (currentDistance >= 0 && currentDistance < resultDistance) {
14444 resultDistance = currentDistance;
14483 if (index >= 0 && index <
mLayers.size()) {
14486 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
14512 qDebug() << Q_FUNC_INFO <<
"layer with name doesn't exist:" <<
name;
14528 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:"
14529 <<
reinterpret_cast<quintptr
>(
layer);
14562 if (!otherLayer) otherLayer =
mLayers.last();
14563 if (!
mLayers.contains(otherLayer)) {
14564 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:"
14565 <<
reinterpret_cast<quintptr
>(otherLayer);
14569 qDebug() << Q_FUNC_INFO <<
"A layer exists already with the name"
14600 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:"
14601 <<
reinterpret_cast<quintptr
>(
layer);
14605 qDebug() << Q_FUNC_INFO <<
"can't remove last layer";
14612 bool isFirstLayer = removedIndex == 0;
14614 :
mLayers.at(removedIndex - 1);
14619 for (
int i = children.size() - 1; i >= 0; --i)
14620 children.at(i)->moveToLayer(targetLayer,
true);
14623 for (
int i = 0; i < children.size(); ++i)
14624 children.at(i)->moveToLayer(targetLayer,
false);
14652 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:"
14653 <<
reinterpret_cast<quintptr
>(
layer);
14656 if (!
mLayers.contains(otherLayer)) {
14657 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:"
14658 <<
reinterpret_cast<quintptr
>(otherLayer);
14673 otherLayer->
mPaintBuffer.toStrongRef()->setInvalidated();
14713 const QList<QCPAxisRect *> rectList =
axisRects();
14714 if (index >= 0 && index < rectList.size()) {
14715 return rectList.at(index);
14717 qDebug() << Q_FUNC_INFO <<
"invalid axis rect index" << index;
14735 QList<QCPAxisRect *>
result;
14736 QStack<QCPLayoutElement *> elementStack;
14739 while (!elementStack.isEmpty()) {
14741 elementStack.pop()->
elements(
false)) {
14743 elementStack.push(element);
14744 if (
QCPAxisRect *ar = qobject_cast<QCPAxisRect *>(element))
14765 bool searchSubElements =
true;
14766 while (searchSubElements && currentElement) {
14767 searchSubElements =
false;
14769 currentElement->
elements(
false)) {
14772 currentElement = subElement;
14773 searchSubElements =
true;
14778 return currentElement;
14796 bool searchSubElements =
true;
14797 while (searchSubElements && currentElement) {
14798 searchSubElements =
false;
14800 currentElement->
elements(
false)) {
14803 currentElement = subElement;
14804 searchSubElements =
true;
14806 qobject_cast<QCPAxisRect *>(currentElement))
14823 QList<QCPAxis *>
result, allAxes;
14826 foreach (
QCPAxis *axis, allAxes) {
14842 QList<QCPLegend *>
result;
14844 QStack<QCPLayoutElement *> elementStack;
14847 while (!elementStack.isEmpty()) {
14849 elementStack.pop()->
elements(
false)) {
14851 elementStack.push(subElement);
14852 if (
QCPLegend *leg = qobject_cast<QCPLegend *>(subElement)) {
14913 QTimer::singleShot(0,
this, SLOT(
replot()));
14954 QList<QCPAxis *> allAxes;
14957 foreach (
QCPAxis *axis, allAxes) axis->
rescale(onlyVisiblePlottables);
15005 const QString &pdfCreator,
15006 const QString &pdfTitle) {
15007 bool success =
false;
15008 #ifdef QT_NO_PRINTER
15010 Q_UNUSED(exportPen)
15013 Q_UNUSED(pdfCreator)
15015 qDebug() << Q_FUNC_INFO
15016 <<
"Qt was built without printer support (QT_NO_PRINTER). PDF not "
15019 int newWidth, newHeight;
15021 newWidth = this->
width();
15022 newHeight = this->
height();
15028 QPrinter printer(QPrinter::ScreenResolution);
15029 printer.setOutputFileName(fileName);
15030 printer.setOutputFormat(QPrinter::PdfFormat);
15031 printer.setColorMode(QPrinter::Color);
15032 printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator);
15033 printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName,
15037 #if QT_VERSION < QT_VERSION_CHECK(5, 3, 0)
15038 printer.setFullPage(
true);
15039 printer.setPaperSize(
viewport().
size(), QPrinter::DevicePixel);
15041 QPageLayout pageLayout;
15042 pageLayout.setMode(QPageLayout::FullPageMode);
15043 pageLayout.setOrientation(QPageLayout::Portrait);
15044 pageLayout.setMargins(QMarginsF(0, 0, 0, 0));
15045 pageLayout.setPageSize(QPageSize(
viewport().
size(), QPageSize::Point,
15046 QString(), QPageSize::ExactMatch));
15047 printer.setPageLayout(pageLayout);
15050 if (printpainter.
begin(&printer)) {
15062 draw(&printpainter);
15063 printpainter.end();
15131 resolution, resolutionUnit);
15190 resolution, resolutionUnit);
15279 if (painter.isActive()) {
15280 painter.setRenderHint(QPainter::Antialiasing);
15284 for (
int bufferIndex = 0; bufferIndex <
mPaintBuffers.size();
15321 QList<QVariant> details;
15322 QList<QCPLayerable *> candidates =
15324 for (
int i = 0; i < candidates.size(); ++i) {
15328 candidates.at(i)->mouseDoubleClickEvent(
event, details.at(i));
15329 if (
event->isAccepted()) {
15337 if (!candidates.isEmpty()) {
15339 qobject_cast<QCPAbstractPlottable *>(candidates.first())) {
15342 dataIndex = details.first()
15347 }
else if (
QCPAxis *ax = qobject_cast<QCPAxis *>(candidates.first()))
15352 qobject_cast<QCPAbstractItem *>(candidates.first()))
15354 else if (
QCPLegend *lg = qobject_cast<QCPLegend *>(candidates.first()))
15357 qobject_cast<QCPAbstractLegendItem *>(
15358 candidates.first()))
15392 QList<QVariant> details;
15393 QList<QCPLayerable *> candidates =
15395 if (!candidates.isEmpty()) {
15397 candidates.first();
15403 for (
int i = 0; i < candidates.size(); ++i) {
15407 candidates.at(i)->mousePressEvent(
event, details.at(i));
15408 if (
event->isAccepted()) {
15496 .value<QCPAxis::SelectablePart>(),
15505 qobject_cast<QCPAbstractLegendItem *>(
15541 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
15542 const QPointF pos =
event->pos();
15544 const QPointF pos =
event->position();
15553 if (
event->isAccepted())
break;
15638 Qt::SmoothTransformation);
15639 painter->drawPixmap(
15644 painter->drawPixmap(
15674 int bufferIndex = 0;
15679 for (
int layerIndex = 0; layerIndex <
mLayers.size(); ++layerIndex) {
15686 mPaintBuffers.append(QSharedPointer<QCPAbstractPaintBuffer>(
15689 if (layerIndex <
mLayers.size() - 1 &&
15690 mLayers.at(layerIndex + 1)->mode() ==
15697 mPaintBuffers.append(QSharedPointer<QCPAbstractPaintBuffer>(
15726 #if defined(QCP_OPENGL_FBO)
15730 #elif defined(QCP_OPENGL_PBUFFER)
15735 qDebug() << Q_FUNC_INFO
15736 <<
"OpenGL enabled even though no support for it compiled in, "
15737 "this shouldn't have happened. Falling back to pixmap "
15781 #ifdef QCP_OPENGL_FBO
15783 QSurfaceFormat proposedSurfaceFormat;
15785 #ifdef QCP_OPENGL_OFFSCREENSURFACE
15786 QOffscreenSurface *surface =
new QOffscreenSurface;
15788 QWindow *surface =
new QWindow;
15789 surface->setSurfaceType(QSurface::OpenGLSurface);
15791 surface->setFormat(proposedSurfaceFormat);
15793 mGlSurface = QSharedPointer<QSurface>(surface);
15794 mGlContext = QSharedPointer<QOpenGLContext>(
new QOpenGLContext);
15795 mGlContext->setFormat(mGlSurface->format());
15796 if (!mGlContext->create()) {
15797 qDebug() << Q_FUNC_INFO <<
"Failed to create OpenGL context";
15798 mGlContext.clear();
15799 mGlSurface.clear();
15802 if (!mGlContext->makeCurrent(
15803 mGlSurface.data()))
15806 qDebug() << Q_FUNC_INFO <<
"Failed to make opengl context current";
15807 mGlContext.clear();
15808 mGlSurface.clear();
15811 if (!QOpenGLFramebufferObject::hasOpenGLFramebufferObjects()) {
15814 <<
"OpenGL of this system doesn't support frame buffer objects";
15815 mGlContext.clear();
15816 mGlSurface.clear();
15819 mGlPaintDevice = QSharedPointer<QOpenGLPaintDevice>(
new QOpenGLPaintDevice);
15821 #elif defined(QCP_OPENGL_PBUFFER)
15822 return QGLFormat::hasOpenGL();
15841 #ifdef QCP_OPENGL_FBO
15842 mGlPaintDevice.clear();
15843 mGlContext.clear();
15844 mGlSurface.clear();
15870 if (this->legend ==
legend) this->legend = 0;
15893 bool selectionStateChanged =
false;
15896 QMap<int, QPair<QCPAbstractPlottable *, QCPDataSelection>>
15897 potentialSelections;
15900 QRectF rectF(rect.normalized());
15905 affectedAxisRect->plottables()) {
15909 plottableInterface->selectTestRect(rectF,
true);
15911 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
15912 potentialSelections.insertMulti(
15914 QPair<QCPAbstractPlottable *, QCPDataSelection>(
15917 potentialSelections.insert(
15919 QPair<QCPAbstractPlottable *, QCPDataSelection>(
15929 if (!potentialSelections.isEmpty()) {
15930 QMap<int, QPair<QCPAbstractPlottable *, QCPDataSelection>>::
15931 iterator it = potentialSelections.begin();
15932 while (it != potentialSelections.end() -
15934 it = potentialSelections.erase(it);
15945 if ((potentialSelections.isEmpty() ||
15946 potentialSelections.constBegin()->first !=
15950 bool selChanged =
false;
15952 selectionStateChanged |= selChanged;
15960 QMap<int, QPair<QCPAbstractPlottable *, QCPDataSelection>>::
15961 const_iterator it = potentialSelections.constEnd();
15962 while (it != potentialSelections.constBegin()) {
15965 it.value().first->selectionCategory())) {
15966 bool selChanged =
false;
15967 it.value().first->selectEvent(
15969 QVariant::fromValue(it.value().second),
15971 selectionStateChanged |= selChanged;
15977 if (selectionStateChanged) {
15999 QList<QCPAxis *> affectedAxes =
16002 affectedAxes.removeAll(
static_cast<QCPAxis *
>(0));
16032 bool selectionStateChanged =
false;
16039 if (layerable != clickedLayerable &&
16041 bool selChanged =
false;
16043 selectionStateChanged |= selChanged;
16048 if (clickedLayerable &&
16051 bool selChanged =
false;
16053 selectionStateChanged |= selChanged;
16055 if (selectionStateChanged) {
16075 qDebug() << Q_FUNC_INFO
16076 <<
"plottable already added to this QCustomPlot:"
16077 <<
reinterpret_cast<quintptr
>(
plottable);
16081 qDebug() << Q_FUNC_INFO
16082 <<
"plottable not created with this QCustomPlot as parent:"
16083 <<
reinterpret_cast<quintptr
>(
plottable);
16109 qDebug() << Q_FUNC_INFO <<
"passed graph is zero";
16113 qDebug() << Q_FUNC_INFO
16114 <<
"graph already registered with this QCustomPlot";
16135 qDebug() << Q_FUNC_INFO <<
"item already added to this QCustomPlot:"
16136 <<
reinterpret_cast<quintptr
>(
item);
16140 qDebug() << Q_FUNC_INFO
16141 <<
"item not created with this QCustomPlot as parent:"
16142 <<
reinterpret_cast<quintptr
>(
item);
16160 for (
int i = 0; i <
mLayers.size(); ++i)
mLayers.at(i)->mIndex = i;
16182 bool onlySelectable,
16183 QVariant *selectionDetails)
const {
16184 QList<QVariant> details;
16186 pos, onlySelectable, selectionDetails ? &details : 0);
16187 if (selectionDetails && !details.isEmpty())
16188 *selectionDetails = details.first();
16189 if (!candidates.isEmpty())
16190 return candidates.first();
16217 const QPointF &pos,
16218 bool onlySelectable,
16219 QList<QVariant> *selectionDetails)
const {
16220 QList<QCPLayerable *>
result;
16221 for (
int layerIndex =
mLayers.size() - 1; layerIndex >= 0; --layerIndex) {
16222 const QList<QCPLayerable *> layerables =
16223 mLayers.at(layerIndex)->children();
16224 for (
int i = layerables.size() - 1; i >= 0; --i) {
16225 if (!layerables.at(i)->realVisibility())
continue;
16227 double dist = layerables.at(i)->selectTest(
16228 pos, onlySelectable, selectionDetails ? &details : 0);
16230 result.append(layerables.at(i));
16231 if (selectionDetails) selectionDetails->append(details);
16270 int dotsPerMeter = 0;
16271 switch (resolutionUnit) {
16273 dotsPerMeter = resolution;
16276 dotsPerMeter = resolution * 100;
16279 dotsPerMeter = resolution / 0.0254;
16282 buffer.setDotsPerMeterX(
16286 buffer.setDotsPerMeterY(
16290 if (!buffer.isNull())
16291 return buffer.save(fileName,
format, quality);
16308 int newWidth, newHeight;
16310 newWidth = this->
width();
16311 newHeight = this->
height();
16316 int scaledWidth = qRound(scale * newWidth);
16317 int scaledHeight = qRound(scale * newHeight);
16319 QPixmap
result(scaledWidth, scaledHeight);
16322 : Qt::transparent);
16327 if (painter.isActive()) {
16331 if (!qFuzzyCompare(scale, 1.0)) {
16336 painter.scale(scale, scale);
16348 qDebug() << Q_FUNC_INFO <<
"Couldn't activate painter on pixmap";
16371 int newWidth, newHeight;
16373 newWidth = this->
width();
16374 newHeight = this->
height();
16380 if (painter->isActive()) {
16392 qDebug() << Q_FUNC_INFO <<
"Passed painter is not active";
16445 : mLevelCount(350),
16446 mColorInterpolation(ciRGB),
16448 mColorBufferInvalidated(true) {
16459 : mLevelCount(350),
16460 mColorInterpolation(ciRGB),
16462 mColorBufferInvalidated(true) {
16469 return ((other.
mLevelCount == this->mLevelCount) &&
16471 (other.
mPeriodic == this->mPeriodic) &&
16484 qDebug() << Q_FUNC_INFO <<
"n must be greater or equal 2 but was" << n;
16581 int dataIndexFactor,
16582 bool logarithmic) {
16586 qDebug() << Q_FUNC_INFO <<
"null pointer given as data";
16590 qDebug() << Q_FUNC_INFO <<
"null pointer given as scanLine";
16595 if (!logarithmic) {
16598 for (
int i = 0; i < n; ++i) {
16599 int index = (int)((
data[dataIndexFactor * i] - range.
lower) *
16600 posToIndexFactor) %
16606 for (
int i = 0; i < n; ++i) {
16607 int index = (
data[dataIndexFactor * i] - range.
lower) *
16619 for (
int i = 0; i < n; ++i) {
16620 int index = (int)(qLn(
data[dataIndexFactor * i] / range.
lower) /
16628 for (
int i = 0; i < n; ++i) {
16629 int index = qLn(
data[dataIndexFactor * i] / range.
lower) /
16651 const unsigned char *alpha,
16655 int dataIndexFactor,
16656 bool logarithmic) {
16660 qDebug() << Q_FUNC_INFO <<
"null pointer given as data";
16664 qDebug() << Q_FUNC_INFO <<
"null pointer given as alpha";
16668 qDebug() << Q_FUNC_INFO <<
"null pointer given as scanLine";
16673 if (!logarithmic) {
16676 for (
int i = 0; i < n; ++i) {
16677 int index = (int)((
data[dataIndexFactor * i] - range.
lower) *
16678 posToIndexFactor) %
16681 if (alpha[dataIndexFactor * i] == 255) {
16685 const float alphaF = alpha[dataIndexFactor * i] / 255.0f;
16687 qRgba(qRed(
rgb) * alphaF, qGreen(
rgb) * alphaF,
16688 qBlue(
rgb) * alphaF, qAlpha(
rgb) * alphaF);
16692 for (
int i = 0; i < n; ++i) {
16693 int index = (
data[dataIndexFactor * i] - range.
lower) *
16699 if (alpha[dataIndexFactor * i] == 255) {
16703 const float alphaF = alpha[dataIndexFactor * i] / 255.0f;
16705 qRgba(qRed(
rgb) * alphaF, qGreen(
rgb) * alphaF,
16706 qBlue(
rgb) * alphaF, qAlpha(
rgb) * alphaF);
16713 for (
int i = 0; i < n; ++i) {
16714 int index = (int)(qLn(
data[dataIndexFactor * i] / range.
lower) /
16719 if (alpha[dataIndexFactor * i] == 255) {
16723 const float alphaF = alpha[dataIndexFactor * i] / 255.0f;
16725 qRgba(qRed(
rgb) * alphaF, qGreen(
rgb) * alphaF,
16726 qBlue(
rgb) * alphaF, qAlpha(
rgb) * alphaF);
16730 for (
int i = 0; i < n; ++i) {
16731 int index = qLn(
data[dataIndexFactor * i] / range.
lower) /
16737 if (alpha[dataIndexFactor * i] == 255) {
16741 const float alphaF = alpha[dataIndexFactor * i] / 255.0f;
16743 qRgba(qRed(
rgb) * alphaF, qGreen(
rgb) * alphaF,
16744 qBlue(
rgb) * alphaF, qAlpha(
rgb) * alphaF);
16766 bool logarithmic) {
16915 result.clearColorStops();
16916 for (QMap<double, QColor>::const_iterator it =
mColorStops.constBegin();
16918 result.setColorStopAt(1.0 - it.key(), it.value());
16928 for (QMap<double, QColor>::const_iterator it =
mColorStops.constBegin();
16930 if (it.value().alpha() < 255)
return true;
16944 double indexToPosFactor = 1.0 / (double)(
mLevelCount - 1);
16947 double position = i * indexToPosFactor;
16948 QMap<double, QColor>::const_iterator it =
16954 const QColor col = (it - 1).value();
16955 const float alphaPremultiplier =
16960 qRgba(col.red() * alphaPremultiplier,
16961 col.green() * alphaPremultiplier,
16962 col.blue() * alphaPremultiplier, col.alpha());
16971 const QColor col = it.value();
16972 const float alphaPremultiplier =
16977 qRgba(col.red() * alphaPremultiplier,
16978 col.green() * alphaPremultiplier,
16979 col.blue() * alphaPremultiplier, col.alpha());
16985 QMap<double, QColor>::const_iterator high = it;
16986 QMap<double, QColor>::const_iterator low = it - 1;
16989 (high.key() - low.key());
16993 const int alpha = (1 - t) * low.value().alpha() +
16994 t * high.value().alpha();
16995 const float alphaPremultiplier =
17000 qRgba(((1 - t) * low.value().red() +
17001 t * high.value().red()) *
17002 alphaPremultiplier,
17003 ((1 - t) * low.value().green() +
17004 t * high.value().green()) *
17005 alphaPremultiplier,
17006 ((1 - t) * low.value().blue() +
17007 t * high.value().blue()) *
17008 alphaPremultiplier,
17012 qRgb(((1 - t) * low.value().red() +
17013 t * high.value().red()),
17014 ((1 - t) * low.value().green() +
17015 t * high.value().green()),
17016 ((1 - t) * low.value().blue() +
17017 t * high.value().blue()));
17022 QColor lowHsv = low.value().toHsv();
17023 QColor highHsv = high.value().toHsv();
17025 double hueDiff = highHsv.hueF() - lowHsv.hueF();
17027 hue = lowHsv.hueF() - t * (1.0 - hueDiff);
17028 else if (hueDiff < -0.5)
17029 hue = lowHsv.hueF() + t * (1.0 + hueDiff);
17031 hue = lowHsv.hueF() + t * hueDiff;
17034 else if (hue >= 1.0)
17040 (1 - t) * lowHsv.saturationF() +
17041 t * highHsv.saturationF(),
17042 (1 - t) * lowHsv.valueF() +
17043 t * highHsv.valueF())
17045 const float alpha = (1 - t) * lowHsv.alphaF() +
17046 t * highHsv.alphaF();
17048 qRed(
rgb) * alpha, qGreen(
rgb) * alpha,
17049 qBlue(
rgb) * alpha, 255 * alpha);
17054 (1 - t) * lowHsv.saturationF() +
17055 t * highHsv.saturationF(),
17056 (1 - t) * lowHsv.valueF() +
17057 t * highHsv.valueF())
17067 const float alpha =
mColorStops.constBegin().value().alphaF();
17069 qBlue(
rgb) * alpha, 255 * alpha));
17106 : mBracketPen(QPen(Qt::
black)),
17107 mBracketBrush(Qt::NoBrush),
17109 mBracketHeight(50),
17110 mBracketStyle(bsSquareBracket),
17111 mTangentToData(false),
17112 mTangentAverage(2) {}
17199 int direction)
const {
17215 -180 * 16 * direction);
17231 qDebug() << Q_FUNC_INFO
17232 <<
"unknown/custom bracket style can't be handeld by "
17233 "default implementation:"
17260 int closeBracketDir = -openBracketDir;
17261 QPointF openBracketPos =
17263 QPointF closeBracketPos =
17265 double openBracketAngle = 0;
17266 double closeBracketAngle = 0;
17269 interface1d, dataRange.
begin(), openBracketDir);
17271 interface1d, dataRange.
end() - 1, closeBracketDir);
17274 QTransform oldTransform = painter->transform();
17277 painter->translate(openBracketPos);
17278 painter->rotate(openBracketAngle /
M_PI * 180.0);
17280 painter->setTransform(oldTransform);
17284 painter->translate(closeBracketPos);
17285 painter->rotate(closeBracketAngle /
M_PI * 180.0);
17287 painter->setTransform(oldTransform);
17310 int direction)
const {
17311 if (!interface1d || dataIndex < 0 || dataIndex >= interface1d->
dataCount())
17313 direction = direction < 0 ? -1 : 1;
17323 qDebug() << averageCount;
17325 QVector<QPointF>
points(averageCount);
17326 QPointF pointsAverage;
17327 int currentIndex = dataIndex;
17328 for (
int i = 0; i < averageCount; ++i) {
17330 pointsAverage +=
points[i];
17331 currentIndex += direction;
17333 pointsAverage /= (double)averageCount;
17337 double denomSum = 0;
17338 for (
int i = 0; i < averageCount; ++i) {
17339 const double dx =
points.at(i).x() - pointsAverage.x();
17340 const double dy =
points.at(i).y() - pointsAverage.y();
17342 denomSum += dx * dx;
17344 if (!qFuzzyIsNull(denomSum) && !qFuzzyIsNull(numSum)) {
17345 return qAtan2(numSum, denomSum);
17360 if (!keyAxis || !valueAxis) {
17361 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
17362 return QPointF(0, 0);
17523 mBackgroundBrush(Qt::NoBrush),
17524 mBackgroundScaled(true),
17525 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
17527 mRangeDrag(Qt::Horizontal | Qt::Vertical),
17528 mRangeZoom(Qt::Horizontal | Qt::Vertical),
17529 mRangeZoomFactorHorz(0.85),
17530 mRangeZoomFactorVert(0.85),
17543 if (setupDefaultAxes) {
17567 QList<QCPAxis *> axesList =
axes();
17568 for (
int i = 0; i < axesList.size(); ++i)
removeAxis(axesList.at(i));
17587 QList<QCPAxis *> ax(
mAxes.value(
type));
17588 if (index >= 0 && index < ax.size()) {
17589 return ax.at(index);
17591 qDebug() << Q_FUNC_INFO <<
"Axis index out of bounds:" << index;
17605 QList<QCPAxis *>
result;
17620 QList<QCPAxis *>
result;
17621 QHashIterator<QCPAxis::AxisType, QList<QCPAxis *>> it(
mAxes);
17622 while (it.hasNext()) {
17660 qDebug() << Q_FUNC_INFO
17661 <<
"passed axis has different axis type than specified in "
17665 if (newAxis->
axisRect() !=
this) {
17666 qDebug() << Q_FUNC_INFO
17667 <<
"passed axis doesn't have this axis rect as parent "
17671 if (
axes().contains(newAxis)) {
17672 qDebug() << Q_FUNC_INFO
17673 <<
"passed axis is already owned by this axis rect";
17724 QList<QCPAxis *>
result;
17742 QHashIterator<QCPAxis::AxisType, QList<QCPAxis *>> it(
mAxes);
17743 while (it.hasNext()) {
17745 if (it.value().contains(
axis)) {
17746 if (it.value().first() ==
axis &&
17747 it.value().size() >
17753 if (qobject_cast<QCustomPlot *>(
17764 qDebug() << Q_FUNC_INFO
17765 <<
"Axis isn't in axis rect:" <<
reinterpret_cast<quintptr
>(
axis);
17791 const QList<QCPAxis *> &affectedAxes) {
17794 qDebug() << Q_FUNC_INFO <<
"a passed axis was zero";
17799 pixelRange =
QCPRange(pixelRect.left(), pixelRect.right());
17801 pixelRange =
QCPRange(pixelRect.top(), pixelRect.bottom());
17829 QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
17863 xAxis2->
ticker()->setTickCount(xAxis->
ticker()->tickCount());
17864 xAxis2->
ticker()->setTickOrigin(xAxis->
ticker()->tickOrigin());
17872 yAxis2->
ticker()->setTickCount(yAxis->
ticker()->tickCount());
17873 yAxis2->
ticker()->setTickOrigin(yAxis->
ticker()->tickOrigin());
17875 if (connectRanges) {
17876 connect(xAxis, SIGNAL(rangeChanged(
QCPRange)), xAxis2,
17878 connect(yAxis, SIGNAL(rangeChanged(
QCPRange)), yAxis2,
17894 QList<QCPAbstractPlottable *>
result;
17914 QList<QCPGraph *>
result;
17938 QList<QCPAbstractItem *>
result;
17944 QList<QCPItemPosition *> positions =
17946 for (
int posId = 0; posId < positions.size(); ++posId) {
17947 if (positions.at(posId)->axisRect() ==
this ||
17948 positions.at(posId)->keyAxis()->axisRect() ==
this ||
17949 positions.at(posId)->valueAxis()->axisRect() ==
this) {
17973 QList<QCPAxis *> allAxes =
axes();
17974 for (
int i = 0; i < allAxes.size(); ++i)
17975 allAxes.at(i)->setupTickVectors();
17993 QList<QCPLayoutElement *>
result;
18059 Qt::AspectRatioMode mode) {
18100 if (orientation == Qt::Horizontal)
18116 if (orientation == Qt::Horizontal)
18130 QList<QCPAxis *>
result;
18131 if (orientation == Qt::Horizontal) {
18151 QList<QCPAxis *>
result;
18152 if (orientation == Qt::Horizontal) {
18232 QList<QCPAxis *> horz, vert;
18233 if (horizontal) horz.append(horizontal);
18234 if (vertical) vert.append(vertical);
18249 QList<QCPAxis *> horz, vert;
18266 QList<QCPAxis *> vertical) {
18268 foreach (
QCPAxis *ax, horizontal) {
18269 QPointer<QCPAxis> axPointer(ax);
18270 if (!axPointer.isNull())
18273 qDebug() << Q_FUNC_INFO <<
"invalid axis passed in horizontal list:"
18274 <<
reinterpret_cast<quintptr
>(ax);
18277 foreach (
QCPAxis *ax, vertical) {
18278 QPointer<QCPAxis> axPointer(ax);
18279 if (!axPointer.isNull())
18282 qDebug() << Q_FUNC_INFO <<
"invalid axis passed in vertical list:"
18283 <<
reinterpret_cast<quintptr
>(ax);
18302 QList<QCPAxis *> horz, vert;
18303 if (horizontal) horz.append(horizontal);
18304 if (vertical) vert.append(vertical);
18319 QList<QCPAxis *> horz, vert;
18336 QList<QCPAxis *> vertical) {
18338 foreach (
QCPAxis *ax, horizontal) {
18339 QPointer<QCPAxis> axPointer(ax);
18340 if (!axPointer.isNull())
18343 qDebug() << Q_FUNC_INFO <<
"invalid axis passed in horizontal list:"
18344 <<
reinterpret_cast<quintptr
>(ax);
18347 foreach (
QCPAxis *ax, vertical) {
18348 QPointer<QCPAxis> axPointer(ax);
18349 if (!axPointer.isNull())
18352 qDebug() << Q_FUNC_INFO <<
"invalid axis passed in vertical list:"
18353 <<
reinterpret_cast<quintptr
>(ax);
18369 double verticalFactor) {
18417 Qt::SmoothTransformation);
18418 painter->drawPixmap(
mRect.topLeft() + QPoint(0, -1),
18420 QRect(0, 0,
mRect.width(),
mRect.height()) &
18423 painter->drawPixmap(
mRect.topLeft() + QPoint(0, -1),
18425 QRect(0, 0,
mRect.width(),
mRect.height()));
18442 const QList<QCPAxis *> axesList =
mAxes.value(
type);
18443 if (axesList.isEmpty())
return;
18445 bool isFirstVisible =
18451 for (
int i = 1; i < axesList.size(); ++i) {
18452 int offset = axesList.at(i - 1)->offset() +
18453 axesList.at(i - 1)->calculateMargin();
18454 if (axesList.at(i)->visible())
18459 if (!isFirstVisible)
offset += axesList.at(i)->tickLengthIn();
18460 isFirstVisible =
false;
18462 axesList.at(i)->setOffset(
offset);
18469 qDebug() << Q_FUNC_INFO
18470 <<
"Called with side that isn't specified as auto margin";
18476 const QList<QCPAxis *> axesList =
18478 if (axesList.size() > 0)
18479 return axesList.last()->offset() + axesList.last()->calculateMargin();
18523 if (
event->buttons() & Qt::LeftButton) {
18610 const QPointF &startPos) {
18645 double wheelSteps =
18650 if (!
axis.isNull())
18657 if (!
axis.isNull())
18717 mParentLegend(parent),
18718 mFont(parent->font()),
18719 mTextColor(parent->textColor()),
18720 mSelectedFont(parent->selectedFont()),
18721 mSelectedTextColor(parent->selectedTextColor()),
18724 setLayer(QLatin1String(
"legend"));
18793 bool onlySelectable,
18794 QVariant *details)
const {
18797 if (onlySelectable &&
18802 if (
mRect.contains(pos.toPoint()))
18820 const QVariant &details,
18821 bool *selectionStateChanged) {
18828 if (selectionStateChanged)
18829 *selectionStateChanged =
mSelected != selBefore;
18839 if (selectionStateChanged)
18840 *selectionStateChanged =
mSelected != selBefore;
18929 QRectF textRect = painter->fontMetrics().boundingRect(
18930 0, 0, 0, iconSize.height(), Qt::TextDontClip,
mPlottable->
name());
18931 QRectF iconRect(
mRect.topLeft(), iconSize);
18933 qMax(textRect.height(),
18934 iconSize.height());
18939 mRect.y(), textRect.width(), textHeight, Qt::TextDontClip,
18943 painter->setClipRect(iconRect, Qt::IntersectClip);
18949 painter->setBrush(Qt::NoBrush);
18950 int halfPen = qCeil(painter->pen().widthF() * 0.5) + 1;
18952 -halfPen, -halfPen, halfPen,
18955 painter->drawRect(iconRect);
18970 QFontMetrics fontMetrics(
getFont());
18972 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(),
18976 result.setHeight(qMax(textRect.height(), iconSize.height()));
19070 if (qobject_cast<QCustomPlot *>(
19082 bool hasSelectedItems =
false;
19083 for (
int i = 0; i <
itemCount(); ++i) {
19085 hasSelectedItems =
true;
19089 if (hasSelectedItems)
19116 for (
int i = 0; i <
itemCount(); ++i) {
19132 for (
int i = 0; i <
itemCount(); ++i) {
19209 SelectableParts newSelected = selected;
19215 newSelected.testFlag(
19218 qDebug() << Q_FUNC_INFO
19219 <<
"spItems flag can not be set, it can only be unset "
19220 "with this function";
19224 !newSelected.testFlag(
spItems))
19227 for (
int i = 0; i <
itemCount(); ++i) {
19275 for (
int i = 0; i <
itemCount(); ++i) {
19290 for (
int i = 0; i <
itemCount(); ++i) {
19304 return qobject_cast<QCPAbstractLegendItem *>(
elementAt(index));
19315 for (
int i = 0; i <
itemCount(); ++i) {
19317 qobject_cast<QCPPlottableLegendItem *>(
item(i))) {
19318 if (pli->plottable() == plottable)
return pli;
19341 for (
int i = 0; i <
itemCount(); ++i) {
19342 if (
item == this->
item(i))
return true;
19391 bool success =
remove(ali);
19435 QList<QCPAbstractLegendItem *>
result;
19436 for (
int i = 0; i <
itemCount(); ++i) {
19438 if (ali->selected())
result.append(ali);
19497 bool onlySelectable,
19498 QVariant *details)
const {
19512 const QVariant &details,
19513 bool *selectionStateChanged) {
19528 if (selectionStateChanged)
19539 if (selectionStateChanged)
19613 mTextFlags(Qt::AlignCenter | Qt::TextWordWrap),
19615 QLatin1String(
"sans serif"),
19617 mTextColor(Qt::
black),
19618 mSelectedFont(QFont(
19619 QLatin1String(
"sans serif"),
19621 mSelectedTextColor(Qt::
blue),
19622 mSelectable(false),
19640 mTextFlags(Qt::AlignCenter | Qt::TextWordWrap),
19642 QLatin1String(
"sans serif"),
19644 mTextColor(Qt::
black),
19645 mSelectedFont(QFont(
19646 QLatin1String(
"sans serif"),
19648 mSelectedTextColor(Qt::
blue),
19649 mSelectable(false),
19665 const QString &text,
19669 mTextFlags(Qt::AlignCenter | Qt::TextWordWrap),
19670 mFont(QFont(QLatin1String(
"sans serif"),
19673 mTextColor(Qt::
black),
19674 mSelectedFont(QFont(QLatin1String(
"sans serif"),
19677 mSelectedTextColor(Qt::
blue),
19678 mSelectable(false),
19682 mFont.setPointSizeF(pointSize);
19697 const QString &text,
19698 const QString &fontFamily,
19702 mTextFlags(Qt::AlignCenter | Qt::TextWordWrap),
19703 mFont(QFont(fontFamily, pointSize)),
19704 mTextColor(Qt::
black),
19705 mSelectedFont(QFont(fontFamily, pointSize)),
19706 mSelectedTextColor(Qt::
blue),
19707 mSelectable(false),
19719 const QString &text,
19723 mTextFlags(Qt::AlignCenter | Qt::TextWordWrap),
19725 mTextColor(Qt::
black),
19726 mSelectedFont(font),
19727 mSelectedTextColor(Qt::
blue),
19728 mSelectable(false),
19838 QFontMetrics metrics(
mFont);
19840 metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size());
19848 QFontMetrics metrics(
mFont);
19850 metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size());
19851 result.setWidth(QWIDGETSIZE_MAX);
19859 const QVariant &details,
19860 bool *selectionStateChanged) {
19866 if (selectionStateChanged)
19867 *selectionStateChanged =
mSelected != selBefore;
19876 if (selectionStateChanged)
19877 *selectionStateChanged =
mSelected != selBefore;
19892 bool onlySelectable,
19893 QVariant *details)
const {
19910 const QVariant &details) {
19922 const QPointF &startPos) {
19923 if ((QPointF(
event->pos()) - startPos).manhattanLength() <= 3)
19933 const QVariant &details) {
20063 mDataScaleType(
QCPAxis::stLinear),
20065 mAxisRect(new QCPColorScaleAxisRectPrivate(this)) {
20079 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
20089 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20093 return mAxisRect.data()->rangeDrag().testFlag(
20103 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20107 return mAxisRect.data()->rangeZoom().testFlag(
20125 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20131 QString labelTransfer;
20132 QSharedPointer<QCPAxisTicker> tickerTransfer;
20138 tickerTransfer =
mColorAxis.data()->ticker();
20146 QList<QCPAxis::AxisType> allAxisTypes =
20147 QList<QCPAxis::AxisType>()
20164 mColorAxis.data()->setTicker(tickerTransfer);
20170 mAxisRect.data()->setRangeDragAxes(QList<QCPAxis *>()
20247 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
20268 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20275 #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
20276 mAxisRect.data()->setRangeDrag(
nullptr);
20292 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20299 #if QT_VERSION < QT_VERSION_CHECK(5, 2, 0)
20300 mAxisRect.data()->setRangeDrag(
nullptr);
20311 QList<QCPColorMap *>
result;
20315 if (cm->colorScale() ==
this)
result.append(cm);
20327 QList<QCPColorMap *> maps =
colorMaps();
20329 bool haveRange =
false;
20333 for (
int i = 0; i < maps.size(); ++i) {
20334 if (!maps.at(i)->realVisibility() && onlyVisibleMaps)
continue;
20336 if (maps.at(i)->colorScale() ==
this) {
20337 bool currentFoundRange =
true;
20338 mapRange = maps.at(i)->data()->dataBounds();
20340 if (mapRange.
lower <= 0 && mapRange.
upper > 0)
20342 else if (mapRange.
lower <= 0 && mapRange.
upper <= 0)
20343 currentFoundRange =
false;
20345 if (mapRange.
upper >= 0 && mapRange.
lower < 0)
20347 else if (mapRange.
upper >= 0 && mapRange.
lower >= 0)
20348 currentFoundRange =
false;
20350 if (currentFoundRange) {
20352 newRange = mapRange;
20354 newRange.
expand(mapRange);
20365 double center = (newRange.
lower + newRange.
upper) *
20388 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20429 const QVariant &details) {
20431 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20439 const QPointF &startPos) {
20441 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20449 const QPointF &startPos) {
20451 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20460 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
20483 QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(
20485 :
QCPAxisRect(parentColorScale->parentPlot(), true),
20486 mParentColorScale(parentColorScale),
20487 mGradientImageInvalidated(true) {
20490 QList<QCPAxis::AxisType> allAxisTypes =
20497 connect(
axis(
type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)),
20498 this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts)));
20499 connect(
axis(
type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)),
20500 this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts)));
20541 if (mGradientImageInvalidated) updateGradientImage();
20543 bool mirrorHorz =
false;
20544 bool mirrorVert =
false;
20545 if (mParentColorScale->mColorAxis) {
20546 mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() &&
20549 mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() &&
20554 painter->drawImage(rect().adjusted(0, -1, 0, -1),
20555 mGradientImage.mirrored(mirrorHorz, mirrorVert));
20565 void QCPColorScaleAxisRectPrivate::updateGradientImage() {
20566 if (rect().isEmpty())
return;
20568 const QImage::Format
format = QImage::Format_ARGB32_Premultiplied;
20569 int n = mParentColorScale->mGradient.levelCount();
20571 QVector<double>
data(n);
20572 for (
int i = 0; i < n; ++i)
data[i] = i;
20576 h = rect().height();
20577 mGradientImage = QImage(w, h,
format);
20578 QVector<QRgb *> pixels;
20579 for (
int y = 0;
y < h; ++
y)
20580 pixels.append(
reinterpret_cast<QRgb *
>(mGradientImage.scanLine(
y)));
20581 mParentColorScale->mGradient.colorize(
20582 data.constData(),
QCPRange(0, n - 1), pixels.first(), n);
20583 for (
int y = 1;
y < h; ++
y)
20584 memcpy(pixels.at(
y), pixels.first(), n *
sizeof(QRgb));
20586 w = rect().width();
20588 mGradientImage = QImage(w, h,
format);
20589 for (
int y = 0;
y < h; ++
y) {
20590 QRgb *pixels =
reinterpret_cast<QRgb *
>(mGradientImage.scanLine(
y));
20591 const QRgb lineColor = mParentColorScale->mGradient.color(
20593 for (
int x = 0;
x < w; ++
x) pixels[
x] = lineColor;
20596 mGradientImageInvalidated =
false;
20604 void QCPColorScaleAxisRectPrivate::axisSelectionChanged(
20605 QCPAxis::SelectableParts selectedParts) {
20607 QList<QCPAxis::AxisType> allAxisTypes =
20611 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis *>(sender()))
20612 if (senderAxis->axisType() ==
type)
continue;
20616 axis(
type)->setSelectedParts(axis(
type)->selectedParts() |
20619 axis(
type)->setSelectedParts(axis(
type)->selectedParts() &
20630 void QCPColorScaleAxisRectPrivate::axisSelectableChanged(
20631 QCPAxis::SelectableParts selectableParts) {
20633 QList<QCPAxis::AxisType> allAxisTypes =
20637 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis *>(sender()))
20638 if (senderAxis->axisType() ==
type)
continue;
20642 axis(
type)->setSelectableParts(axis(
type)->selectableParts() |
20645 axis(
type)->setSelectableParts(axis(
type)->selectableParts() &
20862 const QVector<double> &values,
20863 bool alreadySorted) {
20865 addData(keys, values, alreadySorted);
20913 if (targetGraph ==
this) {
20914 qDebug() << Q_FUNC_INFO <<
"targetGraph is this graph itself";
20920 qDebug() << Q_FUNC_INFO <<
"targetGraph not in same plot";
20983 const QVector<double> &values,
20984 bool alreadySorted) {
20985 if (keys.size() != values.size())
20986 qDebug() << Q_FUNC_INFO
20987 <<
"keys and values have different sizes:" << keys.size()
20989 const int n = qMin(keys.size(), values.size());
20990 QVector<QCPGraphData> tempData(n);
20991 QVector<QCPGraphData>::iterator it = tempData.begin();
20992 const QVector<QCPGraphData>::iterator itEnd = tempData.end();
20994 while (it != itEnd) {
20996 it->value = values[i];
21025 bool onlySelectable,
21026 QVariant *details)
const {
21032 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
21037 int pointIndex = closestDataPoint -
mDataContainer->constBegin();
21055 const QCPRange &inKeyRange)
const {
21056 return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange);
21062 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21069 QVector<QPointF> lines,
21074 QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
21076 allSegments << unselectedSegments << selectedSegments;
21077 for (
int i = 0; i < allSegments.size(); ++i) {
21078 bool isSelectedSegment = i >= unselectedSegments.size();
21082 ? allSegments.at(i)
21092 #ifdef QCUSTOMPLOT_CHECK_DATA
21097 qDebug() << Q_FUNC_INFO <<
"Data point at" << it->key
21099 <<
"Plottable name:" <<
name();
21107 painter->setBrush(
mBrush);
21108 painter->
setPen(Qt::NoPen);
21117 painter->setBrush(Qt::NoBrush);
21129 finalScatterStyle =
21131 if (!finalScatterStyle.
isNone()) {
21146 if (
mBrush.style() != Qt::NoBrush) {
21148 painter->fillRect(QRectF(rect.left(), rect.top() + rect.height() / 2.0,
21149 rect.width(), rect.height() / 3.0),
21157 rect.left(), rect.top() + rect.height() / 2.0, rect.right() + 5,
21158 rect.top() + rect.height() /
21171 rect.size().toSize(), Qt::KeepAspectRatio,
21172 Qt::SmoothTransformation));
21174 scaledStyle.
drawShape(painter, QRectF(rect).center());
21207 if (!lines)
return;
21210 if (begin == end) {
21215 QVector<QCPGraphData> lineData;
21223 std::reverse(lineData.begin(), lineData.end());
21263 if (!scatters)
return;
21267 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21274 if (begin == end) {
21279 QVector<QCPGraphData>
data;
21286 std::reverse(
data.begin(),
data.end());
21288 scatters->resize(
data.size());
21290 for (
int i = 0; i <
data.size(); ++i) {
21291 if (!qIsNaN(
data.at(i).value)) {
21297 for (
int i = 0; i <
data.size(); ++i) {
21298 if (!qIsNaN(
data.at(i).value)) {
21319 const QVector<QCPGraphData> &
data)
const {
21320 QVector<QPointF>
result;
21324 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21332 for (
int i = 0; i <
data.size(); ++i) {
21338 for (
int i = 0; i <
data.size(); ++i) {
21359 const QVector<QCPGraphData> &
data)
const {
21360 QVector<QPointF>
result;
21364 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21373 for (
int i = 0; i <
data.size(); ++i) {
21375 result[i * 2 + 0].setX(lastValue);
21376 result[i * 2 + 0].setY(key);
21378 result[i * 2 + 1].setX(lastValue);
21379 result[i * 2 + 1].setY(key);
21384 for (
int i = 0; i <
data.size(); ++i) {
21386 result[i * 2 + 0].setX(key);
21387 result[i * 2 + 0].setY(lastValue);
21389 result[i * 2 + 1].setX(key);
21390 result[i * 2 + 1].setY(lastValue);
21409 const QVector<QCPGraphData> &
data)
const {
21410 QVector<QPointF>
result;
21414 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21423 for (
int i = 0; i <
data.size(); ++i) {
21425 result[i * 2 + 0].setX(value);
21426 result[i * 2 + 0].setY(lastKey);
21428 result[i * 2 + 1].setX(value);
21429 result[i * 2 + 1].setY(lastKey);
21434 for (
int i = 0; i <
data.size(); ++i) {
21436 result[i * 2 + 0].setX(lastKey);
21437 result[i * 2 + 0].setY(value);
21439 result[i * 2 + 1].setX(lastKey);
21440 result[i * 2 + 1].setY(value);
21459 const QVector<QCPGraphData> &
data)
const {
21460 QVector<QPointF>
result;
21464 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21474 result[0].setX(lastValue);
21475 result[0].setY(lastKey);
21476 for (
int i = 1; i <
data.size(); ++i) {
21479 result[i * 2 - 1].setX(lastValue);
21480 result[i * 2 - 1].setY(key);
21483 result[i * 2 + 0].setX(lastValue);
21484 result[i * 2 + 0].setY(key);
21486 result[
data.size() * 2 - 1].setX(lastValue);
21492 result[0].setX(lastKey);
21493 result[0].setY(lastValue);
21494 for (
int i = 1; i <
data.size(); ++i) {
21497 result[i * 2 - 1].setX(key);
21498 result[i * 2 - 1].setY(lastValue);
21501 result[i * 2 + 0].setX(key);
21502 result[i * 2 + 0].setY(lastValue);
21505 result[
data.size() * 2 - 1].setY(lastValue);
21523 const QVector<QCPGraphData> &
data)
const {
21524 QVector<QPointF>
result;
21528 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21536 for (
int i = 0; i <
data.size(); ++i) {
21539 result[i * 2 + 0].setY(key);
21541 result[i * 2 + 1].setY(key);
21545 for (
int i = 0; i <
data.size(); ++i) {
21547 result[i * 2 + 0].setX(key);
21549 result[i * 2 + 1].setX(key);
21579 if (painter->brush().style() == Qt::NoBrush ||
21580 painter->brush().color().alpha() == 0)
21584 QVector<QCPDataRange> segments =
21589 for (
int i = 0; i < segments.size(); ++i)
21593 QVector<QPointF> otherLines;
21596 if (!otherLines.isEmpty()) {
21599 QVector<QPair<QCPDataRange, QCPDataRange>> segmentPairs =
21602 for (
int i = 0; i < segmentPairs.size(); ++i)
21604 lines, segmentPairs.at(i).first, &otherLines,
21605 segmentPairs.at(i).second));
21619 const QVector<QPointF> &scatters,
21623 for (
int i = 0; i < scatters.size(); ++i)
21624 style.
drawShape(painter, scatters.at(i).x(), scatters.at(i).y());
21634 const QVector<QPointF> &lines)
const {
21635 if (painter->pen().style() != Qt::NoPen &&
21636 painter->pen().color().alpha() != 0) {
21651 const QVector<QPointF> &lines)
const {
21652 if (painter->pen().style() != Qt::NoPen &&
21653 painter->pen().color().alpha() != 0) {
21655 QPen oldPen = painter->pen();
21656 QPen newPen = painter->pen();
21657 newPen.setCapStyle(
21659 painter->
setPen(newPen);
21660 painter->drawLines(lines);
21661 painter->
setPen(oldPen);
21680 QVector<QCPGraphData> *lineData,
21683 if (!lineData)
return;
21687 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21690 if (begin == end)
return;
21693 int maxCount = (std::numeric_limits<int>::max)();
21697 if (2 * keyPixelSpan + 2 <
21698 static_cast<double>((std::numeric_limits<int>::max)()))
21699 maxCount = 2 * keyPixelSpan + 2;
21707 double minValue = it->value;
21708 double maxValue = it->value;
21710 int reversedFactor =
21714 int reversedRound = reversedFactor == -1
21721 double lastIntervalEndKey = currentIntervalStartKey;
21722 double keyEpsilon =
21723 qAbs(currentIntervalStartKey -
21726 1.0 * reversedFactor));
21729 bool keyEpsilonVariable =
21734 int intervalDataCount = 1;
21737 while (it != end) {
21739 currentIntervalStartKey +
21744 if (it->value < minValue)
21745 minValue = it->value;
21746 else if (it->value > maxValue)
21747 maxValue = it->value;
21748 ++intervalDataCount;
21751 if (intervalDataCount >=
21755 if (lastIntervalEndKey <
21756 currentIntervalStartKey -
21761 currentIntervalStartKey + keyEpsilon * 0.2,
21762 currentIntervalFirstPoint->value));
21764 currentIntervalStartKey + keyEpsilon * 0.25,
21767 currentIntervalStartKey + keyEpsilon * 0.75,
21770 currentIntervalStartKey +
21777 currentIntervalStartKey + keyEpsilon * 0.8,
21782 currentIntervalFirstPoint->value));
21783 lastIntervalEndKey = (it - 1)->key;
21784 minValue = it->value;
21785 maxValue = it->value;
21786 currentIntervalFirstPoint = it;
21789 if (keyEpsilonVariable)
21790 keyEpsilon = qAbs(currentIntervalStartKey -
21793 currentIntervalStartKey) +
21794 1.0 * reversedFactor));
21795 intervalDataCount = 1;
21800 if (intervalDataCount >= 2)
21803 if (lastIntervalEndKey <
21804 currentIntervalStartKey -
21809 QCPGraphData(currentIntervalStartKey + keyEpsilon * 0.2,
21810 currentIntervalFirstPoint->value));
21812 currentIntervalStartKey + keyEpsilon * 0.25, minValue));
21814 currentIntervalStartKey + keyEpsilon * 0.75, maxValue));
21816 lineData->append(
QCPGraphData(currentIntervalFirstPoint->key,
21817 currentIntervalFirstPoint->value));
21823 std::copy(begin, end, lineData->begin());
21842 QVector<QCPGraphData> *scatterData,
21845 if (!scatterData)
return;
21849 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21857 while (doScatterSkip && begin != end &&
21858 beginIndex % scatterModulo !=
21864 if (begin == end)
return;
21866 int maxCount = (std::numeric_limits<int>::max)();
21870 maxCount = 2 * keyPixelSpan + 2;
21880 int itIndex = beginIndex;
21881 double minValue = it->value;
21882 double maxValue = it->value;
21886 int reversedFactor =
21890 int reversedRound = reversedFactor == -1
21897 double keyEpsilon =
21898 qAbs(currentIntervalStartKey -
21901 1.0 * reversedFactor));
21904 bool keyEpsilonVariable =
21909 int intervalDataCount = 1;
21912 if (!doScatterSkip)
21915 itIndex += scatterModulo;
21916 if (itIndex < endIndex)
21917 it += scatterModulo;
21920 itIndex = endIndex;
21924 while (it != end) {
21926 currentIntervalStartKey +
21931 if (it->value < minValue && it->value > valueMinRange &&
21932 it->value < valueMaxRange) {
21933 minValue = it->value;
21935 }
else if (it->value > maxValue && it->value > valueMinRange &&
21936 it->value < valueMaxRange) {
21937 maxValue = it->value;
21940 ++intervalDataCount;
21943 if (intervalDataCount >=
21949 double valuePixelSpan =
21952 int dataModulo = qMax(
21954 qRound(intervalDataCount /
21959 currentIntervalStart;
21961 while (intervalIt != it) {
21962 if ((c % dataModulo == 0 || intervalIt == minValueIt ||
21963 intervalIt == maxValueIt) &&
21964 intervalIt->value > valueMinRange &&
21965 intervalIt->value < valueMaxRange)
21966 scatterData->append(*intervalIt);
21968 if (!doScatterSkip)
21980 }
else if (currentIntervalStart->value > valueMinRange &&
21981 currentIntervalStart->value < valueMaxRange)
21982 scatterData->append(*currentIntervalStart);
21983 minValue = it->value;
21984 maxValue = it->value;
21985 currentIntervalStart = it;
21988 if (keyEpsilonVariable)
21989 keyEpsilon = qAbs(currentIntervalStartKey -
21992 currentIntervalStartKey) +
21993 1.0 * reversedFactor));
21994 intervalDataCount = 1;
21997 if (!doScatterSkip)
22000 itIndex += scatterModulo;
22001 if (itIndex < endIndex)
22002 it += scatterModulo;
22005 itIndex = endIndex;
22010 if (intervalDataCount >=
22019 qMax(1, qRound(intervalDataCount /
22024 currentIntervalStart;
22025 int intervalItIndex = intervalIt -
mDataContainer->constBegin();
22027 while (intervalIt != it) {
22028 if ((c % dataModulo == 0 || intervalIt == minValueIt ||
22029 intervalIt == maxValueIt) &&
22030 intervalIt->value > valueMinRange &&
22031 intervalIt->value < valueMaxRange)
22032 scatterData->append(*intervalIt);
22034 if (!doScatterSkip)
22041 intervalItIndex += scatterModulo;
22042 if (intervalItIndex < itIndex)
22043 intervalIt += scatterModulo;
22046 intervalItIndex = itIndex;
22050 }
else if (currentIntervalStart->value > valueMinRange &&
22051 currentIntervalStart->value < valueMaxRange)
22052 scatterData->append(*currentIntervalStart);
22058 int itIndex = beginIndex;
22060 while (it != end) {
22061 scatterData->append(*it);
22063 if (!doScatterSkip)
22066 itIndex += scatterModulo;
22067 if (itIndex < endIndex)
22068 it += scatterModulo;
22071 itIndex = endIndex;
22091 if (rangeRestriction.
isEmpty()) {
22098 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22106 begin, end, rangeRestriction);
22125 const QVector<QPointF> *lineData,
22126 Qt::Orientation keyOrientation)
const {
22127 QVector<QCPDataRange>
result;
22128 const int n = lineData->size();
22133 if (keyOrientation == Qt::Horizontal) {
22136 qIsNaN(lineData->at(i).y()))
22141 !qIsNaN(lineData->at(i).y()))
22144 currentSegment.
setEnd(i++);
22145 result.append(currentSegment);
22151 qIsNaN(lineData->at(i).x()))
22156 !qIsNaN(lineData->at(i).x()))
22159 currentSegment.
setEnd(i++);
22160 result.append(currentSegment);
22187 QVector<QCPDataRange> thisSegments,
22188 const QVector<QPointF> *thisData,
22189 QVector<QCPDataRange> otherSegments,
22190 const QVector<QPointF> *otherData)
const {
22191 QVector<QPair<QCPDataRange, QCPDataRange>>
result;
22192 if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() ||
22193 otherSegments.isEmpty())
22197 int otherIndex = 0;
22198 const bool verticalKey =
mKeyAxis->orientation() == Qt::Vertical;
22199 while (thisIndex < thisSegments.size() &&
22200 otherIndex < otherSegments.size()) {
22201 if (thisSegments.at(thisIndex).size() <
22207 if (otherSegments.at(otherIndex).size() <
22213 double thisLower, thisUpper, otherLower, otherUpper;
22214 if (!verticalKey) {
22215 thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x();
22216 thisUpper = thisData->at(thisSegments.at(thisIndex).end() - 1).x();
22218 otherData->at(otherSegments.at(otherIndex).begin()).x();
22220 otherData->at(otherSegments.at(otherIndex).end() - 1).x();
22222 thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y();
22223 thisUpper = thisData->at(thisSegments.at(thisIndex).end() - 1).y();
22225 otherData->at(otherSegments.at(otherIndex).begin()).y();
22227 otherData->at(otherSegments.at(otherIndex).end() - 1).y();
22233 result.append(QPair<QCPDataRange, QCPDataRange>(
22234 thisSegments.at(thisIndex), otherSegments.at(otherIndex)));
22268 int &bPrecedence)
const {
22270 if (aLower > bUpper) {
22273 }
else if (bLower > aUpper) {
22277 if (aUpper > bUpper)
22279 else if (aUpper < bUpper)
22303 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22310 result.setX(matchingDataPoint.x());
22315 result.setY(matchingDataPoint.y());
22329 result.setY(matchingDataPoint.y());
22332 result.setX(matchingDataPoint.x());
22366 if (segment.
size() < 2)
return QPolygonF();
22371 lineData->constBegin() + segment.
end(),
result.begin() + 1);
22398 const QVector<QPointF> *thisData,
22400 const QVector<QPointF> *otherData,
22407 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22408 return QPolygonF();
22411 qDebug() << Q_FUNC_INFO <<
"channel fill target key axis invalid";
22412 return QPolygonF();
22417 return QPolygonF();
22421 if (thisData->isEmpty())
return QPolygonF();
22422 QVector<QPointF> thisSegmentData(thisSegment.
size());
22423 QVector<QPointF> otherSegmentData(otherSegment.
size());
22425 thisData->constBegin() + thisSegment.
end(),
22426 thisSegmentData.begin());
22428 otherData->constBegin() + otherSegment.
end(),
22429 otherSegmentData.begin());
22432 QVector<QPointF> *staticData = &thisSegmentData;
22433 QVector<QPointF> *croppedData = &otherSegmentData;
22440 if (staticData->first().x() <
22441 croppedData->first().x())
22442 qSwap(staticData, croppedData);
22443 const int lowBound =
22445 if (lowBound == -1)
return QPolygonF();
22446 croppedData->remove(0, lowBound);
22449 if (croppedData->size() < 2)
22450 return QPolygonF();
22452 if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x()))
22453 slope = (croppedData->at(1).y() - croppedData->at(0).y()) /
22454 (croppedData->at(1).x() - croppedData->at(0).x());
22457 (*croppedData)[0].setY(
22458 croppedData->at(0).y() +
22459 slope * (staticData->first().x() - croppedData->at(0).x()));
22460 (*croppedData)[0].setX(staticData->first().x());
22463 if (staticData->last().x() >
22464 croppedData->last().x())
22465 qSwap(staticData, croppedData);
22466 int highBound =
findIndexAboveX(croppedData, staticData->last().x());
22467 if (highBound == -1)
return QPolygonF();
22468 croppedData->remove(highBound + 1,
22469 croppedData->size() - (highBound + 1));
22472 if (croppedData->size() < 2)
22473 return QPolygonF();
22474 const int li = croppedData->size() - 1;
22475 if (!qFuzzyCompare(croppedData->at(li).x(),
22476 croppedData->at(li - 1).x()))
22477 slope = (croppedData->at(li).y() - croppedData->at(li - 1).y()) /
22478 (croppedData->at(li).x() - croppedData->at(li - 1).x());
22481 (*croppedData)[li].setY(
22482 croppedData->at(li - 1).y() +
22483 slope * (staticData->last().x() - croppedData->at(li - 1).x()));
22484 (*croppedData)[li].setX(staticData->last().x());
22489 if (staticData->first().y() <
22490 croppedData->first().y())
22491 qSwap(staticData, croppedData);
22492 int lowBound =
findIndexBelowY(croppedData, staticData->first().y());
22493 if (lowBound == -1)
return QPolygonF();
22494 croppedData->remove(0, lowBound);
22497 if (croppedData->size() < 2)
22498 return QPolygonF();
22500 if (!qFuzzyCompare(croppedData->at(1).y(),
22501 croppedData->at(0).y()))
22503 slope = (croppedData->at(1).x() - croppedData->at(0).x()) /
22504 (croppedData->at(1).y() - croppedData->at(0).y());
22507 (*croppedData)[0].setX(
22508 croppedData->at(0).x() +
22509 slope * (staticData->first().y() - croppedData->at(0).y()));
22510 (*croppedData)[0].setY(staticData->first().y());
22513 if (staticData->last().y() >
22514 croppedData->last().y())
22515 qSwap(staticData, croppedData);
22516 int highBound =
findIndexAboveY(croppedData, staticData->last().y());
22517 if (highBound == -1)
return QPolygonF();
22518 croppedData->remove(highBound + 1,
22519 croppedData->size() - (highBound + 1));
22522 if (croppedData->size() < 2)
22523 return QPolygonF();
22524 int li = croppedData->size() - 1;
22525 if (!qFuzzyCompare(croppedData->at(li).y(),
22526 croppedData->at(li - 1).y()))
22528 slope = (croppedData->at(li).x() - croppedData->at(li - 1).x()) /
22529 (croppedData->at(li).y() - croppedData->at(li - 1).y());
22532 (*croppedData)[li].setX(
22533 croppedData->at(li - 1).x() +
22534 slope * (staticData->last().y() - croppedData->at(li - 1).y()));
22535 (*croppedData)[li].setY(staticData->last().y());
22539 for (
int i = otherSegmentData.size() - 1; i >= 0;
22541 thisSegmentData << otherSegmentData.at(i);
22542 return QPolygonF(thisSegmentData);
22554 for (
int i =
data->size() - 1; i >= 0; --i) {
22555 if (
data->at(i).x() <
x) {
22556 if (i < data->
size() - 1)
22559 return data->size() - 1;
22574 for (
int i = 0; i <
data->size(); ++i) {
22575 if (
data->at(i).x() >
x) {
22594 for (
int i =
data->size() - 1; i >= 0; --i) {
22595 if (
data->at(i).y() <
y) {
22596 if (i < data->
size() - 1)
22599 return data->size() - 1;
22620 const QPointF &pixelPoint,
22628 double minDistSqr = (std::numeric_limits<double>::max)();
22631 double posKeyMin, posKeyMax, dummy;
22638 if (posKeyMin > posKeyMax) qSwap(posKeyMin, posKeyMax);
22646 const double currentDistSqr =
22649 if (currentDistSqr < minDistSqr) {
22650 minDistSqr = currentDistSqr;
22659 QVector<QPointF> lineData;
22667 for (
int i = 0; i < lineData.size() - 1; i += step) {
22668 const double currentDistSqr =
22670 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
22674 return qSqrt(minDistSqr);
22686 for (
int i = 0; i <
data->size(); ++i) {
22687 if (
data->at(i).y() >
y) {
22787 : t(t), key(key), value(value) {}
22904 const QVector<double> &keys,
22905 const QVector<double> &values,
22906 bool alreadySorted) {
22908 addData(t, keys, values, alreadySorted);
22923 const QVector<double> &values) {
22977 const QVector<double> &keys,
22978 const QVector<double> &values,
22979 bool alreadySorted) {
22980 if (t.size() != keys.size() || t.size() != values.size())
22981 qDebug() << Q_FUNC_INFO
22982 <<
"ts, keys and values have different sizes:" << t.size()
22983 << keys.size() << values.size();
22984 const int n = qMin(qMin(t.size(), keys.size()), values.size());
22985 QVector<QCPCurveData> tempData(n);
22986 QVector<QCPCurveData>::iterator it = tempData.begin();
22987 const QVector<QCPCurveData>::iterator itEnd = tempData.end();
22989 while (it != itEnd) {
22992 it->value = values[i];
23014 const QVector<double> &values) {
23015 if (keys.size() != values.size())
23016 qDebug() << Q_FUNC_INFO
23017 <<
"keys and values have different sizes:" << keys.size()
23019 const int n = qMin(keys.size(), values.size());
23025 QVector<QCPCurveData> tempData(n);
23026 QVector<QCPCurveData>::iterator it = tempData.begin();
23027 const QVector<QCPCurveData>::iterator itEnd = tempData.end();
23029 while (it != itEnd) {
23030 it->t = tStart + i;
23032 it->value = values[i];
23078 bool onlySelectable,
23079 QVariant *details)
const {
23085 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
23090 int pointIndex = closestDataPoint -
mDataContainer->constBegin();
23108 const QCPRange &inKeyRange)
const {
23109 return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange);
23117 QVector<QPointF> lines, scatters;
23120 QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
23122 allSegments << unselectedSegments << selectedSegments;
23123 for (
int i = 0; i < allSegments.size(); ++i) {
23124 bool isSelectedSegment = i >= unselectedSegments.size();
23127 QPen finalCurvePen =
23135 ? allSegments.at(i)
23142 getCurveLines(&lines, lineDataRange, finalCurvePen.widthF());
23145 #ifdef QCUSTOMPLOT_CHECK_DATA
23151 qDebug() << Q_FUNC_INFO <<
"Data point at" << it->key
23153 <<
"Plottable name:" <<
name();
23162 painter->setBrush(
mBrush);
23163 painter->
setPen(Qt::NoPen);
23164 if (painter->brush().style() != Qt::NoBrush &&
23165 painter->brush().color().alpha() != 0)
23166 painter->drawPolygon(QPolygonF(lines));
23170 painter->
setPen(finalCurvePen);
23171 painter->setBrush(Qt::NoBrush);
23178 finalScatterStyle =
23180 if (!finalScatterStyle.
isNone()) {
23195 if (
mBrush.style() != Qt::NoBrush) {
23197 painter->fillRect(QRectF(rect.left(), rect.top() + rect.height() / 2.0,
23198 rect.width(), rect.height() / 3.0),
23206 rect.left(), rect.top() + rect.height() / 2.0, rect.right() + 5,
23207 rect.top() + rect.height() /
23220 rect.size().toSize(), Qt::KeepAspectRatio,
23221 Qt::SmoothTransformation));
23223 scaledStyle.
drawShape(painter, QRectF(rect).center());
23238 const QVector<QPointF> &lines)
const {
23239 if (painter->pen().style() != Qt::NoPen &&
23240 painter->pen().color().alpha() != 0) {
23255 const QVector<QPointF> &
points,
23260 for (
int i = 0; i <
points.size(); ++i)
23261 if (!qIsNaN(
points.at(i).x()) && !qIsNaN(
points.at(i).y()))
23298 double penWidth)
const {
23299 if (!lines)
return;
23304 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
23309 const double strokeMargin = qMax(
23310 qreal(1.0), qreal(penWidth * 0.75));
23326 mDataContainer->limitIteratorsToDataRange(itBegin, itEnd, dataRange);
23327 if (itBegin == itEnd)
return;
23330 int prevRegion =
getRegion(prevIt->key, prevIt->value, keyMin, valueMax,
23337 while (it != itEnd) {
23338 const int currentRegion =
getRegion(it->key, it->value, keyMin,
23339 valueMax, keyMax, valueMin);
23340 if (currentRegion !=
23344 if (currentRegion !=
23347 QPointF crossA, crossB;
23352 currentRegion, it->key, it->value, prevIt->key,
23353 prevIt->value, keyMin, valueMax, keyMax, valueMin));
23358 prevRegion, currentRegion, prevIt->key,
23359 prevIt->value, it->key, it->value, keyMin, valueMax,
23361 }
else if (
mayTraverse(prevRegion, currentRegion) &&
23363 it->value, keyMin, valueMax, keyMax,
23364 valueMin, crossA, crossB)) {
23368 QVector<QPointF> beforeTraverseCornerPoints,
23369 afterTraverseCornerPoints;
23371 valueMax, keyMax, valueMin,
23372 beforeTraverseCornerPoints,
23373 afterTraverseCornerPoints);
23374 if (it != itBegin) {
23375 *lines << beforeTraverseCornerPoints;
23376 lines->append(crossA);
23377 lines->append(crossB);
23378 *lines << afterTraverseCornerPoints;
23380 lines->append(crossB);
23381 *lines << afterTraverseCornerPoints;
23382 trailingPoints << beforeTraverseCornerPoints << crossA;
23389 prevRegion, currentRegion, prevIt->key,
23390 prevIt->value, it->key, it->value, keyMin, valueMax,
23400 prevRegion, prevIt->key, prevIt->value, it->key,
23401 it->value, keyMin, valueMax, keyMax, valueMin);
23404 prevRegion, prevIt->key, prevIt->value, it->key,
23405 it->value, keyMin, valueMax, keyMax, valueMin));
23410 if (currentRegion == 5)
23420 prevRegion = currentRegion;
23423 *lines << trailingPoints;
23449 double scatterWidth)
const {
23450 if (!scatters)
return;
23455 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
23461 mDataContainer->limitIteratorsToDataRange(begin, end, dataRange);
23462 if (begin == end)
return;
23485 while (doScatterSkip && it != end &&
23486 itIndex % scatterModulo !=
23493 while (it != end) {
23494 if (!qIsNaN(it->value) && keyRange.
contains(it->key) &&
23500 if (!doScatterSkip)
23503 itIndex += scatterModulo;
23504 if (itIndex < endIndex)
23505 it += scatterModulo;
23508 itIndex = endIndex;
23513 while (it != end) {
23514 if (!qIsNaN(it->value) && keyRange.
contains(it->key) &&
23520 if (!doScatterSkip)
23523 itIndex += scatterModulo;
23524 if (itIndex < endIndex)
23525 it += scatterModulo;
23528 itIndex = endIndex;
23561 double valueMin)
const {
23564 if (value > valueMax)
23566 else if (value < valueMin)
23570 }
else if (key > keyMax)
23572 if (value > valueMax)
23574 else if (value < valueMin)
23580 if (value > valueMax)
23582 else if (value < valueMin)
23614 double valueMin)
const {
23621 const double keyMinPx =
mKeyAxis->coordToPixel(keyMin);
23622 const double keyMaxPx =
mKeyAxis->coordToPixel(keyMax);
23623 const double valueMinPx =
mValueAxis->coordToPixel(valueMin);
23624 const double valueMaxPx =
mValueAxis->coordToPixel(valueMax);
23625 const double otherValuePx =
mValueAxis->coordToPixel(otherValue);
23626 const double valuePx =
mValueAxis->coordToPixel(value);
23627 const double otherKeyPx =
mKeyAxis->coordToPixel(otherKey);
23628 const double keyPx =
mKeyAxis->coordToPixel(key);
23629 double intersectKeyPx = keyMinPx;
23630 double intersectValuePx = valueMinPx;
23631 switch (otherRegion) {
23634 intersectValuePx = valueMaxPx;
23635 intersectKeyPx = otherKeyPx +
23636 (keyPx - otherKeyPx) / (valuePx - otherValuePx) *
23637 (intersectValuePx - otherValuePx);
23638 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) ||
23646 intersectKeyPx = keyMinPx;
23648 otherValuePx + (valuePx - otherValuePx) /
23649 (keyPx - otherKeyPx) *
23650 (intersectKeyPx - otherKeyPx);
23656 intersectKeyPx = keyMinPx;
23657 intersectValuePx = otherValuePx +
23658 (valuePx - otherValuePx) / (keyPx - otherKeyPx) *
23659 (intersectKeyPx - otherKeyPx);
23664 intersectValuePx = valueMinPx;
23665 intersectKeyPx = otherKeyPx +
23666 (keyPx - otherKeyPx) / (valuePx - otherValuePx) *
23667 (intersectValuePx - otherValuePx);
23668 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) ||
23676 intersectKeyPx = keyMinPx;
23678 otherValuePx + (valuePx - otherValuePx) /
23679 (keyPx - otherKeyPx) *
23680 (intersectKeyPx - otherKeyPx);
23686 intersectValuePx = valueMaxPx;
23687 intersectKeyPx = otherKeyPx +
23688 (keyPx - otherKeyPx) / (valuePx - otherValuePx) *
23689 (intersectValuePx - otherValuePx);
23698 intersectValuePx = valueMinPx;
23699 intersectKeyPx = otherKeyPx +
23700 (keyPx - otherKeyPx) / (valuePx - otherValuePx) *
23701 (intersectValuePx - otherValuePx);
23706 intersectValuePx = valueMaxPx;
23707 intersectKeyPx = otherKeyPx +
23708 (keyPx - otherKeyPx) / (valuePx - otherValuePx) *
23709 (intersectValuePx - otherValuePx);
23710 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) ||
23718 intersectKeyPx = keyMaxPx;
23720 otherValuePx + (valuePx - otherValuePx) /
23721 (keyPx - otherKeyPx) *
23722 (intersectKeyPx - otherKeyPx);
23728 intersectKeyPx = keyMaxPx;
23729 intersectValuePx = otherValuePx +
23730 (valuePx - otherValuePx) / (keyPx - otherKeyPx) *
23731 (intersectKeyPx - otherKeyPx);
23736 intersectValuePx = valueMinPx;
23737 intersectKeyPx = otherKeyPx +
23738 (keyPx - otherKeyPx) / (valuePx - otherValuePx) *
23739 (intersectValuePx - otherValuePx);
23740 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) ||
23748 intersectKeyPx = keyMaxPx;
23750 otherValuePx + (valuePx - otherValuePx) /
23751 (keyPx - otherKeyPx) *
23752 (intersectKeyPx - otherKeyPx);
23757 if (
mKeyAxis->orientation() == Qt::Horizontal)
23758 return QPointF(intersectKeyPx, intersectValuePx);
23760 return QPointF(intersectValuePx, intersectKeyPx);
23793 double valueMin)
const {
23794 QVector<QPointF>
result;
23795 switch (prevRegion) {
23797 switch (currentRegion) {
23831 if ((value - prevValue) / (key - prevKey) * (keyMin - key) +
23851 switch (currentRegion) {
23886 switch (currentRegion) {
23920 if ((value - prevValue) / (key - prevKey) * (keyMax - key) +
23940 switch (currentRegion) {
23975 switch (currentRegion) {
23996 switch (currentRegion) {
24031 switch (currentRegion) {
24065 if ((value - prevValue) / (key - prevKey) * (keyMax - key) +
24085 switch (currentRegion) {
24120 switch (currentRegion) {
24154 if ((value - prevValue) / (key - prevKey) * (keyMin - key) +
24191 switch (prevRegion) {
24193 switch (currentRegion) {
24204 switch (currentRegion) {
24213 switch (currentRegion) {
24224 switch (currentRegion) {
24235 switch (currentRegion) {
24244 switch (currentRegion) {
24255 switch (currentRegion) {
24264 switch (currentRegion) {
24304 QPointF &crossB)
const {
24311 QList<QPointF> intersections;
24312 const double valueMinPx =
mValueAxis->coordToPixel(valueMin);
24313 const double valueMaxPx =
mValueAxis->coordToPixel(valueMax);
24314 const double keyMinPx =
mKeyAxis->coordToPixel(keyMin);
24315 const double keyMaxPx =
mKeyAxis->coordToPixel(keyMax);
24316 const double keyPx =
mKeyAxis->coordToPixel(key);
24317 const double valuePx =
mValueAxis->coordToPixel(value);
24318 const double prevKeyPx =
mKeyAxis->coordToPixel(prevKey);
24319 const double prevValuePx =
mValueAxis->coordToPixel(prevValue);
24320 if (qFuzzyIsNull(key - prevKey))
24324 intersections.append(
24325 mKeyAxis->orientation() == Qt::Horizontal
24326 ? QPointF(keyPx, valueMinPx)
24327 : QPointF(valueMinPx,
24330 intersections.append(
mKeyAxis->orientation() == Qt::Horizontal
24331 ? QPointF(keyPx, valueMaxPx)
24332 : QPointF(valueMaxPx, keyPx));
24333 }
else if (qFuzzyIsNull(value - prevValue))
24337 intersections.append(
24338 mKeyAxis->orientation() == Qt::Horizontal
24339 ? QPointF(keyMinPx, valuePx)
24343 intersections.append(
mKeyAxis->orientation() == Qt::Horizontal
24344 ? QPointF(keyMaxPx, valuePx)
24345 : QPointF(valuePx, keyMaxPx));
24349 double keyPerValuePx = (keyPx - prevKeyPx) / (valuePx - prevValuePx);
24351 gamma = prevKeyPx + (valueMaxPx - prevValuePx) * keyPerValuePx;
24352 if (gamma >= qMin(keyMinPx, keyMaxPx) &&
24353 gamma <= qMax(keyMinPx, keyMaxPx))
24355 intersections.append(
mKeyAxis->orientation() == Qt::Horizontal
24356 ? QPointF(gamma, valueMaxPx)
24357 : QPointF(valueMaxPx, gamma));
24359 gamma = prevKeyPx + (valueMinPx - prevValuePx) * keyPerValuePx;
24360 if (gamma >= qMin(keyMinPx, keyMaxPx) &&
24361 gamma <= qMax(keyMinPx, keyMaxPx))
24363 intersections.append(
mKeyAxis->orientation() == Qt::Horizontal
24364 ? QPointF(gamma, valueMinPx)
24365 : QPointF(valueMinPx, gamma));
24366 const double valuePerKeyPx = 1.0 / keyPerValuePx;
24368 gamma = prevValuePx + (keyMinPx - prevKeyPx) * valuePerKeyPx;
24369 if (gamma >= qMin(valueMinPx, valueMaxPx) &&
24370 gamma <= qMax(valueMinPx, valueMaxPx))
24372 intersections.append(
mKeyAxis->orientation() == Qt::Horizontal
24373 ? QPointF(keyMinPx, gamma)
24374 : QPointF(gamma, keyMinPx));
24376 gamma = prevValuePx + (keyMaxPx - prevKeyPx) * valuePerKeyPx;
24377 if (gamma >= qMin(valueMinPx, valueMaxPx) &&
24378 gamma <= qMax(valueMinPx, valueMaxPx))
24380 intersections.append(
mKeyAxis->orientation() == Qt::Horizontal
24381 ? QPointF(keyMaxPx, gamma)
24382 : QPointF(gamma, keyMaxPx));
24386 if (intersections.size() > 2) {
24390 double distSqrMax = 0;
24392 for (
int i = 0; i < intersections.size() - 1; ++i) {
24393 for (
int k = i + 1; k < intersections.size(); ++k) {
24394 QPointF distPoint = intersections.at(i) - intersections.at(k);
24395 double distSqr = distPoint.x() * distPoint.x() + distPoint.y() +
24397 if (distSqr > distSqrMax) {
24398 pv1 = intersections.at(i);
24399 pv2 = intersections.at(k);
24400 distSqrMax = distSqr;
24404 intersections = QList<QPointF>() << pv1 << pv2;
24405 }
else if (intersections.size() != 2) {
24413 double xDelta = keyPx - prevKeyPx;
24414 double yDelta = valuePx - prevValuePx;
24415 if (
mKeyAxis->orientation() != Qt::Horizontal) qSwap(xDelta, yDelta);
24416 if (xDelta * (intersections.at(1).x() - intersections.at(0).x()) +
24417 yDelta * (intersections.at(1).y() - intersections.at(0).y()) <
24419 intersections.move(0, 1);
24420 crossA = intersections.at(0);
24421 crossB = intersections.at(1);
24460 QVector<QPointF> &beforeTraverse,
24461 QVector<QPointF> &afterTraverse)
const {
24462 switch (prevRegion) {
24464 switch (currentRegion) {
24482 switch (currentRegion) {
24495 switch (currentRegion) {
24513 switch (currentRegion) {
24529 switch (currentRegion) {
24542 switch (currentRegion) {
24560 switch (currentRegion) {
24573 switch (currentRegion) {
24608 const QPointF &pixelPoint,
24623 double minDistSqr = (std::numeric_limits<double>::max)();
24629 const double currentDistSqr =
24632 if (currentDistSqr < minDistSqr) {
24633 minDistSqr = currentDistSqr;
24641 QVector<QPointF> lines;
24647 for (
int i = 0; i < lines.size() - 1; ++i) {
24648 double currentDistSqr =
24652 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
24656 return qSqrt(minDistSqr);
24737 : QObject(parentPlot),
24738 mParentPlot(parentPlot),
24739 mSpacingType(stAbsolute),
24772 if (index >= 0 && index <
mBars.size()) {
24773 return mBars.at(index);
24775 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
24788 bars->setBarsGroup(0);
24799 qDebug() << Q_FUNC_INFO <<
"bars is 0";
24804 bars->setBarsGroup(
this);
24806 qDebug() << Q_FUNC_INFO
24807 <<
"bars plottable is already in this bars group:"
24808 <<
reinterpret_cast<quintptr
>(
bars);
24822 qDebug() << Q_FUNC_INFO <<
"bars is 0";
24839 qDebug() << Q_FUNC_INFO <<
"bars is 0";
24844 bars->setBarsGroup(0);
24846 qDebug() << Q_FUNC_INFO <<
"bars plottable is not in this bars group:"
24847 <<
reinterpret_cast<quintptr
>(
bars);
24878 QList<const QCPBars *> baseBars;
24881 if (!baseBars.contains(b)) baseBars.append(b);
24890 int index = baseBars.indexOf(thisBase);
24892 if (baseBars.size() % 2 == 1 &&
24893 index == (baseBars.size() - 1) /
24898 double lowerPixelWidth, upperPixelWidth;
24900 int dir = (index <= (baseBars.size() - 1) / 2)
24904 if (baseBars.size() % 2 == 0)
24906 startIndex = baseBars.size() / 2 + (dir < 0 ? -1 : 0);
24911 startIndex = (baseBars.size() - 1) / 2 + dir;
24912 baseBars.at((baseBars.size() - 1) / 2)
24913 ->getPixelWidth(keyCoord, lowerPixelWidth,
24915 result += qAbs(upperPixelWidth - lowerPixelWidth) *
24921 for (
int i = startIndex; i != index;
24925 baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth,
24927 result += qAbs(upperPixelWidth - lowerPixelWidth);
24931 baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth,
24933 result += qAbs(upperPixelWidth - lowerPixelWidth) * 0.5;
24959 if (
bars->keyAxis()->orientation() == Qt::Horizontal)
24960 return bars->keyAxis()->axisRect()->width() *
mSpacing;
24962 return bars->keyAxis()->axisRect()->height() *
mSpacing;
24965 double keyPixel =
bars->keyAxis()->coordToPixel(keyCoord);
24966 return qAbs(
bars->keyAxis()->coordToPixel(keyCoord +
mSpacing) -
25140 mWidthType(wtPlotCoords),
25146 mPen.setStyle(Qt::SolidLine);
25147 mBrush.setColor(QColor(40, 50, 255, 30));
25148 mBrush.setStyle(Qt::SolidPattern);
25193 const QVector<double> &values,
25194 bool alreadySorted) {
25196 addData(keys, values, alreadySorted);
25269 const QVector<double> &values,
25270 bool alreadySorted) {
25271 if (keys.size() != values.size())
25272 qDebug() << Q_FUNC_INFO
25273 <<
"keys and values have different sizes:" << keys.size()
25275 const int n = qMin(keys.size(), values.size());
25276 QVector<QCPBarsData> tempData(n);
25277 QVector<QCPBarsData>::iterator it = tempData.begin();
25278 const QVector<QCPBarsData>::iterator itEnd = tempData.end();
25280 while (it != itEnd) {
25282 it->value = values[i];
25317 if (bars ==
this)
return;
25320 qDebug() << Q_FUNC_INFO
25321 <<
"passed QCPBars* doesn't have same key and value axis as "
25351 if (bars ==
this)
return;
25354 qDebug() << Q_FUNC_INFO
25355 <<
"passed QCPBars* doesn't have same key and value axis as "
25373 bool onlySelectable)
const {
25384 it != visibleEnd; ++it) {
25385 if (rect.intersects(
getBarRect(it->key, it->value)))
25404 bool onlySelectable,
25405 QVariant *details)
const {
25412 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
25417 it != visibleEnd; ++it) {
25418 if (
getBarRect(it->key, it->value).contains(pos)) {
25451 double lowerPixelWidth, upperPixelWidth, keyPixel;
25454 keyPixel =
mKeyAxis.data()->coordToPixel(range.
lower) + lowerPixelWidth;
25457 const double lowerCorrected =
mKeyAxis.data()->pixelToCoord(keyPixel);
25458 if (!qIsNaN(lowerCorrected) && qIsFinite(lowerCorrected) &&
25459 range.
lower > lowerCorrected)
25460 range.
lower = lowerCorrected;
25463 keyPixel =
mKeyAxis.data()->coordToPixel(range.
upper) + upperPixelWidth;
25466 const double upperCorrected =
mKeyAxis.data()->pixelToCoord(keyPixel);
25467 if (!qIsNaN(upperCorrected) && qIsFinite(upperCorrected) &&
25468 range.
upper < upperCorrected)
25469 range.
upper = upperCorrected;
25477 const QCPRange &inKeyRange)
const {
25483 bool haveLower =
true;
25485 bool haveUpper =
true;
25494 const double current =
25496 if (qIsNaN(current))
continue;
25500 if (current < range.
lower || !haveLower) {
25501 range.
lower = current;
25504 if (current > range.
upper || !haveUpper) {
25505 range.
upper = current;
25518 if (index >= 0 && index < mDataContainer->
size()) {
25522 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
25530 const double keyPixel =
25534 return QPointF(keyPixel, valuePixel);
25536 return QPointF(valuePixel, keyPixel);
25538 qDebug() << Q_FUNC_INFO <<
"Index out of bounds" << index;
25546 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
25555 QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
25557 allSegments << unselectedSegments << selectedSegments;
25558 for (
int i = 0; i < allSegments.size(); ++i) {
25559 bool isSelectedSegment = i >= unselectedSegments.size();
25563 allSegments.at(i));
25564 if (begin == end)
continue;
25568 #ifdef QCUSTOMPLOT_CHECK_DATA
25570 qDebug() << Q_FUNC_INFO <<
"Data point at" << it->key
25571 <<
"of drawn range invalid."
25572 <<
"Plottable name:" <<
name();
25579 painter->setBrush(
mBrush);
25583 painter->drawPolygon(
getBarRect(it->key, it->value));
25597 painter->setBrush(
mBrush);
25599 QRectF r = QRectF(0, 0, rect.width() * 0.67, rect.height() * 0.67);
25600 r.moveCenter(rect.center());
25601 painter->drawRect(r);
25624 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
25638 double lowerPixelBound =
25640 double upperPixelBound =
25642 bool isVisible =
false;
25648 const QRectF barRect =
getBarRect(it->key, it->value);
25649 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
25650 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
25651 barRect.right() >= lowerPixelBound) ||
25652 (
mKeyAxis.data()->rangeReversed() &&
25653 barRect.left() <= lowerPixelBound));
25655 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
25656 barRect.top() <= lowerPixelBound) ||
25657 (
mKeyAxis.data()->rangeReversed() &&
25658 barRect.bottom() >= lowerPixelBound));
25668 const QRectF barRect =
getBarRect(it->key, it->value);
25669 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
25670 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
25671 barRect.left() <= upperPixelBound) ||
25672 (
mKeyAxis.data()->rangeReversed() &&
25673 barRect.right() >= upperPixelBound));
25675 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
25676 barRect.bottom() >= upperPixelBound) ||
25677 (
mKeyAxis.data()->rangeReversed() &&
25678 barRect.top() <= upperPixelBound));
25698 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
25702 double lowerPixelWidth, upperPixelWidth;
25709 double bottomOffset = (
mBarBelow &&
mPen != Qt::NoPen ? 1 : 0) *
25710 (
mPen.isCosmetic() ? 1 :
mPen.widthF());
25713 if (qAbs(valuePixel - basePixel) <= qAbs(bottomOffset))
25714 bottomOffset = valuePixel - basePixel;
25716 return QRectF(QPointF(keyPixel + lowerPixelWidth, valuePixel),
25717 QPointF(keyPixel + upperPixelWidth,
25718 basePixel + bottomOffset))
25721 return QRectF(QPointF(basePixel + bottomOffset,
25722 keyPixel + lowerPixelWidth),
25723 QPointF(valuePixel, keyPixel + upperPixelWidth))
25750 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
25752 0.5 *
mKeyAxis.data()->pixelOrientation();
25755 0.5 *
mKeyAxis.data()->pixelOrientation();
25758 qDebug() << Q_FUNC_INFO <<
"No key axis or axis rect defined";
25763 double keyPixel =
mKeyAxis.data()->coordToPixel(key);
25772 qDebug() << Q_FUNC_INFO <<
"No key axis defined";
25798 (
sizeof(key) == 4 ? 1
e-6
25801 if (key == 0) epsilon = (
sizeof(key) == 4 ? 1
e-6 : 1
e-14);
25803 mBarBelow.data()->mDataContainer->findBegin(key - epsilon);
25805 mBarBelow.data()->mDataContainer->findEnd(key + epsilon);
25806 while (it != itEnd) {
25807 if (it->key > key - epsilon && it->key < key + epsilon) {
25808 if ((positive && it->value > max) ||
25809 (!positive && it->value < max))
25815 return max +
mBarBelow.data()->getStackedBaseValue(key, positive);
25830 if (!lower && !upper)
return;
25836 upper->
mBarBelow.data()->mBarAbove.data() == upper)
25837 upper->
mBarBelow.data()->mBarAbove = 0;
25843 lower->
mBarAbove.data()->mBarBelow.data() == lower)
25844 lower->
mBarAbove.data()->mBarBelow = 0;
25850 lower->
mBarAbove.data()->mBarBelow.data() == lower)
25851 lower->
mBarAbove.data()->mBarBelow = 0;
25854 upper->
mBarBelow.data()->mBarAbove.data() == upper)
25855 upper->
mBarBelow.data()->mBarAbove = 0;
25982 double lowerQuartile,
25984 double upperQuartile,
25986 const QVector<double> &outliers)
25989 lowerQuartile(lowerQuartile),
25991 upperQuartile(upperQuartile),
25993 outliers(outliers) {}
26080 mWhiskerWidth(0.2),
26081 mWhiskerPen(Qt::
black, 0, Qt::DashLine, Qt::FlatCap),
26082 mWhiskerBarPen(Qt::
black),
26083 mWhiskerAntialiased(false),
26084 mMedianPen(Qt::
black, 3, Qt::SolidLine, Qt::FlatCap),
26108 QSharedPointer<QCPStatisticalBoxDataContainer>
data) {
26125 const QVector<double> &minimum,
26126 const QVector<double> &lowerQuartile,
26127 const QVector<double> &median,
26128 const QVector<double> &upperQuartile,
26129 const QVector<double> &maximum,
26130 bool alreadySorted) {
26224 const QVector<double> &minimum,
26225 const QVector<double> &lowerQuartile,
26226 const QVector<double> &median,
26227 const QVector<double> &upperQuartile,
26228 const QVector<double> &maximum,
26229 bool alreadySorted) {
26230 if (keys.size() !=
minimum.size() ||
26235 qDebug() << Q_FUNC_INFO
26236 <<
"keys, minimum, lowerQuartile, median, upperQuartile, "
26237 "maximum have different sizes:"
26240 const int n = qMin(keys.size(),
26245 QVector<QCPStatisticalBoxData> tempData(n);
26246 QVector<QCPStatisticalBoxData>::iterator it = tempData.begin();
26247 const QVector<QCPStatisticalBoxData>::iterator itEnd = tempData.end();
26249 while (it != itEnd) {
26274 double lowerQuartile,
26276 double upperQuartile,
26278 const QVector<double> &outliers) {
26288 bool onlySelectable)
const {
26299 it != visibleEnd; ++it) {
26319 bool onlySelectable,
26320 QVariant *details)
const {
26327 if (
mKeyAxis->axisRect()->rect().contains(pos.toPoint())) {
26333 double minDistSqr = (std::numeric_limits<double>::max)();
26335 it != visibleEnd; ++it) {
26338 double currentDistSqr =
26341 if (currentDistSqr < minDistSqr) {
26342 minDistSqr = currentDistSqr;
26343 closestDataPoint = it;
26347 const QVector<QLineF> whiskerBackbones(
26349 for (
int i = 0; i < whiskerBackbones.size(); ++i) {
26350 double currentDistSqr =
26352 whiskerBackbones.at(i));
26353 if (currentDistSqr < minDistSqr) {
26354 minDistSqr = currentDistSqr;
26355 closestDataPoint = it;
26361 int pointIndex = closestDataPoint -
mDataContainer->constBegin();
26365 return qSqrt(minDistSqr);
26387 const QCPRange &inKeyRange)
const {
26388 return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange);
26397 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
26405 QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
26407 allSegments << unselectedSegments << selectedSegments;
26408 for (
int i = 0; i < allSegments.size(); ++i) {
26409 bool isSelectedSegment = i >= unselectedSegments.size();
26413 allSegments.at(i));
26414 if (begin == end)
continue;
26419 #ifdef QCUSTOMPLOT_CHECK_DATA
26423 qDebug() << Q_FUNC_INFO <<
"Data point at" << it->key
26424 <<
"of drawn range has invalid data."
26425 <<
"Plottable name:" <<
name();
26426 for (
int i = 0; i < it->outliers.size(); ++i)
26428 qDebug() << Q_FUNC_INFO <<
"Data point outlier at"
26429 << it->key <<
"of drawn range invalid."
26430 <<
"Plottable name:" <<
name();
26438 painter->setBrush(
mBrush);
26456 const QRectF &rect)
const {
26460 painter->setBrush(
mBrush);
26461 QRectF r = QRectF(0, 0, rect.width() * 0.67, rect.height() * 0.67);
26462 r.moveCenter(rect.center());
26463 painter->drawRect(r);
26482 painter->drawRect(quartileBox);
26485 painter->setClipRect(quartileBox, Qt::IntersectClip);
26500 for (
int i = 0; i < it->outliers.size(); ++i)
26525 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
26568 QVector<QLineF>
result(2);
26586 QVector<QLineF>
result(2);
26667 mKeyRange(keyRange),
26668 mValueRange(valueRange),
26672 mDataModified(true) {
26692 mDataModified(true) {
26701 if (&other !=
this) {
26729 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 &&
26738 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 &&
26756 if (
mAlpha && keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 &&
26782 #ifdef __EXCEPTIONS
26787 #ifdef __EXCEPTIONS
26795 qDebug() << Q_FUNC_INFO <<
"out of memory for data dimensions "
26905 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 &&
26927 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 &&
26934 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << keyIndex
26956 unsigned char alpha) {
26957 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 &&
26964 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << keyIndex
26985 double minHeight =
mData[0];
26986 double maxHeight =
mData[0];
26988 for (
int i = 0; i < dataCount; ++i) {
26989 if (
mData[i] > maxHeight) maxHeight =
mData[i];
26990 if (
mData[i] < minHeight) minHeight =
mData[i];
27020 for (
int i = 0; i < dataCount; ++i)
mData[i] =
z;
27038 for (
int i = 0; i < dataCount; ++i)
mAlpha[i] =
alpha;
27065 int *valueIndex)
const {
27097 double *value)
const {
27099 *key = keyIndex / (double)(
mKeySize - 1) *
27103 *value = valueIndex / (double)(
mValueSize - 1) *
27127 #ifdef __EXCEPTIONS
27132 #ifdef __EXCEPTIONS
27141 qDebug() << Q_FUNC_INFO <<
"out of memory for data dimensions "
27280 mDataScaleType(
QCPAxis::stLinear),
27283 mInterpolate(true),
27284 mTightBoundary(false),
27285 mMapImageInvalidated(true) {}
27299 qDebug() << Q_FUNC_INFO
27300 <<
"The data pointer is already in (and owned by) this "
27302 <<
reinterpret_cast<quintptr
>(
data);
27505 const QSize &thumbSize) {
27521 QPixmap::fromImage(
mMapImage.mirrored(mirrorX, mirrorY))
27522 .scaled(thumbSize, Qt::KeepAspectRatio, transformMode);
27528 bool onlySelectable,
27529 QVariant *details)
const {
27535 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
27536 double posKey, posValue;
27561 foundRange =
false;
27566 foundRange =
false;
27574 const QCPRange &inKeyRange)
const {
27578 foundRange =
false;
27590 foundRange =
false;
27595 foundRange =
false;
27620 const QImage::Format
format = QImage::Format_ARGB32_Premultiplied;
27623 int keyOversamplingFactor =
27627 100.0 / (
double)keySize);
27632 int valueOversamplingFactor =
27636 100.0 / (
double)valueSize);
27645 (
mMapImage.width() != keySize * keyOversamplingFactor ||
27646 mMapImage.height() != valueSize * valueOversamplingFactor))
27647 mMapImage = QImage(QSize(keySize * keyOversamplingFactor,
27648 valueSize * valueOversamplingFactor),
27651 (
mMapImage.width() != valueSize * valueOversamplingFactor ||
27652 mMapImage.height() != keySize * keyOversamplingFactor))
27653 mMapImage = QImage(QSize(valueSize * valueOversamplingFactor,
27654 keySize * keyOversamplingFactor),
27658 qDebug() << Q_FUNC_INFO
27659 <<
"Couldn't create map image (possibly too large for memory)";
27663 QImage *localMapImage =
27667 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
27673 QImage(QSize(keySize, valueSize),
format);
27678 QImage(QSize(valueSize, keySize),
format);
27691 const int lineCount = valueSize;
27692 const int rowCount = keySize;
27693 for (
int line = 0; line < lineCount; ++line) {
27694 QRgb *pixels =
reinterpret_cast<QRgb *
>(localMapImage->scanLine(
27702 rawData + line * rowCount,
27703 rawAlpha + line * rowCount,
mDataRange, pixels,
27708 rawData + line * rowCount,
mDataRange, pixels,
27714 const int lineCount = keySize;
27715 const int rowCount = valueSize;
27716 for (
int line = 0; line < lineCount; ++line) {
27717 QRgb *pixels =
reinterpret_cast<QRgb *
>(localMapImage->scanLine(
27725 rawData + line, rawAlpha + line,
mDataRange, pixels,
27726 rowCount, lineCount,
27730 rawData + line,
mDataRange, pixels, rowCount,
27736 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
27739 keySize * keyOversamplingFactor,
27740 valueSize * valueOversamplingFactor,
27741 Qt::IgnoreAspectRatio, Qt::FastTransformation);
27744 valueSize * valueOversamplingFactor,
27745 keySize * keyOversamplingFactor, Qt::IgnoreAspectRatio,
27746 Qt::FastTransformation);
27765 QRectF mapBufferTarget;
27769 const double mapBufferPixelRatio =
27771 mapBufferTarget = painter->clipRegion().boundingRect();
27772 mapBuffer = QPixmap(
27773 (mapBufferTarget.size() * mapBufferPixelRatio).toSize());
27774 mapBuffer.fill(Qt::transparent);
27776 localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio);
27777 localPainter->translate(-mapBufferTarget.topLeft());
27787 double halfCellWidth = 0;
27788 double halfCellHeight = 0;
27789 if (
keyAxis()->orientation() == Qt::Horizontal) {
27794 halfCellHeight = 0.5 * imageRect.height() /
27799 halfCellHeight = 0.5 * imageRect.height() /
27802 halfCellWidth = 0.5 * imageRect.width() /
27805 imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth,
27807 const bool mirrorX =
27811 const bool mirrorY =
27815 const bool smoothBackup = localPainter->renderHints().testFlag(
27816 QPainter::SmoothPixmapTransform);
27817 localPainter->setRenderHint(QPainter::SmoothPixmapTransform,
mInterpolate);
27818 QRegion clipBackup;
27820 clipBackup = localPainter->clipRegion();
27821 QRectF tightClipRect =
27827 localPainter->setClipRect(tightClipRect, Qt::IntersectClip);
27829 localPainter->drawImage(imageRect,
mMapImage.mirrored(mirrorX, mirrorY));
27831 localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup);
27836 delete localPainter;
27837 painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer);
27843 const QRectF &rect)
const {
27847 QPixmap scaledIcon =
27848 mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio,
27849 Qt::FastTransformation);
27850 QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height());
27851 iconRect.moveCenter(rect.center());
27852 painter->drawPixmap(iconRect.topLeft(), scaledIcon);
27947 : key(0), open(0), high(0), low(0), close(0) {}
27953 double key,
double open,
double high,
double low,
double close)
27954 : key(key), open(open), high(high), low(low), close(close) {}
28042 mChartStyle(csCandlestick),
28044 mWidthType(wtPlotCoords),
28046 mBrushPositive(QBrush(QColor(50, 160, 0))),
28047 mBrushNegative(QBrush(QColor(180, 0, 15))),
28048 mPenPositive(QPen(QColor(40, 150, 0))),
28049 mPenNegative(QPen(QColor(170, 5, 5))) {
28089 const QVector<double> &open,
28090 const QVector<double> &high,
28091 const QVector<double> &low,
28092 const QVector<double> &close,
28093 bool alreadySorted) {
28095 addData(keys, open, high, low, close, alreadySorted);
28205 const QVector<double> &open,
28206 const QVector<double> &high,
28207 const QVector<double> &low,
28208 const QVector<double> &close,
28209 bool alreadySorted) {
28210 if (keys.size() != open.size() || open.size() != high.size() ||
28211 high.size() != low.size() || low.size() != close.size() ||
28212 close.size() != keys.size())
28213 qDebug() << Q_FUNC_INFO
28214 <<
"keys, open, high, low, close have different sizes:"
28215 << keys.size() << open.size() << high.size() << low.size()
28217 const int n = qMin(keys.size(),
28219 qMin(high.size(), qMin(low.size(), close.size()))));
28220 QVector<QCPFinancialData> tempData(n);
28221 QVector<QCPFinancialData>::iterator it = tempData.begin();
28222 const QVector<QCPFinancialData>::iterator itEnd = tempData.end();
28224 while (it != itEnd) {
28226 it->open = open[i];
28227 it->high = high[i];
28229 it->close = close[i];
28249 double key,
double open,
double high,
double low,
double close) {
28257 bool onlySelectable)
const {
28268 it != visibleEnd; ++it) {
28288 bool onlySelectable,
28289 QVariant *details)
const {
28296 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
28315 int pointIndex = closestDataPoint -
mDataContainer->constBegin();
28342 const QCPRange &inKeyRange)
const {
28343 return mDataContainer->valueRange(foundRange, inSignDomain, inKeyRange);
28361 const QVector<double> &time,
28362 const QVector<double> &value,
28363 double timeBinSize,
28364 double timeBinOffset) {
28366 int count = qMin(time.size(), value.size());
28370 value.first(), value.first());
28371 int currentBinIndex =
28372 qFloor((time.first() - timeBinOffset) / timeBinSize + 0.5);
28373 for (
int i = 0; i <
count; ++i) {
28374 int index = qFloor((time.at(i) - timeBinOffset) / timeBinSize + 0.5);
28375 if (currentBinIndex ==
28378 if (value.at(i) < currentBinData.
low)
28379 currentBinData.
low = value.at(i);
28380 if (value.at(i) > currentBinData.
high)
28381 currentBinData.
high = value.at(i);
28385 currentBinData.
close = value.at(i);
28386 currentBinData.
key = timeBinOffset + (index)*timeBinSize;
28387 data.add(currentBinData);
28393 currentBinData.
close = value.at(i - 1);
28394 currentBinData.
key = timeBinOffset + (index - 1) * timeBinSize;
28395 data.add(currentBinData);
28397 currentBinIndex = index;
28398 currentBinData.
open = value.at(i);
28399 currentBinData.
high = value.at(i);
28400 currentBinData.
low = value.at(i);
28414 QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
28416 allSegments << unselectedSegments << selectedSegments;
28417 for (
int i = 0; i < allSegments.size(); ++i) {
28418 bool isSelectedSegment = i >= unselectedSegments.size();
28422 allSegments.at(i));
28423 if (begin == end)
continue;
28444 const QRectF &rect)
const {
28452 painter->setClipRegion(QRegion(QPolygon()
28453 << rect.bottomLeft().toPoint()
28454 << rect.topRight().toPoint()
28455 << rect.topLeft().toPoint()));
28456 painter->
drawLine(QLineF(0, rect.height() * 0.5, rect.width(),
28457 rect.height() * 0.5)
28458 .translated(rect.topLeft()));
28459 painter->
drawLine(QLineF(rect.width() * 0.2, rect.height() * 0.3,
28460 rect.width() * 0.2, rect.height() * 0.5)
28461 .translated(rect.topLeft()));
28462 painter->
drawLine(QLineF(rect.width() * 0.8, rect.height() * 0.5,
28463 rect.width() * 0.8, rect.height() * 0.7)
28464 .translated(rect.topLeft()));
28468 painter->setClipRegion(QRegion(QPolygon()
28469 << rect.bottomLeft().toPoint()
28470 << rect.topRight().toPoint()
28471 << rect.bottomRight().toPoint()));
28472 painter->
drawLine(QLineF(0, rect.height() * 0.5, rect.width(),
28473 rect.height() * 0.5)
28474 .translated(rect.topLeft()));
28475 painter->
drawLine(QLineF(rect.width() * 0.2, rect.height() * 0.3,
28476 rect.width() * 0.2, rect.height() * 0.5)
28477 .translated(rect.topLeft()));
28478 painter->
drawLine(QLineF(rect.width() * 0.8, rect.height() * 0.5,
28479 rect.width() * 0.8, rect.height() * 0.7)
28480 .translated(rect.topLeft()));
28482 painter->setBrush(
mBrush);
28484 painter->
drawLine(QLineF(0, rect.height() * 0.5, rect.width(),
28485 rect.height() * 0.5)
28486 .translated(rect.topLeft()));
28487 painter->
drawLine(QLineF(rect.width() * 0.2, rect.height() * 0.3,
28488 rect.width() * 0.2, rect.height() * 0.5)
28489 .translated(rect.topLeft()));
28490 painter->
drawLine(QLineF(rect.width() * 0.8, rect.height() * 0.5,
28491 rect.width() * 0.8, rect.height() * 0.7)
28492 .translated(rect.topLeft()));
28499 painter->setClipRegion(QRegion(QPolygon()
28500 << rect.bottomLeft().toPoint()
28501 << rect.topRight().toPoint()
28502 << rect.topLeft().toPoint()));
28503 painter->
drawLine(QLineF(0, rect.height() * 0.5,
28504 rect.width() * 0.25, rect.height() * 0.5)
28505 .translated(rect.topLeft()));
28506 painter->
drawLine(QLineF(rect.width() * 0.75, rect.height() * 0.5,
28507 rect.width(), rect.height() * 0.5)
28508 .translated(rect.topLeft()));
28509 painter->drawRect(QRectF(rect.width() * 0.25, rect.height() * 0.25,
28510 rect.width() * 0.5, rect.height() * 0.5)
28511 .translated(rect.topLeft()));
28515 painter->setClipRegion(QRegion(QPolygon()
28516 << rect.bottomLeft().toPoint()
28517 << rect.topRight().toPoint()
28518 << rect.bottomRight().toPoint()));
28519 painter->
drawLine(QLineF(0, rect.height() * 0.5,
28520 rect.width() * 0.25, rect.height() * 0.5)
28521 .translated(rect.topLeft()));
28522 painter->
drawLine(QLineF(rect.width() * 0.75, rect.height() * 0.5,
28523 rect.width(), rect.height() * 0.5)
28524 .translated(rect.topLeft()));
28525 painter->drawRect(QRectF(rect.width() * 0.25, rect.height() * 0.25,
28526 rect.width() * 0.5, rect.height() * 0.5)
28527 .translated(rect.topLeft()));
28529 painter->setBrush(
mBrush);
28531 painter->
drawLine(QLineF(0, rect.height() * 0.5,
28532 rect.width() * 0.25, rect.height() * 0.5)
28533 .translated(rect.topLeft()));
28534 painter->
drawLine(QLineF(rect.width() * 0.75, rect.height() * 0.5,
28535 rect.width(), rect.height() * 0.5)
28536 .translated(rect.topLeft()));
28537 painter->drawRect(QRectF(rect.width() * 0.25, rect.height() * 0.25,
28538 rect.width() * 0.5, rect.height() * 0.5)
28539 .translated(rect.topLeft()));
28560 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
28583 it->key, keyPixel);
28585 painter->
drawLine(QPointF(keyPixel - pixelWidth, openPixel),
28586 QPointF(keyPixel, openPixel));
28588 painter->
drawLine(QPointF(keyPixel, closePixel),
28589 QPointF(keyPixel + pixelWidth, closePixel));
28610 it->key, keyPixel);
28612 painter->
drawLine(QPointF(openPixel, keyPixel - pixelWidth),
28613 QPointF(openPixel, keyPixel));
28615 painter->
drawLine(QPointF(closePixel, keyPixel),
28616 QPointF(closePixel, keyPixel + pixelWidth));
28637 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
28654 painter->setBrush(
mBrush);
28663 qMax(it->open, it->close))));
28668 qMin(it->open, it->close))));
28672 QRectF(QPointF(keyPixel - pixelWidth, closePixel),
28673 QPointF(keyPixel + pixelWidth, openPixel)));
28689 painter->setBrush(
mBrush);
28707 QRectF(QPointF(closePixel, keyPixel - pixelWidth),
28708 QPointF(openPixel, keyPixel + pixelWidth)));
28737 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
28739 0.5 *
mKeyAxis.data()->pixelOrientation();
28742 0.5 *
mKeyAxis.data()->pixelOrientation();
28744 qDebug() << Q_FUNC_INFO <<
"No key axis or axis rect defined";
28752 qDebug() << Q_FUNC_INFO <<
"No key axis defined";
28770 const QPointF &pos,
28778 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
28782 double minDistSqr = (std::numeric_limits<double>::max)();
28791 if (currentDistSqr < minDistSqr) {
28792 minDistSqr = currentDistSqr;
28793 closestDataPoint = it;
28805 if (currentDistSqr < minDistSqr) {
28806 minDistSqr = currentDistSqr;
28807 closestDataPoint = it;
28811 return qSqrt(minDistSqr);
28825 const QPointF &pos,
28833 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
28837 double minDistSqr = (std::numeric_limits<double>::max)();
28841 double currentDistSqr;
28844 it->key +
mWidth * 0.5);
28845 QCPRange boxValueRange(it->close, it->open);
28846 double posKey, posValue;
28848 if (boxKeyRange.
contains(posKey) &&
28860 it->open, it->close))));
28864 it->open, it->close))));
28865 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
28867 if (currentDistSqr < minDistSqr) {
28868 minDistSqr = currentDistSqr;
28869 closestDataPoint = it;
28876 double currentDistSqr;
28879 it->key +
mWidth * 0.5);
28880 QCPRange boxValueRange(it->close, it->open);
28881 double posKey, posValue;
28883 if (boxKeyRange.
contains(posKey) &&
28895 qMax(it->open, it->close)),
28900 qMin(it->open, it->close)),
28902 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
28904 if (currentDistSqr < minDistSqr) {
28905 minDistSqr = currentDistSqr;
28906 closestDataPoint = it;
28910 return qSqrt(minDistSqr);
28934 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
28960 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
28967 double keyWidthPixels =
28970 return QRectF(keyPixel - keyWidthPixels, highPixel, keyWidthPixels * 2,
28971 lowPixel - highPixel)
28974 return QRectF(highPixel, keyPixel - keyWidthPixels,
28975 lowPixel - highPixel, keyWidthPixels * 2)
29012 : errorMinus(error), errorPlus(error) {}
29019 : errorMinus(errorMinus), errorPlus(errorPlus) {}
29090 mErrorType(etValueError),
29149 const QVector<double> &errorPlus) {
29151 addData(errorMinus, errorPlus);
29171 if (plottable && qobject_cast<QCPErrorBars *>(plottable)) {
29173 qDebug() << Q_FUNC_INFO
29174 <<
"can't set another QCPErrorBars instance as data plottable";
29179 qDebug() << Q_FUNC_INFO
29180 <<
"passed plottable doesn't implement 1d interface, can't "
29181 "associate with QCPErrorBars";
29233 const QVector<double> &errorPlus) {
29234 if (errorMinus.size() != errorPlus.size())
29235 qDebug() << Q_FUNC_INFO
29236 <<
"minus and plus error vectors have different sizes:"
29237 << errorMinus.size() << errorPlus.size();
29238 const int n = qMin(errorMinus.size(), errorPlus.size());
29240 for (
int i = 0; i < n; ++i)
29281 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29290 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29299 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29306 const double value =
29308 if (index >= 0 && index < mDataContainer->
size() &&
29315 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29325 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29334 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29343 bool onlySelectable)
const {
29351 QCPErrorBarsDataContainer::const_iterator visibleBegin, visibleEnd;
29355 QVector<QLineF> backbones, whiskers;
29356 for (QCPErrorBarsDataContainer::const_iterator it = visibleBegin;
29357 it != visibleEnd; ++it) {
29361 for (
int i = 0; i < backbones.size(); ++i) {
29380 sortKey, expandedRange);
29385 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29399 qDebug() << Q_FUNC_INFO <<
"no data plottable set";
29412 bool onlySelectable,
29413 QVariant *details)
const {
29421 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
29422 QCPErrorBarsDataContainer::const_iterator closestDataPoint =
29426 int pointIndex = closestDataPoint -
mDataContainer->constBegin();
29439 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
29448 bool checkPointVisibility =
29452 #ifdef QCUSTOMPLOT_CHECK_DATA
29453 QCPErrorBarsDataContainer::const_iterator it;
29457 qDebug() << Q_FUNC_INFO <<
"Data point at index"
29459 <<
"Plottable name:" <<
name();
29464 painter->setBrush(Qt::NoBrush);
29466 QList<QCPDataRange> selectedSegments, unselectedSegments, allSegments;
29468 allSegments << unselectedSegments << selectedSegments;
29469 QVector<QLineF> backbones, whiskers;
29470 for (
int i = 0; i < allSegments.size(); ++i) {
29471 QCPErrorBarsDataContainer::const_iterator begin, end;
29473 if (begin == end)
continue;
29475 bool isSelectedSegment = i >= unselectedSegments.size();
29480 if (painter->pen().capStyle() == Qt::SquareCap) {
29481 QPen capFixPen(painter->pen());
29482 capFixPen.setCapStyle(Qt::FlatCap);
29483 painter->
setPen(capFixPen);
29487 for (QCPErrorBarsDataContainer::const_iterator it = begin; it != end;
29489 if (!checkPointVisibility ||
29493 painter->drawLines(backbones);
29494 painter->drawLines(whiskers);
29505 const QRectF &rect)
const {
29509 mValueAxis->orientation() == Qt::Vertical) {
29510 painter->
drawLine(QLineF(rect.center().x(), rect.top() + 2,
29511 rect.center().x(), rect.bottom() - 1));
29512 painter->
drawLine(QLineF(rect.center().x() - 4, rect.top() + 2,
29513 rect.center().x() + 4, rect.top() + 2));
29514 painter->
drawLine(QLineF(rect.center().x() - 4, rect.bottom() - 1,
29515 rect.center().x() + 4, rect.bottom() - 1));
29517 painter->
drawLine(QLineF(rect.left() + 2, rect.center().y(),
29518 rect.right() - 2, rect.center().y()));
29519 painter->
drawLine(QLineF(rect.left() + 2, rect.center().y() - 4,
29520 rect.left() + 2, rect.center().y() + 4));
29521 painter->
drawLine(QLineF(rect.right() - 2, rect.center().y() - 4,
29522 rect.right() - 2, rect.center().y() + 4));
29530 foundRange =
false;
29535 bool haveLower =
false;
29536 bool haveUpper =
false;
29537 QCPErrorBarsDataContainer::const_iterator it;
29543 const double current =
mDataPlottable->interface1D()->dataMainKey(
29545 if (qIsNaN(current))
continue;
29549 if (current < range.
lower || !haveLower) {
29550 range.
lower = current;
29553 if (current > range.
upper || !haveUpper) {
29554 range.
upper = current;
29560 const double dataKey =
mDataPlottable->interface1D()->dataMainKey(
29562 if (qIsNaN(dataKey))
continue;
29565 dataKey + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus);
29569 if (current > range.
upper || !haveUpper) {
29570 range.
upper = current;
29575 current = dataKey - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus);
29579 if (current < range.
lower || !haveLower) {
29580 range.
lower = current;
29587 if (haveUpper && !haveLower) {
29590 }
else if (haveLower && !haveUpper) {
29595 foundRange = haveLower && haveUpper;
29602 const QCPRange &inKeyRange)
const {
29604 foundRange =
false;
29609 const bool restrictKeyRange = inKeyRange !=
QCPRange();
29610 bool haveLower =
false;
29611 bool haveUpper =
false;
29612 QCPErrorBarsDataContainer::const_iterator itBegin =
29614 QCPErrorBarsDataContainer::const_iterator itEnd =
29616 if (
mDataPlottable->interface1D()->sortKeyIsMainKey() && restrictKeyRange) {
29620 for (QCPErrorBarsDataContainer::const_iterator it = itBegin; it != itEnd;
29622 if (restrictKeyRange) {
29623 const double dataKey =
mDataPlottable->interface1D()->dataMainKey(
29625 if (dataKey < inKeyRange.lower || dataKey > inKeyRange.
upper)
29629 const double dataValue =
29632 if (qIsNaN(dataValue))
continue;
29635 dataValue + (qIsNaN(it->errorPlus) ? 0 : it->errorPlus);
29639 if (current > range.
upper || !haveUpper) {
29640 range.
upper = current;
29645 current = dataValue - (qIsNaN(it->errorMinus) ? 0 : it->errorMinus);
29649 if (current < range.
lower || !haveLower) {
29650 range.
lower = current;
29658 const double current =
mDataPlottable->interface1D()->dataMainValue(
29660 if (qIsNaN(current))
continue;
29664 if (current < range.
lower || !haveLower) {
29665 range.
lower = current;
29668 if (current > range.
upper || !haveUpper) {
29669 range.
upper = current;
29676 if (haveUpper && !haveLower) {
29679 }
else if (haveLower && !haveUpper) {
29684 foundRange = haveLower && haveUpper;
29702 QCPErrorBarsDataContainer::const_iterator it,
29703 QVector<QLineF> &backbones,
29704 QVector<QLineF> &whiskers)
const {
29708 QPointF centerPixel =
29710 if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y()))
return;
29715 const double centerErrorAxisPixel =
29716 errorAxis->
orientation() == Qt::Horizontal ? centerPixel.x()
29718 const double centerOrthoAxisPixel =
29719 orthoAxis->
orientation() == Qt::Horizontal ? centerPixel.x()
29721 const double centerErrorAxisCoord = errorAxis->
pixelToCoord(
29722 centerErrorAxisPixel);
29727 double errorStart, errorEnd;
29728 if (!qIsNaN(it->errorPlus)) {
29729 errorStart = centerErrorAxisPixel +
symbolGap;
29731 errorAxis->
coordToPixel(centerErrorAxisCoord + it->errorPlus);
29734 backbones.append(QLineF(centerOrthoAxisPixel, errorStart,
29735 centerOrthoAxisPixel, errorEnd));
29736 whiskers.append(QLineF(
29741 backbones.append(QLineF(errorStart, centerOrthoAxisPixel,
29742 errorEnd, centerOrthoAxisPixel));
29743 whiskers.append(QLineF(
29749 if (!qIsNaN(it->errorMinus)) {
29750 errorStart = centerErrorAxisPixel -
symbolGap;
29752 errorAxis->
coordToPixel(centerErrorAxisCoord - it->errorMinus);
29755 backbones.append(QLineF(centerOrthoAxisPixel, errorStart,
29756 centerOrthoAxisPixel, errorEnd));
29757 whiskers.append(QLineF(
29762 backbones.append(QLineF(errorStart, centerOrthoAxisPixel,
29763 errorEnd, centerOrthoAxisPixel));
29764 whiskers.append(QLineF(
29793 QCPErrorBarsDataContainer::const_iterator &begin,
29794 QCPErrorBarsDataContainer::const_iterator &end,
29799 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
29816 dataRange = dataRange.
bounded(rangeRestriction);
29830 int i = beginIndex;
29831 while (i > 0 && i < n && i > rangeRestriction.
begin()) {
29836 while (i >= 0 && i < n && i < rangeRestriction.
end()) {
29841 dataRange = dataRange.
bounded(
29855 const QPointF &pixelPoint,
29856 QCPErrorBarsDataContainer::const_iterator &closestData)
const {
29860 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
29864 QCPErrorBarsDataContainer::const_iterator begin, end;
29869 double minDistSqr = (std::numeric_limits<double>::max)();
29870 QVector<QLineF> backbones, whiskers;
29871 for (QCPErrorBarsDataContainer::const_iterator it = begin; it != end;
29874 for (
int i = 0; i < backbones.size(); ++i) {
29875 const double currentDistSqr =
29878 if (currentDistSqr < minDistSqr) {
29879 minDistSqr = currentDistSqr;
29884 return qSqrt(minDistSqr);
29896 QList<QCPDataRange> &selectedSegments,
29897 QList<QCPDataRange> &unselectedSegments)
const {
29898 selectedSegments.clear();
29899 unselectedSegments.clear();
29912 unselectedSegments =
29928 QPointF centerPixel =
29930 const double centerKeyPixel =
mKeyAxis->orientation() == Qt::Horizontal
29933 if (qIsNaN(centerKeyPixel))
return false;
29935 double keyMin, keyMax;
29937 const double centerKey =
mKeyAxis->pixelToCoord(centerKeyPixel);
29940 keyMax = centerKey + (qIsNaN(errorPlus) ? 0 : errorPlus);
29941 keyMin = centerKey - (qIsNaN(errorMinus) ? 0 : errorMinus);
29944 keyMax =
mKeyAxis->pixelToCoord(centerKeyPixel +
29947 keyMin =
mKeyAxis->pixelToCoord(centerKeyPixel -
29951 return ((keyMax >
mKeyAxis->range().lower) &&
29952 (keyMin <
mKeyAxis->range().upper));
29963 const QLineF &line)
const {
29964 if (pixelRect.left() > line.x1() && pixelRect.left() > line.x2())
29966 else if (pixelRect.right() < line.x1() && pixelRect.right() < line.x2())
29968 else if (pixelRect.top() > line.y1() && pixelRect.top() > line.y2())
29970 else if (pixelRect.bottom() < line.y1() && pixelRect.bottom() < line.y2())
30002 point1(createPosition(QLatin1String(
"point1"))),
30003 point2(createPosition(QLatin1String(
"point2"))) {
30031 bool onlySelectable,
30032 QVariant *details)
const {
30046 double clipPad =
mainPen().widthF();
30048 start, end - start,
30049 clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad));
30051 if (!line.isNull()) {
30067 const QRect &rect)
const {
30071 if (vec.
x() == 0 && vec.
y() == 0)
return result;
30072 if (qFuzzyIsNull(vec.
x()))
30077 gamma = base.
x() - bx + (by - base.
y()) * vec.
x() / vec.
y();
30078 if (gamma >= 0 && gamma <= rect.width())
30079 result.setLine(bx + gamma, rect.top(), bx + gamma,
30082 }
else if (qFuzzyIsNull(vec.
y()))
30087 gamma = base.
y() - by + (bx - base.
x()) * vec.
y() / vec.
x();
30088 if (gamma >= 0 && gamma <= rect.height())
30089 result.setLine(rect.left(), by + gamma, rect.right(),
30094 QList<QCPVector2D> pointVectors;
30098 gamma = base.
x() - bx + (by - base.
y()) * vec.
x() / vec.
y();
30099 if (gamma >= 0 && gamma <= rect.width())
30100 pointVectors.append(
QCPVector2D(bx + gamma, by));
30103 by = rect.bottom();
30104 gamma = base.
x() - bx + (by - base.
y()) * vec.
x() / vec.
y();
30105 if (gamma >= 0 && gamma <= rect.width())
30106 pointVectors.append(
QCPVector2D(bx + gamma, by));
30110 gamma = base.
y() - by + (bx - base.
x()) * vec.
y() / vec.
x();
30111 if (gamma >= 0 && gamma <= rect.height())
30112 pointVectors.append(
QCPVector2D(bx, by + gamma));
30116 gamma = base.
y() - by + (bx - base.
x()) * vec.
y() / vec.
x();
30117 if (gamma >= 0 && gamma <= rect.height())
30118 pointVectors.append(
QCPVector2D(bx, by + gamma));
30121 if (pointVectors.size() == 2) {
30122 result.setPoints(pointVectors.at(0).toPointF(),
30123 pointVectors.at(1).toPointF());
30124 }
else if (pointVectors.size() > 2) {
30127 double distSqrMax = 0;
30129 for (
int i = 0; i < pointVectors.size() - 1; ++i) {
30130 for (
int k = i + 1; k < pointVectors.size(); ++k) {
30131 double distSqr = (pointVectors.at(i) - pointVectors.at(k))
30133 if (distSqr > distSqrMax) {
30134 pv1 = pointVectors.at(i);
30135 pv2 = pointVectors.at(k);
30136 distSqrMax = distSqr;
30185 start(createPosition(QLatin1String(
"start"))),
30186 end(createPosition(QLatin1String(
"end"))) {
30236 bool onlySelectable,
30237 QVariant *details)
const {
30249 if (qFuzzyIsNull((startVec - endVec).lengthSquared()))
return;
30252 clipPad = qMax(clipPad, (
double)
mainPen().widthF());
30255 clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad));
30257 if (!line.isNull()) {
30260 painter->setBrush(Qt::SolidPattern);
30262 mTail.
draw(painter, startVec, startVec - endVec);
30264 mHead.
draw(painter, endVec, endVec - startVec);
30277 const QRect &rect)
const {
30278 bool containsStart = rect.contains(
start.x(),
start.y());
30279 bool containsEnd = rect.contains(
end.x(),
end.y());
30280 if (containsStart && containsEnd)
30281 return QLineF(
start.toPointF(),
end.toPointF());
30288 QList<QCPVector2D> pointVectors;
30290 if (!qFuzzyIsNull(vec.
y()))
30295 mu = (by - base.
y()) / vec.
y();
30296 if (mu >= 0 && mu <= 1) {
30297 gamma = base.
x() - bx + mu * vec.
x();
30298 if (gamma >= 0 && gamma <= rect.width())
30299 pointVectors.append(
QCPVector2D(bx + gamma, by));
30303 by = rect.bottom();
30304 mu = (by - base.
y()) / vec.
y();
30305 if (mu >= 0 && mu <= 1) {
30306 gamma = base.
x() - bx + mu * vec.
x();
30307 if (gamma >= 0 && gamma <= rect.width())
30308 pointVectors.append(
QCPVector2D(bx + gamma, by));
30311 if (!qFuzzyIsNull(vec.
x()))
30316 mu = (bx - base.
x()) / vec.
x();
30317 if (mu >= 0 && mu <= 1) {
30318 gamma = base.
y() - by + mu * vec.
y();
30319 if (gamma >= 0 && gamma <= rect.height())
30320 pointVectors.append(
QCPVector2D(bx, by + gamma));
30325 mu = (bx - base.
x()) / vec.
x();
30326 if (mu >= 0 && mu <= 1) {
30327 gamma = base.
y() - by + mu * vec.
y();
30328 if (gamma >= 0 && gamma <= rect.height())
30329 pointVectors.append(
QCPVector2D(bx, by + gamma));
30333 if (containsStart) pointVectors.append(
start);
30334 if (containsEnd) pointVectors.append(
end);
30337 if (pointVectors.size() == 2) {
30338 result.setPoints(pointVectors.at(0).toPointF(),
30339 pointVectors.at(1).toPointF());
30340 }
else if (pointVectors.size() > 2) {
30343 double distSqrMax = 0;
30345 for (
int i = 0; i < pointVectors.size() - 1; ++i) {
30346 for (
int k = i + 1; k < pointVectors.size(); ++k) {
30347 double distSqr = (pointVectors.at(i) - pointVectors.at(k))
30349 if (distSqr > distSqrMax) {
30350 pv1 = pointVectors.at(i);
30351 pv2 = pointVectors.at(k);
30352 distSqrMax = distSqr;
30405 start(createPosition(QLatin1String(
"start"))),
30406 startDir(createPosition(QLatin1String(
"startDir"))),
30407 endDir(createPosition(QLatin1String(
"endDir"))),
30408 end(createPosition(QLatin1String(
"end"))) {
30460 bool onlySelectable,
30461 QVariant *details)
const {
30470 QPainterPath cubicPath(startVec);
30471 cubicPath.cubicTo(startDirVec, endDirVec, endVec);
30473 QList<QPolygonF> polygons = cubicPath.toSubpathPolygons();
30474 if (polygons.isEmpty())
return -1;
30475 const QPolygonF
polygon = polygons.first();
30477 double minDistSqr = (std::numeric_limits<double>::max)();
30478 for (
int i = 1; i <
polygon.size(); ++i) {
30481 if (distSqr < minDistSqr) minDistSqr = distSqr;
30483 return qSqrt(minDistSqr);
30492 if ((endVec - startVec).length() > 1e10)
30495 QPainterPath cubicPath(startVec.
toPointF());
30502 QRect cubicRect = cubicPath.controlPointRect().toRect();
30503 if (cubicRect.isEmpty())
30505 cubicRect.adjust(0, 0, 1, 1);
30506 if (clip.intersects(cubicRect)) {
30508 painter->drawPath(cubicPath);
30509 painter->setBrush(Qt::SolidPattern);
30512 M_PI - cubicPath.angleAtPercent(0) / 180.0 *
M_PI);
30515 -cubicPath.angleAtPercent(1) / 180.0 *
M_PI);
30553 topLeft(createPosition(QLatin1String(
"topLeft"))),
30554 bottomRight(createPosition(QLatin1String(
"bottomRight"))),
30555 top(createAnchor(QLatin1String(
"top"), aiTop)),
30556 topRight(createAnchor(QLatin1String(
"topRight"), aiTopRight)),
30557 right(createAnchor(QLatin1String(
"right"), aiRight)),
30558 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
30559 bottomLeft(createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
30560 left(createAnchor(QLatin1String(
"left"), aiLeft)) {
30606 bool onlySelectable,
30607 QVariant *details)
const {
30614 mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0;
30622 if (p1.toPoint() == p2.toPoint())
return;
30623 QRectF rect = QRectF(p1, p2).normalized();
30624 double clipPad =
mainPen().widthF();
30625 QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
30626 if (boundingRect.intersects(
30632 painter->drawRect(rect);
30640 switch (anchorId) {
30642 return (rect.topLeft() + rect.topRight()) * 0.5;
30644 return rect.topRight();
30646 return (rect.topRight() + rect.bottomRight()) * 0.5;
30648 return (rect.bottomLeft() + rect.bottomRight()) * 0.5;
30650 return rect.bottomLeft();
30652 return (rect.topLeft() + rect.bottomLeft()) * 0.5;
30655 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
30708 position(createPosition(QLatin1String(
"position"))),
30709 topLeft(createAnchor(QLatin1String(
"topLeft"), aiTopLeft)),
30710 top(createAnchor(QLatin1String(
"top"), aiTop)),
30711 topRight(createAnchor(QLatin1String(
"topRight"), aiTopRight)),
30712 right(createAnchor(QLatin1String(
"right"), aiRight)),
30713 bottomRight(createAnchor(QLatin1String(
"bottomRight"), aiBottomRight)),
30714 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
30715 bottomLeft(createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
30716 left(createAnchor(QLatin1String(
"left"), aiLeft)),
30717 mText(QLatin1String(
"text")),
30718 mPositionAlignment(Qt::AlignCenter),
30719 mTextAlignment(Qt::AlignTop | Qt::AlignHCenter),
30841 bool onlySelectable,
30842 QVariant *details)
const {
30850 QTransform inputTransform;
30851 inputTransform.translate(positionPixels.x(), positionPixels.y());
30853 inputTransform.translate(-positionPixels.x(), -positionPixels.y());
30854 QPointF rotatedPos = inputTransform.map(pos);
30855 QFontMetrics fontMetrics(
mFont);
30856 QRect textRect = fontMetrics.boundingRect(
30862 textBoxRect.moveTopLeft(textPos.toPoint());
30870 QTransform transform = painter->transform();
30871 transform.translate(pos.x(), pos.y());
30874 QRect textRect = painter->fontMetrics().boundingRect(
30882 textRect.moveTopLeft(textPos.toPoint() +
30884 textBoxRect.moveTopLeft(textPos.toPoint());
30885 double clipPad =
mainPen().widthF();
30886 QRect boundingRect =
30887 textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
30888 if (transform.mapRect(boundingRect)
30889 .intersects(painter->transform().mapRect(
clipRect()))) {
30890 painter->setTransform(transform);
30891 if ((
mainBrush().style() != Qt::NoBrush &&
30893 (
mainPen().style() != Qt::NoPen &&
30897 painter->drawRect(textBoxRect);
30899 painter->setBrush(Qt::NoBrush);
30909 QTransform transform;
30910 transform.translate(pos.x(), pos.y());
30912 QFontMetrics fontMetrics(
mainFont());
30913 QRect textRect = fontMetrics.boundingRect(
30921 textBoxRect.moveTopLeft(textPos.toPoint());
30922 QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect));
30924 switch (anchorId) {
30926 return rectPoly.at(0);
30928 return (rectPoly.at(0) + rectPoly.at(1)) * 0.5;
30930 return rectPoly.at(1);
30932 return (rectPoly.at(1) + rectPoly.at(2)) * 0.5;
30934 return rectPoly.at(2);
30936 return (rectPoly.at(2) + rectPoly.at(3)) * 0.5;
30938 return rectPoly.at(3);
30940 return (rectPoly.at(3) + rectPoly.at(0)) * 0.5;
30943 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
30959 const QRectF &rect,
30967 result.rx() -= rect.width() / 2.0;
30969 result.rx() -= rect.width();
30971 result.ry() -= rect.height() / 2.0;
30973 result.ry() -= rect.height();
31038 topLeft(createPosition(QLatin1String(
"topLeft"))),
31039 bottomRight(createPosition(QLatin1String(
"bottomRight"))),
31040 topLeftRim(createAnchor(QLatin1String(
"topLeftRim"), aiTopLeftRim)),
31041 top(createAnchor(QLatin1String(
"top"), aiTop)),
31042 topRightRim(createAnchor(QLatin1String(
"topRightRim"), aiTopRightRim)),
31043 right(createAnchor(QLatin1String(
"right"), aiRight)),
31045 createAnchor(QLatin1String(
"bottomRightRim"), aiBottomRightRim)),
31046 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
31048 createAnchor(QLatin1String(
"bottomLeftRim"), aiBottomLeftRim)),
31049 left(createAnchor(QLatin1String(
"left"), aiLeft)),
31050 center(createAnchor(QLatin1String(
"center"), aiCenter)) {
31096 bool onlySelectable,
31097 QVariant *details)
const {
31103 QPointF
center((p1 + p2) / 2.0);
31104 double a = qAbs(p1.x() - p2.x()) / 2.0;
31105 double b = qAbs(p1.y() - p2.y()) / 2.0;
31106 double x = pos.x() -
center.x();
31107 double y = pos.y() -
center.y();
31110 double c = 1.0 / qSqrt(
x *
x / (
a *
a) +
y *
y / (b * b));
31111 double result = qAbs(c - 1) * qSqrt(
x *
x +
y *
y);
31114 mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0) {
31115 if (
x *
x / (
a *
a) +
y *
y / (b * b) <= 1)
31125 if (p1.toPoint() == p2.toPoint())
return;
31126 QRectF ellipseRect = QRectF(p1, p2).normalized();
31129 if (ellipseRect.intersects(clip))
31134 #ifdef __EXCEPTIONS
31138 painter->drawEllipse(ellipseRect);
31139 #ifdef __EXCEPTIONS
31141 qDebug() << Q_FUNC_INFO
31142 <<
"Item too large for memory, setting invisible";
31153 switch (anchorId) {
31155 return rect.center() +
31156 (rect.topLeft() - rect.center()) * 1 / qSqrt(2);
31158 return (rect.topLeft() + rect.topRight()) * 0.5;
31160 return rect.center() +
31161 (rect.topRight() - rect.center()) * 1 / qSqrt(2);
31163 return (rect.topRight() + rect.bottomRight()) * 0.5;
31165 return rect.center() +
31166 (rect.bottomRight() - rect.center()) * 1 / qSqrt(2);
31168 return (rect.bottomLeft() + rect.bottomRight()) * 0.5;
31170 return rect.center() +
31171 (rect.bottomLeft() - rect.center()) * 1 / qSqrt(2);
31173 return (rect.topLeft() + rect.bottomLeft()) * 0.5;
31175 return (rect.topLeft() + rect.bottomRight()) * 0.5;
31178 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
31231 topLeft(createPosition(QLatin1String(
"topLeft"))),
31232 bottomRight(createPosition(QLatin1String(
"bottomRight"))),
31233 top(createAnchor(QLatin1String(
"top"), aiTop)),
31234 topRight(createAnchor(QLatin1String(
"topRight"), aiTopRight)),
31235 right(createAnchor(QLatin1String(
"right"), aiRight)),
31236 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
31237 bottomLeft(createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
31238 left(createAnchor(QLatin1String(
"left"), aiLeft)),
31240 mScaledPixmapInvalidated(true),
31241 mAspectRatioMode(Qt::KeepAspectRatio),
31242 mTransformationMode(Qt::SmoothTransformation) {
31258 if (
mPixmap.isNull()) qDebug() << Q_FUNC_INFO <<
"pixmap is null";
31266 Qt::AspectRatioMode aspectRatioMode,
31267 Qt::TransformationMode transformationMode) {
31291 bool onlySelectable,
31292 QVariant *details)
const {
31301 bool flipHorz =
false;
31302 bool flipVert =
false;
31304 double clipPad =
mainPen().style() == Qt::NoPen ? 0 :
mainPen().widthF();
31305 QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
31306 if (boundingRect.intersects(
clipRect())) {
31310 if (
pen.style() != Qt::NoPen) {
31312 painter->setBrush(Qt::NoBrush);
31313 painter->drawRect(rect);
31325 if (flipHorz) rect.adjust(rect.width(), 0, -rect.width(), 0);
31326 if (flipVert) rect.adjust(0, rect.height(), 0, -rect.height());
31328 switch (anchorId) {
31330 return (rect.topLeft() + rect.topRight()) * 0.5;
31332 return rect.topRight();
31334 return (rect.topRight() + rect.bottomRight()) * 0.5;
31336 return (rect.bottomLeft() + rect.bottomRight()) * 0.5;
31338 return rect.bottomLeft();
31340 return (rect.topLeft() + rect.bottomLeft()) * 0.5;
31344 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
31364 if (
mPixmap.isNull())
return;
31367 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
31368 double devicePixelRatio =
mPixmap.devicePixelRatio();
31370 double devicePixelRatio = 1.0;
31372 if (finalRect.isNull()) finalRect =
getFinalRect(&flipHorz, &flipVert);
31374 finalRect.size() !=
mScaledPixmap.size() / devicePixelRatio) {
31376 mPixmap.scaled(finalRect.size() * devicePixelRatio,
31378 if (flipHorz || flipVert)
31381 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
31408 bool flipHorz =
false;
31409 bool flipVert =
false;
31412 if (p1 == p2)
return QRect(p1, QSize(0, 0));
31414 QSize newSize = QSize(p2.x() - p1.x(), p2.y() - p1.y());
31416 if (newSize.width() < 0) {
31418 newSize.rwidth() *= -1;
31421 if (newSize.height() < 0) {
31423 newSize.rheight() *= -1;
31426 QSize scaledSize =
mPixmap.size();
31427 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
31428 scaledSize /=
mPixmap.devicePixelRatio();
31429 scaledSize.scale(newSize *
mPixmap.devicePixelRatio(),
31436 #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED
31442 if (flippedHorz) *flippedHorz = flipHorz;
31443 if (flippedVert) *flippedVert = flipVert;
31504 position(createPosition(QLatin1String(
"position"))),
31506 mStyle(tsCrosshair),
31509 mInterpolating(false) {
31586 qDebug() << Q_FUNC_INFO
31587 <<
"graph isn't in same QCustomPlot instance as this item";
31621 bool onlySelectable,
31622 QVariant *details)
const {
31627 double w =
mSize / 2.0;
31634 QRectF(center - QPointF(w, w), center + QPointF(w, w))
31636 return qSqrt(qMin(
QCPVector2D(pos).distanceSquaredToLine(
31637 center + QPointF(-w, 0),
31638 center + QPointF(w, 0)),
31640 center + QPointF(0, -w),
31641 center + QPointF(0, w))));
31645 return qSqrt(qMin(
QCPVector2D(pos).distanceSquaredToLine(
31653 if (clip.intersects(
31654 QRectF(center - QPointF(w, w), center + QPointF(w, w))
31658 double circleLine = w;
31659 double result = qAbs(centerDist - circleLine);
31662 mBrush.style() != Qt::NoBrush &&
31663 mBrush.color().alpha() != 0) {
31664 if (centerDist <= circleLine)
31672 if (clip.intersects(
31673 QRectF(center - QPointF(w, w), center + QPointF(w, w))
31676 QRectF(center - QPointF(w, w), center + QPointF(w, w));
31677 bool filledRect =
mBrush.style() != Qt::NoBrush &&
31678 mBrush.color().alpha() != 0;
31695 double w =
mSize / 2.0;
31701 if (clip.intersects(
31702 QRectF(center - QPointF(w, w), center + QPointF(w, w))
31704 painter->
drawLine(QLineF(center + QPointF(-w, 0),
31705 center + QPointF(w, 0)));
31706 painter->
drawLine(QLineF(center + QPointF(0, -w),
31707 center + QPointF(0, w)));
31712 if (center.y() > clip.top() && center.y() < clip.bottom())
31713 painter->
drawLine(QLineF(clip.left(), center.y(), clip.right(),
31715 if (center.x() > clip.left() && center.x() < clip.right())
31716 painter->
drawLine(QLineF(center.x(), clip.top(), center.x(),
31721 if (clip.intersects(
31722 QRectF(center - QPointF(w, w), center + QPointF(w, w))
31724 painter->drawEllipse(center, w, w);
31728 if (clip.intersects(
31729 QRectF(center - QPointF(w, w), center + QPointF(w, w))
31732 QRectF(center - QPointF(w, w), center + QPointF(w, w)));
31760 if (mGraphKey <= first->key)
31779 if (!qFuzzyCompare((
double)it->key,
31780 (
double)prevIt->key))
31781 slope = (it->value - prevIt->value) /
31782 (it->key - prevIt->key);
31789 if (
mGraphKey < (prevIt->key + it->key) * 0.5)
31804 qDebug() << Q_FUNC_INFO <<
"graph has no data";
31806 qDebug() << Q_FUNC_INFO
31807 <<
"graph not contained in QCustomPlot instance (anymore)";
31868 left(createPosition(QLatin1String(
"left"))),
31869 right(createPosition(QLatin1String(
"right"))),
31870 center(createAnchor(QLatin1String(
"center"), aiCenter)),
31872 mStyle(bsCalligraphic) {
31924 bool onlySelectable,
31925 QVariant *details)
const {
31934 QCPVector2D widthVec = (rightVec - leftVec) * 0.5;
31936 QCPVector2D centerVec = (rightVec + leftVec) * 0.5 - lengthVec;
31942 centerVec + widthVec);
31944 centerVec - widthVec);
31946 centerVec + widthVec);
31947 return qSqrt(qMin(qMin(
a, b), c));
31952 centerVec - widthVec * 0.75 + lengthVec * 0.15,
31953 centerVec + lengthVec * 0.3);
31955 centerVec - widthVec + lengthVec * 0.7,
31956 centerVec - widthVec * 0.75 + lengthVec * 0.15);
31958 centerVec + widthVec * 0.75 + lengthVec * 0.15,
31959 centerVec + lengthVec * 0.3);
31961 centerVec + widthVec + lengthVec * 0.7,
31962 centerVec + widthVec * 0.75 + lengthVec * 0.15);
31963 return qSqrt(qMin(qMin(
a, b), qMin(c, d)));
31975 QCPVector2D widthVec = (rightVec - leftVec) * 0.5;
31977 QCPVector2D centerVec = (rightVec + leftVec) * 0.5 - lengthVec;
31979 QPolygon boundingPoly;
31981 << (rightVec - lengthVec).toPoint()
31982 << (leftVec - lengthVec).toPoint();
31985 if (clip.intersects(boundingPoly.boundingRect())) {
31989 painter->
drawLine((centerVec + widthVec).toPointF(),
31990 (centerVec - widthVec).toPointF());
31992 (centerVec + widthVec).toPointF(),
31993 (centerVec + widthVec + lengthVec).toPointF());
31995 (centerVec - widthVec).toPointF(),
31996 (centerVec - widthVec + lengthVec).toPointF());
32000 painter->setBrush(Qt::NoBrush);
32002 path.moveTo((centerVec + widthVec + lengthVec).toPointF());
32003 path.cubicTo((centerVec + widthVec).toPointF(),
32004 (centerVec + widthVec).toPointF(),
32006 path.cubicTo((centerVec - widthVec).toPointF(),
32007 (centerVec - widthVec).toPointF(),
32008 (centerVec - widthVec + lengthVec).toPointF());
32009 painter->drawPath(
path);
32013 painter->setBrush(Qt::NoBrush);
32015 path.moveTo((centerVec + widthVec + lengthVec).toPointF());
32017 (centerVec + widthVec - lengthVec * 0.8).toPointF(),
32018 (centerVec + 0.4 * widthVec + lengthVec).toPointF(),
32021 (centerVec - 0.4 * widthVec + lengthVec).toPointF(),
32022 (centerVec - widthVec - lengthVec * 0.8).toPointF(),
32023 (centerVec - widthVec + lengthVec).toPointF());
32024 painter->drawPath(
path);
32028 painter->
setPen(Qt::NoPen);
32031 path.moveTo((centerVec + widthVec + lengthVec).toPointF());
32034 (centerVec + widthVec - lengthVec * 0.8).toPointF(),
32035 (centerVec + 0.4 * widthVec + 0.8 * lengthVec)
32039 (centerVec - 0.4 * widthVec + 0.8 * lengthVec)
32041 (centerVec - widthVec - lengthVec * 0.8).toPointF(),
32042 (centerVec - widthVec + lengthVec).toPointF());
32045 (centerVec - widthVec - lengthVec * 0.5).toPointF(),
32046 (centerVec - 0.2 * widthVec + 1.2 * lengthVec)
32048 (centerVec + lengthVec * 0.2).toPointF());
32050 (centerVec + 0.2 * widthVec + 1.2 * lengthVec)
32052 (centerVec + widthVec - lengthVec * 0.5).toPointF(),
32053 (centerVec + widthVec + lengthVec).toPointF());
32055 painter->drawPath(
path);
32068 QCPVector2D widthVec = (rightVec - leftVec) * 0.5;
32070 QCPVector2D centerVec = (rightVec + leftVec) * 0.5 - lengthVec;
32072 switch (anchorId) {
32076 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
filament::Texture::InternalFormat format
QPointF qtCompatWheelEventPos(const QWheelEvent *event) noexcept
double qtCompatWheelEventDelta(const QWheelEvent *event) noexcept
boost::geometry::model::polygon< point_xy > polygon
QCPDataContainer< QCPFinancialData > QCPFinancialDataContainer
The abstract base class for all items in a plot.
QCPItemAnchor * anchor(const QString &name) const
Q_SLOT void setSelected(bool selected)
QCPItemPosition * position(const QString &name) const
QList< QCPItemAnchor * > mAnchors
QPointer< QCPAxisRect > mClipAxisRect
virtual ~QCPAbstractItem()
void setClipToAxisRect(bool clip)
QList< QCPItemPosition * > mPositions
friend class QCPItemAnchor
bool clipToAxisRect() const
virtual QRect clipRect() const
virtual QCP::Interaction selectionCategory() const
void selectableChanged(bool selectable)
QCPItemPosition * createPosition(const QString &name)
void setClipAxisRect(QCPAxisRect *rect)
double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
bool hasAnchor(const QString &name) const
Q_SLOT void setSelectable(bool selectable)
virtual void deselectEvent(bool *selectionStateChanged)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
QCPAbstractItem(QCustomPlot *parentPlot)
void selectionChanged(bool selected)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
virtual QPointF anchorPixelPosition(int anchorId) const
QCPAxisRect * clipAxisRect() const
QCPItemAnchor * createAnchor(const QString &name, int anchorId)
The abstract base class for all entries in a QCPLegend.
void setFont(const QFont &font)
QColor mSelectedTextColor
void setSelectedTextColor(const QColor &color)
void setTextColor(const QColor &color)
Q_SLOT void setSelected(bool selected)
void selectionChanged(bool selected)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setSelectedFont(const QFont &font)
Q_SLOT void setSelectable(bool selectable)
virtual QCP::Interaction selectionCategory() const
void selectableChanged(bool selectable)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
virtual QRect clipRect() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void deselectEvent(bool *selectionStateChanged)
QCPLegend * mParentLegend
QCPAbstractLegendItem(QCPLegend *parent)
The abstract base class for paint buffers, which define the rendering backend.
QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio)
virtual ~QCPAbstractPaintBuffer()
void setDevicePixelRatio(double ratio)
void setSize(const QSize &size)
void setInvalidated(bool invalidated=true)
virtual void reallocateBuffer()=0
A template base class for plottables with one-dimensional data.
virtual int dataCount() const
void drawPolyline(QCPPainter *painter, const QVector< QPointF > &lineData) const
QSharedPointer< QCPDataContainer< QCPGraphData > > mDataContainer
void getDataSegments(QList< QCPDataRange > &selectedSegments, QList< QCPDataRange > &unselectedSegments) const
The abstract base class for all data representing objects in a plot.
QCP::SelectionType selectable() const
QCPDataSelection selection() const
void setAntialiasedFill(bool enabled)
QCPSelectionDecorator * mSelectionDecorator
void rescaleAxes(bool onlyEnlarge=false) const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
QCPDataSelection mSelection
void setSelectionDecorator(QCPSelectionDecorator *decorator)
Q_SLOT void setSelection(QCPDataSelection selection)
QCPAxis * keyAxis() const
void setAntialiasedScatters(bool enabled)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
void pixelsToCoords(double x, double y, double &key, double &value) const
QCP::SelectionType mSelectable
void selectionChanged(bool selected)
bool removeFromLegend(QCPLegend *legend) const
friend class QCPPlottableLegendItem
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const =0
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const =0
void applyDefaultAntialiasingHint(QCPPainter *painter) const
void selectableChanged(QCP::SelectionType selectable)
virtual void deselectEvent(bool *selectionStateChanged)
void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const
void setValueAxis(QCPAxis *axis)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const =0
void setBrush(const QBrush &brush)
void coordsToPixels(double key, double value, double &x, double &y) const
QPointer< QCPAxis > mValueAxis
virtual QCPPlottableInterface1D * interface1D()
void setKeyAxis(QCPAxis *axis)
virtual ~QCPAbstractPlottable()
void applyFillAntialiasingHint(QCPPainter *painter) const
bool mAntialiasedScatters
bool addToLegend(QCPLegend *legend)
virtual QRect clipRect() const
void setPen(const QPen &pen)
void setName(const QString &name)
Q_SLOT void setSelectable(QCP::SelectionType selectable)
QPointer< QCPAxis > mKeyAxis
void applyScattersAntialiasingHint(QCPPainter *painter) const
bool removeFromLegend() const
void rescaleKeyAxis(bool onlyEnlarge=false) const
QCPAxis * valueAxis() const
QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual QCP::Interaction selectionCategory() const
Holds multiple axes and arranges them in a rectangular shape.
QList< QCPAbstractItem * > items() const
bool removeAxis(QCPAxis *axis)
QList< QCPAxis * > axes() const
Qt::Orientations mRangeZoom
virtual void update(UpdatePhase phase)
QList< QCPRange > mDragStartHorzRange
QList< QCPGraph * > graphs() const
QCPAxis * addAxis(QCPAxis::AxisType type, QCPAxis *axis=0)
double mRangeZoomFactorVert
QPixmap mBackgroundPixmap
QList< QPointer< QCPAxis > > mRangeDragVertAxis
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details)
QCPAxis * axis(QCPAxis::AxisType type, int index=0) const
QList< QCPAbstractPlottable * > plottables() const
virtual void wheelEvent(QWheelEvent *event)
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
void setupFullAxesBox(bool connectRanges=false)
virtual void layoutChanged()
void zoom(const QRectF &pixelRect)
void updateAxesOffset(QCPAxis::AxisType type)
void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical)
QCPAxis * rangeZoomAxis(Qt::Orientation orientation)
QCPAxis * rangeDragAxis(Qt::Orientation orientation)
QCP::AntialiasedElements mNotAADragBackup
QList< QCPAxis * > addAxes(QCPAxis::AxisTypes types)
void setRangeZoom(Qt::Orientations orientations)
Qt::AspectRatioMode mBackgroundScaledMode
int axisCount(QCPAxis::AxisType type) const
QList< QCPAxis * > rangeZoomAxes(Qt::Orientation orientation)
void setRangeZoomFactor(double horizontalFactor, double verticalFactor)
QList< QCPAxis * > axes(QCPAxis::AxisTypes types) const
void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical)
QCPLayoutInset * insetLayout() const
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
Qt::Orientations rangeZoom() const
QList< QPointer< QCPAxis > > mRangeZoomHorzAxis
Qt::Orientations rangeDrag() const
QCP::AntialiasedElements mAADragBackup
QPixmap mScaledBackgroundPixmap
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
Qt::Orientations mRangeDrag
QList< QCPAxis * > rangeDragAxes(Qt::Orientation orientation)
QList< QPointer< QCPAxis > > mRangeZoomVertAxis
QList< QCPRange > mDragStartVertRange
void drawBackground(QCPPainter *painter)
QList< QPointer< QCPAxis > > mRangeDragHorzAxis
double mRangeZoomFactorHorz
QHash< QCPAxis::AxisType, QList< QCPAxis * > > mAxes
double rangeZoomFactor(Qt::Orientation orientation)
void setRangeDrag(Qt::Orientations orientations)
void setBackgroundScaled(bool scaled)
virtual int calculateAutoMargin(QCP::MarginSide side)
QCPLayoutInset * mInsetLayout
void setBackground(const QPixmap &pm)
virtual void draw(QCPPainter *painter)
virtual QVector< double > createTickVector(double tickStep, const QCPRange &range)
static QDateTime keyToDateTime(double key)
void setTickOrigin(double origin)
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
Qt::TimeSpec mDateTimeSpec
enum QCPAxisTickerDateTime::DateStrategy mDateStrategy
virtual int getSubTickCount(double tickStep)
static double dateTimeToKey(const QDateTime dateTime)
void setDateTimeFormat(const QString &format)
virtual double getTickStep(const QCPRange &range)
void setDateTimeSpec(Qt::TimeSpec spec)
@ ssPowers
An integer power of the specified tick step is allowed.
void setTickStep(double step)
ScaleStrategy mScaleStrategy
virtual double getTickStep(const QCPRange &range)
void setScaleStrategy(ScaleStrategy strategy)
virtual QVector< double > createTickVector(double tickStep, const QCPRange &range)
virtual int getSubTickCount(double tickStep)
virtual double getTickStep(const QCPRange &range)
void setLogBase(double base)
void setSubTickCount(int subTicks)
virtual double getTickStep(const QCPRange &range)
void simplifyFraction(int &numerator, int &denominator) const
QString unicodeSuperscript(int number) const
FractionStyle mFractionStyle
void setPiValue(double pi)
void setPeriodicity(int multiplesOfPi)
QString unicodeSubscript(int number) const
virtual int getSubTickCount(double tickStep)
void setFractionStyle(FractionStyle style)
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
void setPiSymbol(QString symbol)
QString unicodeFraction(int numerator, int denominator) const
QString fractionToString(int numerator, int denominator) const
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
QMap< double, QString > mTicks
void addTick(double position, const QString &label)
virtual double getTickStep(const QCPRange &range)
void setTicks(const QMap< double, QString > &ticks)
void setSubTickCount(int subTicks)
virtual int getSubTickCount(double tickStep)
void addTicks(const QMap< double, QString > &ticks)
QMap< double, QString > & ticks()
virtual QVector< double > createTickVector(double tickStep, const QCPRange &range)
void replaceUnit(QString &text, TimeUnit unit, int value) const
void setTimeFormat(const QString &format)
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
QHash< TimeUnit, int > mFieldWidth
@ tuSeconds
Seconds (%s in setTimeFormat)
@ tuMinutes
Minutes (%m in setTimeFormat)
@ tuHours
Hours (%h in setTimeFormat)
@ tuDays
Days (%d in setTimeFormat)
virtual int getSubTickCount(double tickStep)
void setFieldWidth(TimeUnit unit, int width)
QHash< TimeUnit, QString > mFormatPattern
virtual double getTickStep(const QCPRange &range)
The base class tick generator used by QCPAxis to create tick positions and tick labels.
double getMantissa(double input, double *magnitude=0) const
void setTickCount(int count)
virtual int getSubTickCount(double tickStep)
double pickClosest(double target, const QVector< double > &candidates) const
void setTickStepStrategy(TickStepStrategy strategy)
virtual QVector< QString > createLabelVector(const QVector< double > &ticks, const QLocale &locale, QChar formatChar, int precision)
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
virtual double getTickStep(const QCPRange &range)
virtual QVector< double > createSubTickVector(int subTickCount, const QVector< double > &ticks)
void trimTicks(const QCPRange &range, QVector< double > &ticks, bool keepOneOutlier) const
void setTickOrigin(double origin)
TickStepStrategy mTickStepStrategy
double cleanMantissa(double input) const
virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector< double > &ticks, QVector< double > *subTicks, QVector< QString > *tickLabels)
virtual QVector< double > createTickVector(double tickStep, const QCPRange &range)
Manages a single axis inside a QCustomPlot.
void setSelectedLabelFont(const QFont &font)
void setOffset(int offset)
virtual QCP::Interaction selectionCategory() const
void setTickLabels(bool show)
void rangeChanged(const QCPRange &newRange)
void setLowerEnding(const QCPLineEnding &ending)
QCP::AntialiasedElements mNotAADragBackup
QCPLineEnding lowerEnding() const
void setTickLabelSide(LabelSide side)
QVector< double > mSubTickVector
void moveRange(double diff)
void setTickLabelRotation(double degrees)
LabelSide tickLabelSide() const
QString numberFormat() const
void setRangeReversed(bool reversed)
void setNumberPrecision(int precision)
SelectablePart getPartAt(const QPointF &pos) const
@ lsOutside
Tick labels will be displayed outside the axis rect.
int numberPrecision() const
virtual void draw(QCPPainter *painter)
void setSelectedSubTickPen(const QPen &pen)
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
void setTickLabelFont(const QFont &font)
void scaleRange(double factor)
void setLabel(const QString &str)
void scaleTypeChanged(QCPAxis::ScaleType scaleType)
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
@ stLinear
Linear scaling.
QLatin1Char mNumberFormatChar
void setTickLabelColor(const QColor &color)
void setTickLengthOut(int outside)
QColor mSelectedTickLabelColor
QList< QCPAbstractItem * > items() const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setLabelPadding(int padding)
int pixelOrientation() const
virtual int calculateMargin()
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void rescale(bool onlyVisiblePlottables=false)
void setSubTickLengthOut(int outside)
void setTicker(QSharedPointer< QCPAxisTicker > ticker)
QFont mSelectedTickLabelFont
virtual void deselectEvent(bool *selectionStateChanged)
double pixelToCoord(double value) const
void setPadding(int padding)
double tickLabelRotation() const
void setSelectedLabelColor(const QColor &color)
void selectionChanged(const QCPAxis::SelectableParts &parts)
void setTickLength(int inside, int outside=0)
void setUpperEnding(const QCPLineEnding &ending)
QFont getTickLabelFont() const
void setLabelColor(const QColor &color)
QVector< double > mTickVector
QCPAxisPainterPrivate * mAxisPainter
virtual void wheelEvent(QWheelEvent *event)
void setLabelFont(const QFont &font)
void setBasePen(const QPen &pen)
QSharedPointer< QCPAxisTicker > ticker() const
Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts)
void setSelectedTickPen(const QPen &pen)
void setSelectedTickLabelFont(const QFont &font)
SelectableParts selectedParts() const
QColor getTickLabelColor() const
SelectableParts mSelectedParts
QColor mSelectedLabelColor
void setSelectedTickLabelColor(const QColor &color)
QCP::AntialiasedElements mAADragBackup
QCPLineEnding upperEnding() const
AxisType axisType() const
void selectableChanged(const QCPAxis::SelectableParts &parts)
static AxisType opposite(AxisType type)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
QPen getSubTickPen() const
Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts)
void setSubTickLength(int inside, int outside=0)
SelectableParts mSelectableParts
bool rangeReversed() const
Qt::Orientation orientation() const
@ spAxis
The axis backbone and tick marks.
@ spAxisLabel
The axis label.
@ spNone
None of the selectable parts.
static AxisType marginSideToAxisType(QCP::MarginSide side)
const QCPRange range() const
void setSubTickLengthIn(int inside)
QList< QCPAbstractPlottable * > plottables() const
QCPAxis(QCPAxisRect *parent, AxisType type)
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details)
int subTickLengthOut() const
QVector< QString > mTickVectorLabels
void setRangeUpper(double upper)
ScaleType scaleType() const
int tickLengthOut() const
QList< QCPGraph * > graphs() const
void setTickPen(const QPen &pen)
QSharedPointer< QCPAxisTicker > mTicker
Q_SLOT void setScaleType(QCPAxis::ScaleType type)
void setNumberFormat(const QString &formatCode)
QColor getLabelColor() const
QFont getLabelFont() const
void setSelectedBasePen(const QPen &pen)
Q_SLOT void setRange(const QCPRange &range)
void setSubTickPen(const QPen &pen)
bool mNumberBeautifulPowers
double coordToPixel(double value) const
void setTickLabelPadding(int padding)
void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0)
int subTickLengthIn() const
void setSubTicks(bool show)
int tickLabelPadding() const
void setTickLengthIn(int inside)
QCPAxisRect * axisRect() const
void setRangeLower(double lower)
Holds the data of one single data point (one bar) for QCPBars.
Groups multiple QCPBars together so they appear side by side.
double getPixelSpacing(const QCPBars *bars, double keyCoord)
void remove(QCPBars *bars)
void setSpacingType(SpacingType spacingType)
void insert(int i, QCPBars *bars)
@ stAbsolute
Bar spacing is in absolute pixels.
QList< QCPBars * > bars() const
void registerBars(QCPBars *bars)
void append(QCPBars *bars)
SpacingType spacingType() const
double keyPixelOffset(const QCPBars *bars, double keyCoord)
QCPBarsGroup(QCustomPlot *parentPlot)
void setSpacing(double spacing)
void unregisterBars(QCPBars *bars)
A plottable representing a bar chart in a plot.
QRectF getBarRect(double key, double value) const
double getStackedBaseValue(double key, bool positive) const
QCPBars * barBelow() const
void addData(const QVector< double > &keys, const QVector< double > &values, bool alreadySorted=false)
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
virtual void draw(QCPPainter *painter)
WidthType widthType() const
void setBaseValue(double baseValue)
QCPBarsGroup * barsGroup() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
@ wtAbsolute
Bar width is in absolute pixels.
QPointer< QCPBars > mBarAbove
void moveBelow(QCPBars *bars)
void setData(QSharedPointer< QCPBarsDataContainer > data)
static void connectBars(QCPBars *lower, QCPBars *upper)
QSharedPointer< QCPBarsDataContainer > data() const
QCPBarsGroup * mBarsGroup
virtual QPointF dataPixelPosition(int index) const
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const
void moveAbove(QCPBars *bars)
void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
QPointer< QCPBars > mBarBelow
void getPixelWidth(double key, double &lower, double &upper) const
void setWidthType(WidthType widthType)
void setStackingGap(double pixels)
void setBarsGroup(QCPBarsGroup *barsGroup)
void setWidth(double width)
Defines a color gradient for use with e.g. QCPColorMap.
ColorInterpolation mColorInterpolation
QRgb color(double position, const QCPRange &range, bool logarithmic=false)
bool stopsUseAlpha() const
void setLevelCount(int n)
void setPeriodic(bool enabled)
void setColorStopAt(double position, const QColor &color)
void setColorStops(const QMap< double, QColor > &colorStops)
bool operator==(const QCPColorGradient &other) const
QMap< double, QColor > mColorStops
QCPColorGradient inverted() const
void loadPreset(GradientPreset preset)
void setColorInterpolation(ColorInterpolation interpolation)
QMap< double, QColor > colorStops() const
void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false)
bool mColorBufferInvalidated
@ ciRGB
Color channels red, green and blue are linearly interpolated.
QVector< QRgb > mColorBuffer
@ gpCandy
Blue over pink to white.
Holds the two-dimensional data of a QCPColorMap plottable.
void setKeyRange(const QCPRange &keyRange)
void setValueSize(int valueSize)
void setSize(int keySize, int valueSize)
QCPRange keyRange() const
double data(double key, double value)
bool createAlpha(bool initializeOpaque=true)
unsigned char alpha(int keyIndex, int valueIndex)
QCPRange valueRange() const
void setCell(int keyIndex, int valueIndex, double z)
void fillAlpha(unsigned char alpha)
QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange)
void setRange(const QCPRange &keyRange, const QCPRange &valueRange)
void setAlpha(int keyIndex, int valueIndex, unsigned char alpha)
void recalculateDataBounds()
QCPRange dataBounds() const
void setKeySize(int keySize)
void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const
void setValueRange(const QCPRange &valueRange)
void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const
double cell(int keyIndex, int valueIndex)
void setData(double key, double value, double z)
QCPColorMapData & operator=(const QCPColorMapData &other)
A plottable representing a two-dimensional color map in a plot.
QCPColorMapData * data() const
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
QCPColorMapData * mMapData
void gradientChanged(const QCPColorGradient &newGradient)
virtual void draw(QCPPainter *painter)
QPointer< QCPColorScale > mColorScale
void setInterpolate(bool enabled)
void setData(QCPColorMapData *data, bool copy=false)
Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18))
virtual void updateMapImage()
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
Q_SLOT void setGradient(const QCPColorGradient &gradient)
void dataRangeChanged(const QCPRange &newRange)
void rescaleDataRange(bool recalculateDataBounds=false)
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
Q_SLOT void setDataRange(const QCPRange &dataRange)
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
QCPColorScale * colorScale() const
QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setColorScale(QCPColorScale *colorScale)
QCPColorGradient mGradient
QCPAxis::ScaleType mDataScaleType
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
bool mMapImageInvalidated
QImage mUndersampledMapImage
QCPColorGradient gradient() const
void setTightBoundary(bool enabled)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
QCPRange dataRange() const
A color scale for use with color coding data such as QCPColorMap.
void setType(QCPAxis::AxisType type)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
void setRangeDrag(bool enabled)
QCPAxis::ScaleType mDataScaleType
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details)
QCPColorGradient gradient() const
void rescaleDataRange(bool onlyVisibleMaps)
QCPRange dataRange() const
QList< QCPColorMap * > colorMaps() const
QPointer< QCPColorScaleAxisRectPrivate > mAxisRect
void gradientChanged(const QCPColorGradient &newGradient)
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
void dataRangeChanged(const QCPRange &newRange)
QCPAxis::AxisType type() const
void setRangeZoom(bool enabled)
QPointer< QCPAxis > mColorAxis
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
QCPColorScale(QCustomPlot *parentPlot)
virtual void wheelEvent(QWheelEvent *event)
virtual void update(UpdatePhase phase)
void setBarWidth(int width)
Q_SLOT void setDataRange(const QCPRange &dataRange)
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QCPColorGradient mGradient
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
void setLabel(const QString &str)
Holds the data of one single data point for QCPCurve.
QCPScatterStyle mScatterStyle
virtual void drawScatterPlot(QCPPainter *painter, const QVector< QPointF > &points, const QCPScatterStyle &style) const
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
virtual void draw(QCPPainter *painter)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
@ lsNone
No line is drawn between data points (e.g. only scatters)
@ lsLine
Data points are connected with a straight line.
QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setData(QSharedPointer< QCPCurveDataContainer > data)
void setLineStyle(LineStyle style)
void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector< QPointF > &beforeTraverse, QVector< QPointF > &afterTraverse) const
void setScatterStyle(const QCPScatterStyle &style)
void getScatters(QVector< QPointF > *scatters, const QCPDataRange &dataRange, double scatterWidth) const
QVector< QPointF > getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
void addData(const QVector< double > &t, const QVector< double > &keys, const QVector< double > &values, bool alreadySorted=false)
QSharedPointer< QCPCurveDataContainer > data() const
int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setScatterSkip(int skip)
double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const
virtual void drawCurveLine(QCPPainter *painter, const QVector< QPointF > &lines) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void getCurveLines(QVector< QPointF > *lines, const QCPDataRange &dataRange, double penWidth) const
bool mayTraverse(int prevRegion, int currentRegion) const
bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const
The generic data container for one-dimensional plottables.
QVector< DataType >::const_iterator const_iterator
Describes a data range given by begin and end index.
bool contains(const QCPDataRange &other) const
QCPDataRange adjusted(int changeBegin, int changeEnd) const
QCPDataRange expanded(const QCPDataRange &other) const
QCPDataRange intersection(const QCPDataRange &other) const
bool intersects(const QCPDataRange &other) const
QCPDataRange bounded(const QCPDataRange &other) const
Describes a data set by holding multiple QCPDataRange instances.
void enforceType(QCP::SelectionType type)
QCPDataSelection & operator+=(const QCPDataSelection &other)
void addDataRange(const QCPDataRange &dataRange, bool simplify=true)
bool operator==(const QCPDataSelection &other) const
QCPDataSelection & operator-=(const QCPDataSelection &other)
QCPDataRange dataRange(int index=0) const
QCPDataRange span() const
bool contains(const QCPDataSelection &other) const
int dataRangeCount() const
QList< QCPDataRange > dataRanges() const
int dataPointCount() const
QCPDataSelection inverse(const QCPDataRange &outerRange) const
QCPDataSelection intersection(const QCPDataRange &other) const
Holds the data of one single error bar for QCPErrorBars.
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
virtual void draw(QCPPainter *painter)
virtual QCPRange dataValueRange(int index) const
QPointer< QCPAbstractPlottable > mDataPlottable
virtual double dataSortKey(int index) const
void getDataSegments(QList< QCPDataRange > &selectedSegments, QList< QCPDataRange > &unselectedSegments) const
void setSymbolGap(double pixels)
bool errorBarVisible(int index) const
virtual int findBegin(double sortKey, bool expandedRange=true) const
QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual int findEnd(double sortKey, bool expandedRange=true) const
virtual QPointF dataPixelPosition(int index) const
QSharedPointer< QCPErrorBarsDataContainer > mDataContainer
virtual double dataMainValue(int index) const
double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const
void setData(QSharedPointer< QCPErrorBarsDataContainer > data)
virtual bool sortKeyIsMainKey() const
bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const
void setDataPlottable(QCPAbstractPlottable *plottable)
void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const
void addData(const QVector< double > &error)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector< QLineF > &backbones, QVector< QLineF > &whiskers) const
virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const
void setWhiskerWidth(double pixels)
virtual int dataCount() const
virtual double dataMainKey(int index) const
QSharedPointer< QCPErrorBarsDataContainer > data() const
void setErrorType(ErrorType type)
Holds the data of one single data point for QCPFinancial.
static QCPFinancialDataContainer timeSeriesToOhlc(const QVector< double > &time, const QVector< double > &value, double timeBinSize, double timeBinOffset=0)
@ csOhlc
Open-High-Low-Close bar representation.
@ csCandlestick
Candlestick representation.
void setTwoColored(bool twoColored)
virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const
void setWidthType(WidthType widthType)
double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const
void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected)
void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const
void addData(const QVector< double > &keys, const QVector< double > &open, const QVector< double > &high, const QVector< double > &low, const QVector< double > &close, bool alreadySorted=false)
double getPixelWidth(double key, double keyPixel) const
QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
QSharedPointer< QCPFinancialDataContainer > data() const
void setChartStyle(ChartStyle style)
void setBrushPositive(const QBrush &brush)
void setData(QSharedPointer< QCPFinancialDataContainer > data)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
WidthType widthType() const
void setBrushNegative(const QBrush &brush)
double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const
void setWidth(double width)
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
void setPenPositive(const QPen &pen)
virtual void draw(QCPPainter *painter)
void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected)
@ wtAbsolute
width is in absolute pixels
@ wtAxisRectRatio
width is given by a fraction of the axis rect size
QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const
void setPenNegative(const QPen &pen)
Holds the data of one single data point for QCPGraph.
A plottable representing a graph in a plot.
QVector< QPointF > dataToLines(const QVector< QCPGraphData > &data) const
QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis)
QVector< QCPDataRange > getNonNanSegments(const QVector< QPointF > *lineData, Qt::Orientation keyOrientation) const
void setScatterStyle(const QCPScatterStyle &style)
QPointF getFillBasePoint(QPointF matchingDataPoint) const
void setScatterSkip(int skip)
void setData(QSharedPointer< QCPGraphDataContainer > data)
QVector< QPointF > dataToStepLeftLines(const QVector< QCPGraphData > &data) const
virtual void getOptimizedLineData(QVector< QCPGraphData > *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const
virtual void drawImpulsePlot(QCPPainter *painter, const QVector< QPointF > &lines) const
QVector< QPointF > dataToStepCenterLines(const QVector< QCPGraphData > &data) const
QPointer< QCPGraph > mChannelFillGraph
QVector< QPointF > dataToImpulseLines(const QVector< QCPGraphData > &data) const
void setChannelFillGraph(QCPGraph *targetGraph)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
QVector< QPair< QCPDataRange, QCPDataRange > > getOverlappingSegments(QVector< QCPDataRange > thisSegments, const QVector< QPointF > *thisData, QVector< QCPDataRange > otherSegments, const QVector< QPointF > *otherData) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPScatterStyle mScatterStyle
virtual void drawLinePlot(QCPPainter *painter, const QVector< QPointF > &lines) const
void setLineStyle(LineStyle ls)
virtual void getOptimizedScatterData(QVector< QCPGraphData > *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const
void getLines(QVector< QPointF > *lines, const QCPDataRange &dataRange) const
int findIndexBelowY(const QVector< QPointF > *data, double y) const
virtual void draw(QCPPainter *painter)
virtual void drawFill(QCPPainter *painter, QVector< QPointF > *lines) const
void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const
double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const
int findIndexAboveY(const QVector< QPointF > *data, double y) const
int findIndexBelowX(const QVector< QPointF > *data, double x) const
const QPolygonF getChannelFillPolygon(const QVector< QPointF > *lineData, QCPDataRange thisSegment, const QVector< QPointF > *otherData, QCPDataRange otherSegment) const
void getScatters(QVector< QPointF > *scatters, const QCPDataRange &dataRange) const
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
int findIndexAboveX(const QVector< QPointF > *data, double x) const
QVector< QPointF > dataToStepRightLines(const QVector< QCPGraphData > &data) const
void setAdaptiveSampling(bool enabled)
bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const
virtual void drawScatterPlot(QCPPainter *painter, const QVector< QPointF > &scatters, const QCPScatterStyle &style) const
QSharedPointer< QCPGraphDataContainer > data() const
@ lsLine
data points are connected by a straight line
void addData(const QVector< double > &keys, const QVector< double > &values, bool alreadySorted=false)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
const QPolygonF getFillPolygon(const QVector< QPointF > *lineData, QCPDataRange segment) const
Responsible for drawing the grid of a QCPAxis.
void setZeroLinePen(const QPen &pen)
void setAntialiasedZeroLine(bool enabled)
void setAntialiasedSubGrid(bool enabled)
void drawSubGridLines(QCPPainter *painter) const
bool mAntialiasedZeroLine
void setSubGridPen(const QPen &pen)
void setPen(const QPen &pen)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QCPGrid(QCPAxis *parentAxis)
virtual void draw(QCPPainter *painter)
void setSubGridVisible(bool visible)
void drawGridLines(QCPPainter *painter) const
An anchor of an item to which positions can be attached to.
virtual QPointF pixelPosition() const
void removeChildX(QCPItemPosition *pos)
QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1)
QCPAbstractItem * mParentItem
QSet< QCPItemPosition * > mChildrenY
QCustomPlot * mParentPlot
friend class QCPItemPosition
void removeChildY(QCPItemPosition *pos)
virtual QCPItemPosition * toQCPItemPosition()
QSet< QCPItemPosition * > mChildrenX
void addChildX(QCPItemPosition *pos)
void addChildY(QCPItemPosition *pos)
void setSelectedPen(const QPen &pen)
QCPItemBracket(QCustomPlot *parentPlot)
BracketStyle style() const
void setStyle(BracketStyle style)
QCPItemPosition *const left
@ bsSquare
A brace with angled edges.
@ bsRound
A brace with round edges.
virtual void draw(QCPPainter *painter)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setPen(const QPen &pen)
virtual QPointF anchorPixelPosition(int anchorId) const
QCPItemPosition *const right
void setLength(double length)
virtual ~QCPItemBracket()
QCPItemPosition *const startDir
void setPen(const QPen &pen)
QCPItemPosition *const start
void setHead(const QCPLineEnding &head)
QCPItemPosition *const end
void setSelectedPen(const QPen &pen)
virtual void draw(QCPPainter *painter)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPLineEnding head() const
QCPItemPosition *const endDir
QCPLineEnding tail() const
void setTail(const QCPLineEnding &tail)
QCPItemCurve(QCustomPlot *parentPlot)
virtual QPointF anchorPixelPosition(int anchorId) const
QCPItemPosition *const bottomRight
QCPItemPosition *const topLeft
virtual ~QCPItemEllipse()
void setBrush(const QBrush &brush)
void setSelectedPen(const QPen &pen)
QCPItemEllipse(QCustomPlot *parentPlot)
void setSelectedBrush(const QBrush &brush)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPItemAnchor *const center
void setPen(const QPen &pen)
virtual void draw(QCPPainter *painter)
QCPItemLine(QCustomPlot *parentPlot)
virtual void draw(QCPPainter *painter)
QCPItemPosition *const start
void setSelectedPen(const QPen &pen)
QCPItemPosition *const end
void setPen(const QPen &pen)
QCPLineEnding head() const
QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const
QCPLineEnding tail() const
void setTail(const QCPLineEnding &tail)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setHead(const QCPLineEnding &head)
virtual QPointF anchorPixelPosition(int anchorId) const
QCPItemPosition *const bottomRight
bool mScaledPixmapInvalidated
QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const
Qt::AspectRatioMode aspectRatioMode() const
void setPixmap(const QPixmap &pixmap)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void draw(QCPPainter *painter)
void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false)
Qt::AspectRatioMode mAspectRatioMode
QCPItemPixmap(QCustomPlot *parentPlot)
void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation)
Qt::TransformationMode transformationMode() const
Qt::TransformationMode mTransformationMode
void setPen(const QPen &pen)
QCPItemPosition *const topLeft
void setSelectedPen(const QPen &pen)
Manages the position of an item.
QCPItemAnchor * mParentAnchorX
QCPItemAnchor * parentAnchor() const
void setAxisRect(QCPAxisRect *axisRect)
void setTypeX(PositionType type)
void setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis)
QPointer< QCPAxis > mKeyAxis
QCPAxis * valueAxis() const
virtual QPointF pixelPosition() const
PositionType mPositionTypeY
QPointer< QCPAxis > mValueAxis
QCPItemAnchor * parentAnchorX() const
QPointer< QCPAxisRect > mAxisRect
void setPixelPosition(const QPointF &pixelPosition)
QCPAxis * keyAxis() const
QCPItemAnchor * parentAnchorY() const
void setType(PositionType type)
void setCoords(double key, double value)
PositionType type() const
bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
void setTypeY(PositionType type)
virtual ~QCPItemPosition()
bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
PositionType mPositionTypeX
QCPAxisRect * axisRect() const
QCPItemAnchor * mParentAnchorY
virtual void draw(QCPPainter *painter)
QCPItemRect(QCustomPlot *parentPlot)
void setPen(const QPen &pen)
void setSelectedPen(const QPen &pen)
QCPItemPosition *const bottomRight
virtual QPointF anchorPixelPosition(int anchorId) const
QCPItemPosition *const topLeft
void setBrush(const QBrush &brush)
void setSelectedBrush(const QBrush &brush)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual ~QCPItemStraightLine()
virtual void draw(QCPPainter *painter)
QCPItemPosition *const point1
QCPItemStraightLine(QCustomPlot *parentPlot)
void setSelectedPen(const QPen &pen)
QCPItemPosition *const point2
void setPen(const QPen &pen)
QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const
void setSelectedFont(const QFont &font)
Qt::Alignment positionAlignment() const
void setBrush(const QBrush &brush)
QCPItemPosition *const position
void setSelectedPen(const QPen &pen)
void setText(const QString &text)
void setRotation(double degrees)
QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const
void setSelectedBrush(const QBrush &brush)
Qt::Alignment mPositionAlignment
QCPItemText(QCustomPlot *parentPlot)
void setPositionAlignment(Qt::Alignment alignment)
virtual void draw(QCPPainter *painter)
void setFont(const QFont &font)
void setPen(const QPen &pen)
void setColor(const QColor &color)
virtual QPointF anchorPixelPosition(int anchorId) const
void setTextAlignment(Qt::Alignment alignment)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Qt::Alignment mTextAlignment
void setSelectedColor(const QColor &color)
void setPadding(const QMargins &padding)
void setSelectedBrush(const QBrush &brush)
void setBrush(const QBrush &brush)
@ tsPlus
A plus shaped crosshair with limited size.
@ tsNone
The tracer is not visible.
void setStyle(TracerStyle style)
void setGraphKey(double key)
void setInterpolating(bool enabled)
virtual void draw(QCPPainter *painter)
QCPItemTracer(QCustomPlot *parentPlot)
void setSelectedPen(const QPen &pen)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setSize(double size)
QCPItemPosition *const position
void setGraph(QCPGraph *graph)
void setPen(const QPen &pen)
TracerStyle style() const
A layer that may contain objects, to control the rendering order.
QList< QCPLayerable * > mChildren
QList< QCPLayerable * > children() const
QCustomPlot * parentPlot() const
void addChild(QCPLayerable *layerable, bool prepend)
QCPLayer(QCustomPlot *parentPlot, const QString &layerName)
QCustomPlot * mParentPlot
void setMode(LayerMode mode)
QWeakPointer< QCPAbstractPaintBuffer > mPaintBuffer
void draw(QCPPainter *painter)
void setVisible(bool visible)
void removeChild(QCPLayerable *layerable)
Base class for all drawable objects.
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const =0
QCustomPlot * mParentPlot
virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details)
QCustomPlot * parentPlot() const
virtual void wheelEvent(QWheelEvent *event)
void setAntialiased(bool enabled)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0)
void initializeParentPlot(QCustomPlot *parentPlot)
virtual QCP::Interaction selectionCategory() const
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
void setParentLayerable(QCPLayerable *parentLayerable)
QCPLayerable * parentLayerable() const
bool realVisibility() const
Q_SLOT bool setLayer(QCPLayer *layer)
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
void layerChanged(QCPLayer *newLayer)
void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const
virtual QRect clipRect() const
virtual void draw(QCPPainter *painter)=0
virtual void deselectEvent(bool *selectionStateChanged)
QPointer< QCPLayerable > mParentLayerable
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details)
bool moveToLayer(QCPLayer *layer, bool prepend)
The abstract base class for all objects that form the layout system.
virtual int calculateAutoMargin(QCP::MarginSide side)
void setMinimumMargins(const QMargins &margins)
@ scrInnerRect
Minimum/Maximum size constraints apply to inner rect.
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
@ upMargins
Phase in which the margins are calculated and set.
virtual ~QCPLayoutElement()
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
QHash< QCP::MarginSide, QCPMarginGroup * > mMarginGroups
void setSizeConstraintRect(SizeConstraintRect constraintRect)
void setOuterRect(const QRect &rect)
virtual QSize minimumOuterSizeHint() const
QCPLayout * layout() const
void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group)
void setMinimumSize(const QSize &size)
QSize minimumSize() const
SizeConstraintRect sizeConstraintRect() const
void setMaximumSize(const QSize &size)
virtual void layoutChanged()
virtual QList< QCPLayoutElement * > elements(bool recursive) const
QCPLayoutElement(QCustomPlot *parentPlot=0)
QCPMarginGroup * marginGroup(QCP::MarginSide side) const
void setMargins(const QMargins &margins)
virtual void update(UpdatePhase phase)
QCPLayout * mParentLayout
SizeConstraintRect mSizeConstraintRect
void setAutoMargins(QCP::MarginSides sides)
virtual QSize maximumOuterSizeHint() const
QCP::MarginSides mAutoMargins
QSize maximumSize() const
A layout that arranges child elements in a grid.
virtual void updateLayout()
void insertColumn(int newIndex)
void setRowStretchFactors(const QList< double > &factors)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
void setColumnSpacing(int pixels)
void insertRow(int newIndex)
void getMinimumRowColSizes(QVector< int > *minColWidths, QVector< int > *minRowHeights) const
void indexToRowCol(int index, int &row, int &column) const
QCPLayoutElement * element(int row, int column) const
virtual bool take(QCPLayoutElement *element)
int rowColToIndex(int row, int column) const
void setColumnStretchFactors(const QList< double > &factors)
FillOrder fillOrder() const
virtual int elementCount() const
void setRowStretchFactor(int row, double factor)
virtual QSize minimumOuterSizeHint() const
void expandTo(int newRowCount, int newColumnCount)
QList< QList< QCPLayoutElement * > > mElements
virtual QCPLayoutElement * elementAt(int index) const
void getMaximumRowColSizes(QVector< int > *maxColWidths, QVector< int > *maxRowHeights) const
QList< double > mColumnStretchFactors
void setRowSpacing(int pixels)
bool hasElement(int row, int column)
virtual QSize maximumOuterSizeHint() const
virtual QCPLayoutElement * takeAt(int index)
bool addElement(int row, int column, QCPLayoutElement *element)
void setColumnStretchFactor(int column, double factor)
QList< double > mRowStretchFactors
void setFillOrder(FillOrder order, bool rearrange=true)
A layout that places child elements aligned to the border or arbitrarily positioned.
virtual int elementCount() const
QList< QCPLayoutElement * > mElements
QList< InsetPlacement > mInsetPlacement
QList< Qt::Alignment > mInsetAlignment
Qt::Alignment insetAlignment(int index) const
void setInsetAlignment(int index, Qt::Alignment alignment)
void setInsetPlacement(int index, InsetPlacement placement)
InsetPlacement insetPlacement(int index) const
virtual void updateLayout()
virtual ~QCPLayoutInset()
virtual QCPLayoutElement * elementAt(int index) const
virtual bool take(QCPLayoutElement *element)
QList< QRectF > mInsetRect
void setInsetRect(int index, const QRectF &rect)
QRectF insetRect(int index) const
void addElement(QCPLayoutElement *element, Qt::Alignment alignment)
virtual QCPLayoutElement * takeAt(int index)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
The abstract base class for layouts.
virtual void updateLayout()
virtual void update(UpdatePhase phase)
virtual int elementCount() const =0
QVector< int > getSectionSizes(QVector< int > maxSizes, QVector< int > minSizes, QVector< double > stretchFactors, int totalSize) const
void releaseElement(QCPLayoutElement *el)
virtual QCPLayoutElement * takeAt(int index)=0
bool remove(QCPLayoutElement *element)
static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el)
virtual bool take(QCPLayoutElement *element)=0
virtual QList< QCPLayoutElement * > elements(bool recursive) const
static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el)
void sizeConstraintsChanged() const
void adoptElement(QCPLayoutElement *el)
virtual QCPLayoutElement * elementAt(int index) const =0
Manages a legend inside a QCustomPlot.
SelectableParts mSelectableParts
int iconTextPadding() const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QPen getBorderPen() const
Q_SLOT void setSelectedParts(const SelectableParts &selectedParts)
void setSelectedBorderPen(const QPen &pen)
void setIconBorderPen(const QPen &pen)
bool addItem(QCPAbstractLegendItem *item)
SelectableParts selectedParts() const
virtual void draw(QCPPainter *painter)
void setBrush(const QBrush &brush)
bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
virtual void deselectEvent(bool *selectionStateChanged)
@ spLegendBox
0x001 The legend box (frame)
QPen iconBorderPen() const
void setIconTextPadding(int padding)
QColor mSelectedTextColor
QPen mSelectedIconBorderPen
void setSelectedTextColor(const QColor &color)
void selectionChanged(QCPLegend::SelectableParts parts)
void setBorderPen(const QPen &pen)
void setSelectedBrush(const QBrush &brush)
void selectableChanged(QCPLegend::SelectableParts parts)
void setIconSize(const QSize &size)
virtual QCP::Interaction selectionCategory() const
SelectableParts mSelectedParts
QCPPlottableLegendItem * itemWithPlottable(const QCPAbstractPlottable *plottable) const
Q_SLOT void setSelectableParts(const SelectableParts &selectableParts)
void setFont(const QFont &font)
void setSelectedFont(const QFont &font)
QList< QCPAbstractLegendItem * > selectedItems() const
bool removeItem(int index)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPAbstractLegendItem * item(int index) const
SelectableParts selectableParts() const
bool hasItem(QCPAbstractLegendItem *item) const
QPen selectedIconBorderPen() const
void setSelectedIconBorderPen(const QPen &pen)
void setTextColor(const QColor &color)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
Handles the different ending decorations for line-like items.
EndingStyle style() const
double boundingDistance() const
void setWidth(double width)
void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const
void setStyle(EndingStyle style)
void setInverted(bool inverted)
@ esDiamond
A filled diamond (45 degrees rotated square)
@ esBar
A bar perpendicular to the line.
@ esNone
No ending decoration.
@ esLineArrow
A non-filled arrow head with open back.
@ esSpikeArrow
A filled arrow head with an indented back.
@ esSquare
A filled square.
double realLength() const
void setLength(double length)
A margin group allows synchronization of margin sides if working with multiple layout elements.
void removeChild(QCP::MarginSide side, QCPLayoutElement *element)
QList< QCPLayoutElement * > elements(QCP::MarginSide side) const
QHash< QCP::MarginSide, QList< QCPLayoutElement * > > mChildren
virtual ~QCPMarginGroup()
QCPMarginGroup(QCustomPlot *parentPlot)
void addChild(QCP::MarginSide side, QCPLayoutElement *element)
virtual int commonMargin(QCP::MarginSide side) const
A paint buffer based on QPixmap, using software raster rendering.
virtual QCPPainter * startPainting()
virtual ~QCPPaintBufferPixmap()
virtual void draw(QCPPainter *painter) const
virtual void reallocateBuffer()
void clear(const QColor &color)
QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio)
QPainter subclass used internally.
bool begin(QPaintDevice *device)
void drawLine(const QLineF &line)
QStack< bool > mAntialiasingStack
bool antialiasing() const
void setModes(PainterModes modes)
void setAntialiasing(bool enabled)
PainterModes modes() const
void setMode(PainterMode mode, bool enabled=true)
void setPen(const QPen &pen)
Defines an abstract interface for one-dimensional plottables.
virtual int dataCount() const =0
virtual double dataMainKey(int index) const =0
virtual double dataMainValue(int index) const =0
A legend item representing a plottable with an icon and the plottable name.
QColor getTextColor() const
virtual void draw(QCPPainter *painter)
QCPAbstractPlottable * mPlottable
QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable)
virtual QSize minimumOuterSizeHint() const
QPen getIconBorderPen() const
Represents the range an axis is encompassing.
void expand(const QCPRange &otherRange)
QCPRange bounded(double lowerBound, double upperBound) const
static const double maxRange
QCPRange sanitizedForLogScale() const
QCPRange sanitizedForLinScale() const
static const double minRange
QCPRange expanded(const QCPRange &otherRange) const
static bool validRange(double lower, double upper)
bool contains(double value) const
Represents the visual appearance of scatter points.
bool isPenDefined() const
void setPixmap(const QPixmap &pixmap)
void setBrush(const QBrush &brush)
void setPen(const QPen &pen)
void setShape(ScatterShape shape)
void setFromOther(const QCPScatterStyle &other, ScatterProperties properties)
@ spShape
0x08 The shape property, see setShape
@ spSize
0x04 The size property, see setSize
@ spPen
0x01 The pen property, see setPen
@ spBrush
0x02 The brush property, see setBrush
void drawShape(QCPPainter *painter, const QPointF &pos) const
void setCustomPath(const QPainterPath &customPath)
void setSize(double size)
@ ssPlus
\enumimage{ssPlus.png} a plus
@ ssCircle
\enumimage{ssCircle.png} a circle
@ ssSquare
\enumimage{ssSquare.png} a square
@ ssCross
\enumimage{ssCross.png} a cross
@ ssDiamond
\enumimage{ssDiamond.png} a diamond
QPainterPath customPath() const
ScatterShape shape() const
void applyTo(QCPPainter *painter, const QPen &defaultPen) const
void setBracketStyle(BracketStyle style)
virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection)
void setBracketWidth(int width)
void setBracketBrush(const QBrush &brush)
virtual void drawBracket(QCPPainter *painter, int direction) const
BracketStyle mBracketStyle
void setTangentToData(bool enabled)
QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const
@ bsSquareBracket
A square bracket is drawn.
double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const
void setBracketPen(const QPen &pen)
QCPSelectionDecoratorBracket()
void setTangentAverage(int pointCount)
virtual ~QCPSelectionDecoratorBracket()
void setBracketHeight(int height)
Controls how a plottable's data selection is drawn.
QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const
void applyBrush(QCPPainter *painter) const
QCPAbstractPlottable * mPlottable
virtual void copyFrom(const QCPSelectionDecorator *other)
virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection)
QCPScatterStyle mScatterStyle
void applyPen(QCPPainter *painter) const
void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties)
QCPScatterStyle scatterStyle() const
void setBrush(const QBrush &brush)
QCPScatterStyle::ScatterProperties usedScatterProperties() const
virtual ~QCPSelectionDecorator()
void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen)
void setPen(const QPen &pen)
QCPScatterStyle::ScatterProperties mUsedScatterProperties
virtual bool registerWithPlottable(QCPAbstractPlottable *plottable)
Provides rect/rubber-band data selection and range zoom interaction.
void accepted(const QRect &rect, QMouseEvent *event)
virtual void keyPressEvent(QKeyEvent *event)
void changed(const QRect &rect, QMouseEvent *event)
QCPRange range(const QCPAxis *axis) const
virtual void startSelection(QMouseEvent *event)
virtual void endSelection(QMouseEvent *event)
void started(QMouseEvent *event)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
virtual void moveSelection(QMouseEvent *event)
void setBrush(const QBrush &brush)
void setPen(const QPen &pen)
QCPSelectionRect(QCustomPlot *parentPlot)
virtual ~QCPSelectionRect()
void canceled(const QRect &rect, QInputEvent *event)
virtual void draw(QCPPainter *painter)
Holds the data of one single data point for QCPStatisticalBox.
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
void setData(QSharedPointer< QCPStatisticalBoxDataContainer > data)
QVector< double > outliers() const
void setWidth(double width)
void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const
QVector< QLineF > getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void setWhiskerPen(const QPen &pen)
void setWhiskerAntialiased(bool enabled)
void setMedianPen(const QPen &pen)
QSharedPointer< QCPStatisticalBoxDataContainer > data() const
virtual void draw(QCPPainter *painter)
QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis)
void addData(const QVector< double > &keys, const QVector< double > &minimum, const QVector< double > &lowerQuartile, const QVector< double > &median, const QVector< double > &upperQuartile, const QVector< double > &maximum, bool alreadySorted=false)
QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const
void setWhiskerBarPen(const QPen &pen)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
void setOutlierStyle(const QCPScatterStyle &style)
void setWhiskerWidth(double width)
QCPScatterStyle mOutlierStyle
QCPScatterStyle outlierStyle() const
virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const
QVector< QLineF > getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const
double lowerQuartile() const
double upperQuartile() const
void setFont(const QFont &font)
void setSelectedFont(const QFont &font)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
virtual void deselectEvent(bool *selectionStateChanged)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Q_SLOT void setSelectable(bool selectable)
virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details)
void selectionChanged(bool selected)
void setTextColor(const QColor &color)
QColor mainTextColor() const
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
virtual void draw(QCPPainter *painter)
virtual QSize minimumOuterSizeHint() const
void doubleClicked(QMouseEvent *event)
void setTextFlags(int flags)
Q_SLOT void setSelected(bool selected)
void setSelectedTextColor(const QColor &color)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void setText(const QString &text)
void selectableChanged(bool selectable)
void clicked(QMouseEvent *event)
QColor mSelectedTextColor
QCPTextElement(QCustomPlot *parentPlot)
virtual QSize maximumOuterSizeHint() const
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details)
Represents two doubles as a mathematical 2D vector.
QCPVector2D perpendicular() const
double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const
double dot(const QCPVector2D &vec) const
QCPVector2D & operator-=(const QCPVector2D &vector)
QCPVector2D normalized() const
double lengthSquared() const
QCPVector2D & operator+=(const QCPVector2D &vector)
QCPVector2D & operator*=(double factor)
double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const
QCPVector2D & operator/=(double divisor)
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
QCPLayer * currentLayer() const
void drawBackground(QCPPainter *painter)
QPixmap mScaledBackgroundPixmap
QCPLayer * layer(const QString &name) const
void setSelectionRect(QCPSelectionRect *selectionRect)
Qt::KeyboardModifier mMultiSelectModifier
virtual QSize minimumSizeHint() const
QCPLayerable * layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const
QList< QCPGraph * > mGraphs
QList< QCPAxisRect * > axisRects() const
QCPAbstractItem * item() const
void setBackground(const QPixmap &pm)
virtual void resizeEvent(QResizeEvent *event)
void setBufferDevicePixelRatio(double ratio)
void toPainter(QCPPainter *painter, int width=0, int height=0)
QPointer< QCPLayerable > mMouseEventLayerable
QCP::AntialiasedElements mNotAntialiasedElements
virtual void paintEvent(QPaintEvent *event)
const QCP::Interactions interactions() const
QVariant mMouseSignalLayerableDetails
QCPAbstractPlottable * plottable(int index)
void setBackgroundScaled(bool scaled)
void setPlottingHint(QCP::PlottingHint hint, bool enabled=true)
void setViewport(const QRect &rect)
bool removeLayer(QCPLayer *layer)
void setInteraction(const QCP::Interaction &interaction, bool enabled=true)
QCustomPlot(QWidget *parent=0)
QCPSelectionRect * mSelectionRect
QCPAxisRect * axisRectAt(const QPointF &pos) const
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
void setSelectionTolerance(int pixels)
void selectionChangedByUser()
virtual QSize sizeHint() const
int selectionTolerance() const
virtual Q_SLOT void processRectZoom(QRect rect, QMouseEvent *event)
QList< QSharedPointer< QCPAbstractPaintBuffer > > mPaintBuffers
void setInteractions(const QCP::Interactions &interactions)
int plottableCount() const
QCP::AntialiasedElements antialiasedElements() const
double mBufferDevicePixelRatio
void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
virtual void updateLayout()
QCPGraph * addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0)
virtual void mouseReleaseEvent(QMouseEvent *event)
bool hasPlottable(QCPAbstractPlottable *plottable) const
bool setCurrentLayer(const QString &name)
void mouseMove(QMouseEvent *event)
QList< QCPAbstractPlottable * > selectedPlottables() const
QCP::AntialiasedElements notAntialiasedElements() const
@ limAbove
Layer is inserted above other layer.
bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
void setNoAntialiasingOnDrag(bool enabled)
QList< QCPAbstractItem * > mItems
void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
virtual void wheelEvent(QWheelEvent *event)
void setOpenGl(bool enabled, int multisampling=16)
QList< QCPAxis * > selectedAxes() const
void updateLayerIndices() const
void setSelectionRectMode(QCP::SelectionRectMode mode)
void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event)
virtual void axisRemoved(QCPAxis *axis)
int axisRectCount() const
void setMultiSelectModifier(Qt::KeyboardModifier modifier)
bool removeGraph(QCPGraph *graph)
QCPAbstractPaintBuffer * createPaintBuffer()
void setPlottingHints(const QCP::PlottingHints &hints)
void mouseDoubleClick(QMouseEvent *event)
virtual void legendRemoved(QCPLegend *legend)
Q_SLOT void deselectAll()
QCP::PlottingHints mPlottingHints
QCP::AntialiasedElements mAntialiasedElements
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint)
QPixmap toPixmap(int width=0, int height=0, double scale=1.0)
QList< QCPAbstractPlottable * > mPlottables
bool mAutoAddPlottableToLegend
bool mOpenGlCacheLabelsBackup
Qt::AspectRatioMode mBackgroundScaledMode
QCPLayoutGrid * mPlotLayout
virtual void mousePressEvent(QMouseEvent *event)
QCP::SelectionRectMode mSelectionRectMode
void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
QCPAbstractItem * itemAt(const QPointF &pos, bool onlySelectable=false) const
virtual Q_SLOT void processRectSelection(QRect rect, QMouseEvent *event)
virtual Q_SLOT void processPointSelection(QMouseEvent *event)
virtual void mouseMoveEvent(QMouseEvent *event)
void mouseWheel(QWheelEvent *event)
void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event)
bool mNoAntialiasingOnDrag
QList< QCPLegend * > selectedLegends() const
void mouseRelease(QMouseEvent *event)
QList< QCPLayerable * > layerableListAt(const QPointF &pos, bool onlySelectable, QList< QVariant > *selectionDetails=0) const
bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
bool noAntialiasingOnDrag() const
void mousePress(QMouseEvent *event)
QCPAbstractPlottable * plottableAt(const QPointF &pos, bool onlySelectable=false) const
bool registerGraph(QCPGraph *graph)
QList< QCPLayer * > mLayers
QList< QCPGraph * > selectedGraphs() const
bool hasInvalidatedPaintBuffers()
bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove)
bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString())
QVariant mMouseEventLayerableDetails
QCP::Interactions mInteractions
bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
virtual void draw(QCPPainter *painter)
QCPSelectionRect * selectionRect() const
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false)
void setAutoAddPlottableToLegend(bool on)
QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup
QCPAbstractPlottable * plottable()
QPointer< QCPLayerable > mMouseSignalLayerable
bool removeItem(QCPAbstractItem *item)
void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements)
void itemClick(QCPAbstractItem *item, QMouseEvent *event)
bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
QCPAxisRect * axisRect(int index=0) const
bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove)
QPixmap mBackgroundPixmap
bool registerPlottable(QCPAbstractPlottable *plottable)
void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true)
bool hasItem(QCPAbstractItem *item) const
bool removePlottable(QCPAbstractPlottable *plottable)
void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event)
void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements)
QCPLayoutElement * layoutElementAt(const QPointF &pos) const
bool registerItem(QCPAbstractItem *item)
void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true)
QList< QCPAbstractItem * > selectedItems() const
bool isInvalidData(double value)
int getMarginValue(const QMargins &margins, QCP::MarginSide side)
@ ruDotsPerMeter
Resolution is given in dots per meter (dpm)
@ ruDotsPerInch
Resolution is given in dots per inch (DPI/PPI)
@ msRight
0x02 right margin
@ msBottom
0x08 bottom margin
@ stNone
The plottable is not selectable.
@ stSingleData
One individual data point can be selected at a time.
@ aeAxes
0x0001 Axis base line and tick marks
@ aeItems
0x0040 Main lines of items
@ aeLegendItems
0x0010 Legend items
@ aePlottables
0x0020 Main lines of plottables
@ aeNone
0x0000 No elements
@ aeSubGrid
0x0004 Sub grid lines
@ aeAll
0xFFFF All elements
@ aeGrid
0x0002 Grid lines
@ aeLegend
0x0008 Legend box
void setMarginValue(QMargins &margins, QCP::MarginSide side, int value)
@ sdNegative
The negative sign domain, i.e. numbers smaller than zero.
@ sdPositive
The positive sign domain, i.e. numbers greater than zero.
@ sdBoth
Both sign domains, including zero, i.e. all numbers.
static const std::string path
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
constexpr Rgb black(0, 0, 0)
constexpr Rgb white(MAX, MAX, MAX)
constexpr Rgb blue(0, 0, MAX)