58 mIsAntialiasing(false)
75 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. 77 setRenderHint(QPainter::NonCosmeticDefaultPen);
93 QPainter::setPen(pen);
107 QPainter::setPen(color);
121 QPainter::setPen(penStyle);
137 QPainter::drawLine(line);
139 QPainter::drawLine(line.toLine());
150 setRenderHint(QPainter::Antialiasing, enabled);
159 translate(-0.5, -0.5);
186 bool result = QPainter::begin(device);
187 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. 189 setRenderHint(QPainter::NonCosmeticDefaultPen);
201 if (!enabled &&
mModes.testFlag(mode))
203 else if (enabled && !
mModes.testFlag(mode))
234 qDebug() << Q_FUNC_INFO <<
"Unbalanced save/restore";
244 if (qFuzzyIsNull(pen().widthF()))
539 painter->setBrush(
mBrush);
566 painter->
drawLine(QPointF(x, y), QPointF(x+0.0001, y));
571 painter->
drawLine(QLineF(x-w, y-w, x+w, y+w));
572 painter->
drawLine(QLineF(x-w, y+w, x+w, y-w));
577 painter->
drawLine(QLineF(x-w, y, x+w, y));
578 painter->
drawLine(QLineF( x, y+w, x, y-w));
583 painter->drawEllipse(QPointF(x , y), w, w);
588 QBrush b = painter->brush();
589 painter->setBrush(painter->pen().color());
590 painter->drawEllipse(QPointF(x , y), w, w);
591 painter->setBrush(b);
596 painter->drawRect(QRectF(x-w, y-w,
mSize,
mSize));
601 painter->
drawLine(QLineF(x-w, y, x, y-w));
602 painter->
drawLine(QLineF( x, y-w, x+w, y));
603 painter->
drawLine(QLineF(x+w, y, x, y+w));
604 painter->
drawLine(QLineF( x, y+w, x-w, y));
609 painter->
drawLine(QLineF(x-w, y, x+w, y));
610 painter->
drawLine(QLineF( x, y+w, x, y-w));
611 painter->
drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707));
612 painter->
drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707));
617 painter->
drawLine(QLineF(x-w, y+0.755*w, x+w, y+0.755*w));
618 painter->
drawLine(QLineF(x+w, y+0.755*w, x, y-0.977*w));
619 painter->
drawLine(QLineF( x, y-0.977*w, x-w, y+0.755*w));
624 painter->
drawLine(QLineF(x-w, y-0.755*w, x+w, y-0.755*w));
625 painter->
drawLine(QLineF(x+w, y-0.755*w, x, y+0.977*w));
626 painter->
drawLine(QLineF( x, y+0.977*w, x-w, y-0.755*w));
631 painter->
drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95));
632 painter->
drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w));
633 painter->drawRect(QRectF(x-w, y-w,
mSize,
mSize));
638 painter->
drawLine(QLineF(x-w, y, x+w*0.95, y));
639 painter->
drawLine(QLineF( x, y+w, x, y-w));
640 painter->drawRect(QRectF(x-w, y-w,
mSize,
mSize));
645 painter->
drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670));
646 painter->
drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707));
647 painter->drawEllipse(QPointF(x, y), w, w);
652 painter->
drawLine(QLineF(x-w, y, x+w, y));
653 painter->
drawLine(QLineF( x, y+w, x, y-w));
654 painter->drawEllipse(QPointF(x, y), w, w);
659 painter->
drawLine(QLineF(x, y-w, x, y+w));
660 painter->
drawLine(QLineF(x, y, x-w*0.707, y+w*0.707));
661 painter->
drawLine(QLineF(x, y, x+w*0.707, y+w*0.707));
662 painter->drawEllipse(QPointF(x, y), w, w);
672 QTransform oldTransform = painter->transform();
673 painter->translate(x, y);
676 painter->setTransform(oldTransform);
757 mParentPlot(parentPlot),
777 qDebug() << Q_FUNC_INFO <<
"The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand.";
812 qDebug() << Q_FUNC_INFO <<
"layerable is already child of this layer" <<
reinterpret_cast<quintptr
>(layerable);
827 qDebug() << Q_FUNC_INFO <<
"layerable is not child of this layer" <<
reinterpret_cast<quintptr
>(layerable);
940 mParentLayerable(parentLayerable),
946 if (targetLayer.isEmpty())
949 qDebug() << Q_FUNC_INFO <<
"setting QCPlayerable initial layer to" << targetLayer <<
"failed.";
992 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
1000 qDebug() << Q_FUNC_INFO <<
"there is no layer with name" << layerName;
1071 Q_UNUSED(onlySelectable)
1097 qDebug() << Q_FUNC_INFO <<
"called with mParentPlot already initialized";
1102 qDebug() << Q_FUNC_INFO <<
"called with parentPlot zero";
1136 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
1141 qDebug() << Q_FUNC_INFO <<
"layer" << layer->
name() <<
"is not in same QCustomPlot as this layerable";
1191 Q_UNUSED(parentPlot)
1260 Q_UNUSED(selectionStateChanged)
1277 Q_UNUSED(selectionStateChanged)
1382 result.
expand(otherRange);
1400 double rangeFac = 1e-3;
1405 if (sanitizedRange.
lower == 0.0 && sanitizedRange.
upper != 0.0)
1408 if (rangeFac < sanitizedRange.
upper*rangeFac)
1409 sanitizedRange.
lower = rangeFac;
1411 sanitizedRange.
lower = sanitizedRange.
upper*rangeFac;
1413 else if (sanitizedRange.
lower != 0.0 && sanitizedRange.
upper == 0.0)
1416 if (-rangeFac > sanitizedRange.
lower*rangeFac)
1417 sanitizedRange.
upper = -rangeFac;
1419 sanitizedRange.
upper = sanitizedRange.
lower*rangeFac;
1420 }
else if (sanitizedRange.
lower < 0 && sanitizedRange.
upper > 0)
1423 if (-sanitizedRange.
lower > sanitizedRange.
upper)
1426 if (-rangeFac > sanitizedRange.
lower*rangeFac)
1427 sanitizedRange.
upper = -rangeFac;
1429 sanitizedRange.
upper = sanitizedRange.
lower*rangeFac;
1433 if (rangeFac < sanitizedRange.
upper*rangeFac)
1434 sanitizedRange.
lower = rangeFac;
1436 sanitizedRange.
lower = sanitizedRange.
upper*rangeFac;
1440 return sanitizedRange;
1451 return sanitizedRange;
1565 QObject(parentPlot),
1566 mParentPlot(parentPlot)
1585 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement*> > it(
mChildren);
1586 while (it.hasNext())
1589 if (!it.value().isEmpty())
1602 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement*> > it(
mChildren);
1603 while (it.hasNext())
1606 const QList<QCPLayoutElement*>
elements = it.value();
1607 for (
int i=elements.size()-1; i>=0; --i)
1608 elements.at(i)->setMarginGroup(it.key(), 0);
1627 for (
int i=0; i<elements.size(); ++i)
1629 if (!elements.at(i)->autoMargins().testFlag(side))
1631 int m = qMax(elements.at(i)->calculateAutoMargin(side),
QCP::getMarginValue(elements.at(i)->minimumMargins(), side));
1649 qDebug() << Q_FUNC_INFO <<
"element is already child of this margin group side" <<
reinterpret_cast<quintptr
>(element);
1660 if (!
mChildren[side].removeOne(element))
1661 qDebug() << Q_FUNC_INFO <<
"element is not child of this margin group side" <<
reinterpret_cast<quintptr
>(element);
1753 mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX),
1755 mOuterRect(0, 0, 0, 0),
1756 mMargins(0, 0, 0, 0),
1757 mMinimumMargins(0, 0, 0, 0),
1906 QVector<QCP::MarginSide> sideVector;
1912 for (
int i=0; i<sideVector.size(); ++i)
2005 return QList<QCPLayoutElement*>();
2032 qDebug() << Q_FUNC_INFO <<
"parent plot not defined";
2165 const int elCount = elementCount();
2166 for (
int i=0; i<elCount; ++i)
2176 const int c = elementCount();
2177 QList<QCPLayoutElement*> result;
2178 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) 2181 for (
int i=0; i<c; ++i)
2182 result.append(elementAt(i));
2185 for (
int i=0; i<c; ++i)
2188 result << result.at(i)->elements(recursive);
2250 for (
int i=elementCount()-1; i>=0; --i)
2268 if (QWidget *
w = qobject_cast<QWidget*>(parent()))
2269 w->updateGeometry();
2270 else if (
QCPLayout *l = qobject_cast<QCPLayout*>(parent()))
2271 l->sizeConstraintsChanged();
2309 el->setParent(
this);
2313 qDebug() << Q_FUNC_INFO <<
"Null element passed";
2335 qDebug() << Q_FUNC_INFO <<
"Null element passed";
2369 if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size())
2371 qDebug() << Q_FUNC_INFO <<
"Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors;
2372 return QVector<int>();
2374 if (stretchFactors.isEmpty())
2375 return QVector<int>();
2376 int sectionCount = stretchFactors.size();
2377 QVector<double> sectionSizes(sectionCount);
2380 for (
int i=0; i<sectionCount; ++i)
2381 minSizeSum += minSizes.at(i);
2382 if (totalSize < minSizeSum)
2385 for (
int i=0; i<sectionCount; ++i)
2387 stretchFactors[i] = minSizes.at(i);
2392 QList<int> minimumLockedSections;
2393 QList<int> unfinishedSections;
2394 for (
int i=0; i<sectionCount; ++i)
2395 unfinishedSections.append(i);
2396 double freeSize = totalSize;
2398 int outerIterations = 0;
2399 while (!unfinishedSections.isEmpty() && outerIterations < sectionCount*2)
2402 int innerIterations = 0;
2403 while (!unfinishedSections.isEmpty() && innerIterations < sectionCount*2)
2408 double nextMax = 1e12;
2409 for (
int i=0; i<unfinishedSections.size(); ++i)
2411 int secId = unfinishedSections.at(i);
2412 double hitsMaxAt = (maxSizes.at(secId)-sectionSizes.at(secId))/stretchFactors.at(secId);
2413 if (hitsMaxAt < nextMax)
2415 nextMax = hitsMaxAt;
2421 double stretchFactorSum = 0;
2422 for (
int i=0; i<unfinishedSections.size(); ++i)
2423 stretchFactorSum += stretchFactors.at(unfinishedSections.at(i));
2424 double nextMaxLimit = freeSize/stretchFactorSum;
2425 if (nextMax < nextMaxLimit)
2427 for (
int i=0; i<unfinishedSections.size(); ++i)
2429 sectionSizes[unfinishedSections.at(i)] += nextMax*stretchFactors.at(unfinishedSections.at(i));
2430 freeSize -= nextMax*stretchFactors.at(unfinishedSections.at(i));
2432 unfinishedSections.removeOne(nextId);
2435 for (
int i=0; i<unfinishedSections.size(); ++i)
2436 sectionSizes[unfinishedSections.at(i)] += nextMaxLimit*stretchFactors.at(unfinishedSections.at(i));
2437 unfinishedSections.clear();
2440 if (innerIterations == sectionCount*2)
2441 qDebug() << Q_FUNC_INFO <<
"Exceeded maximum expected inner iteration count, layouting aborted. Input was:" << maxSizes << minSizes << stretchFactors << totalSize;
2444 bool foundMinimumViolation =
false;
2445 for (
int i=0; i<sectionSizes.size(); ++i)
2447 if (minimumLockedSections.contains(i))
2449 if (sectionSizes.at(i) < minSizes.at(i))
2451 sectionSizes[i] = minSizes.at(i);
2452 foundMinimumViolation =
true;
2453 minimumLockedSections.append(i);
2456 if (foundMinimumViolation)
2458 freeSize = totalSize;
2459 for (
int i=0; i<sectionCount; ++i)
2461 if (!minimumLockedSections.contains(i))
2462 unfinishedSections.append(i);
2464 freeSize -= sectionSizes.at(i);
2467 for (
int i=0; i<unfinishedSections.size(); ++i)
2468 sectionSizes[unfinishedSections.at(i)] = 0;
2471 if (outerIterations == sectionCount*2)
2472 qDebug() << Q_FUNC_INFO <<
"Exceeded maximum expected outer iteration count, layouting aborted. Input was:" << maxSizes << minSizes << stretchFactors << totalSize;
2474 QVector<int> result(sectionCount);
2475 for (
int i=0; i<sectionCount; ++i)
2476 result[i] = qRound(sectionSizes.at(i));
2529 if (column >= 0 && column <
mElements.first().size())
2534 qDebug() << Q_FUNC_INFO <<
"Requested cell is empty. Row:" << row <<
"Column:" << column;
2536 qDebug() << Q_FUNC_INFO <<
"Invalid column. Row:" << row <<
"Column:" << column;
2538 qDebug() << Q_FUNC_INFO <<
"Invalid row. Row:" << row <<
"Column:" << column;
2588 qDebug() << Q_FUNC_INFO <<
"There is already an element in the specified row/column:" << row << column;
2590 qDebug() << Q_FUNC_INFO <<
"Can't add null element to row/column:" << row << column;
2626 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" << factor;
2628 qDebug() << Q_FUNC_INFO <<
"Invalid column:" << column;
2651 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" <<
mColumnStretchFactors.at(i);
2656 qDebug() << Q_FUNC_INFO <<
"Column count not equal to passed stretch factor count:" << factors;
2677 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" << factor;
2679 qDebug() << Q_FUNC_INFO <<
"Invalid row:" << row;
2702 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" <<
mRowStretchFactors.at(i);
2707 qDebug() << Q_FUNC_INFO <<
"Row count not equal to passed stretch factor count:" << factors;
2749 mElements.append(QList<QCPLayoutElement*>());
2753 int newColCount = qMax(
columnCount(), newColumnCount);
2756 while (
mElements.at(i).size() < newColCount)
2783 QList<QCPLayoutElement*> newRow;
2809 for (
int row=0; row<
rowCount(); ++row)
2816 QVector<int> minColWidths, minRowHeights, maxColWidths, maxRowHeights;
2826 int yOffset =
mRect.top();
2827 for (
int row=0; row<
rowCount(); ++row)
2831 int xOffset =
mRect.left();
2837 mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row)));
2867 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
2885 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
2887 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
2894 QList<QCPLayoutElement*> result;
2897 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) 2898 result.reserve(colC*rowC);
2900 for (
int row=0; row<rowC; ++row)
2902 for (
int col=0; col<colC; ++col)
2904 result.append(
mElements.at(row).at(col));
2909 int c = result.size();
2910 for (
int i=0; i<c; ++i)
2913 result << result.at(i)->elements(recursive);
2925 for (
int row=
rowCount()-1; row>=0; --row)
2927 bool hasElements =
false;
2948 bool hasElements =
false;
2949 for (
int row=0; row<
rowCount(); ++row)
2960 for (
int row=0; row<
rowCount(); ++row)
2969 QVector<int> minColWidths, minRowHeights;
2972 for (
int i=0; i<minColWidths.size(); ++i)
2973 result.rwidth() += minColWidths.at(i);
2974 for (
int i=0; i<minRowHeights.size(); ++i)
2975 result.rheight() += minRowHeights.at(i);
2984 QVector<int> maxColWidths, maxRowHeights;
2988 for (
int i=0; i<maxColWidths.size(); ++i)
2989 result.setWidth(qMin(result.width()+maxColWidths.at(i), QWIDGETSIZE_MAX));
2990 for (
int i=0; i<maxRowHeights.size(); ++i)
2991 result.setHeight(qMin(result.height()+maxRowHeights.at(i), QWIDGETSIZE_MAX));
3012 *minRowHeights = QVector<int>(
rowCount(), 0);
3013 for (
int row=0; row<
rowCount(); ++row)
3019 QSize minHint =
mElements.at(row).at(col)->minimumSizeHint();
3021 QSize
final(min.width() > 0 ? min.width() : minHint.width(), min.height() > 0 ? min.height() : minHint.height());
3022 if (minColWidths->at(col) <
final.width())
3023 (*minColWidths)[col] =
final.width();
3024 if (minRowHeights->at(row) <
final.height())
3025 (*minRowHeights)[row] =
final.height();
3045 *maxColWidths = QVector<int>(
columnCount(), QWIDGETSIZE_MAX);
3046 *maxRowHeights = QVector<int>(
rowCount(), QWIDGETSIZE_MAX);
3047 for (
int row=0; row<
rowCount(); ++row)
3053 QSize maxHint =
mElements.at(row).at(col)->maximumSizeHint();
3055 QSize
final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(), max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height());
3056 if (maxColWidths->at(col) >
final.width())
3057 (*maxColWidths)[col] =
final.width();
3058 if (maxRowHeights->at(row) >
final.height())
3059 (*maxRowHeights)[row] =
final.height();
3117 return mInsetPlacement.at(index);
3120 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3132 return mInsetAlignment.at(index);
3135 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3147 return mInsetRect.at(index);
3150 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3163 mInsetPlacement[index] = placement;
3165 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3179 mInsetAlignment[index] = alignment;
3181 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3198 mInsetRect[index] =
rect;
3200 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3209 QSize finalMinSize, finalMaxSize;
3210 QSize minSizeHint =
mElements.at(i)->minimumSizeHint();
3211 QSize maxSizeHint =
mElements.at(i)->maximumSizeHint();
3212 finalMinSize.setWidth(
mElements.at(i)->minimumSize().width() > 0 ?
mElements.at(i)->minimumSize().width() : minSizeHint.width());
3213 finalMinSize.setHeight(
mElements.at(i)->minimumSize().height() > 0 ?
mElements.at(i)->minimumSize().height() : minSizeHint.height());
3214 finalMaxSize.setWidth(
mElements.at(i)->maximumSize().width() < QWIDGETSIZE_MAX ?
mElements.at(i)->maximumSize().width() : maxSizeHint.width());
3215 finalMaxSize.setHeight(
mElements.at(i)->maximumSize().height() < QWIDGETSIZE_MAX ?
mElements.at(i)->maximumSize().height() : maxSizeHint.height());
3216 if (mInsetPlacement.at(i) == ipFree)
3218 insetRect = QRect(
rect().x()+
rect().width()*mInsetRect.at(i).x(),
3219 rect().y()+
rect().height()*mInsetRect.at(i).y(),
3220 rect().width()*mInsetRect.at(i).width(),
3221 rect().height()*mInsetRect.at(i).height());
3222 if (insetRect.size().width() < finalMinSize.width())
3223 insetRect.setWidth(finalMinSize.width());
3224 if (insetRect.size().height() < finalMinSize.height())
3225 insetRect.setHeight(finalMinSize.height());
3226 if (insetRect.size().width() > finalMaxSize.width())
3227 insetRect.setWidth(finalMaxSize.width());
3228 if (insetRect.size().height() > finalMaxSize.height())
3229 insetRect.setHeight(finalMaxSize.height());
3230 }
else if (mInsetPlacement.at(i) == ipBorderAligned)
3232 insetRect.setSize(finalMinSize);
3233 Qt::Alignment al = mInsetAlignment.at(i);
3234 if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(
rect().x());
3235 else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(
rect().x()+
rect().width());
3236 else insetRect.moveLeft(
rect().x()+
rect().width()*0.5-finalMinSize.width()*0.5);
3237 if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(
rect().y());
3238 else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(
rect().y()+
rect().height());
3239 else insetRect.moveTop(
rect().y()+
rect().height()*0.5-finalMinSize.height()*0.5);
3241 mElements.at(i)->setOuterRect(insetRect);
3254 if (index >= 0 && index <
mElements.size())
3267 mInsetPlacement.removeAt(index);
3268 mInsetAlignment.removeAt(index);
3269 mInsetRect.removeAt(index);
3273 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
3291 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
3293 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
3316 if (
mElements.at(i)->realVisibility() &&
mElements.at(i)->selectTest(pos, onlySelectable) >= 0)
3340 mInsetPlacement.append(ipBorderAligned);
3341 mInsetAlignment.append(alignment);
3342 mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4));
3345 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
3366 mInsetPlacement.append(ipFree);
3367 mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop);
3368 mInsetRect.append(rect);
3371 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
3543 QVector2D lengthVec(dir.normalized());
3544 if (lengthVec.isNull())
3545 lengthVec = QVector2D(1, 0);
3546 QVector2D widthVec(-lengthVec.y(), lengthVec.x());
3550 QPen penBackup = painter->pen();
3551 QBrush brushBackup = painter->brush();
3552 QPen miterPen = penBackup;
3553 miterPen.setJoinStyle(Qt::MiterJoin);
3554 QBrush brush(painter->pen().color(), Qt::SolidPattern);
3560 QPointF points[3] = {pos.toPointF(),
3561 (pos-lengthVec+widthVec).toPointF(),
3562 (pos-lengthVec-widthVec).toPointF()
3564 painter->
setPen(miterPen);
3565 painter->setBrush(brush);
3566 painter->drawConvexPolygon(points, 3);
3567 painter->setBrush(brushBackup);
3568 painter->
setPen(penBackup);
3573 QPointF points[4] = {pos.toPointF(),
3574 (pos-lengthVec+widthVec).toPointF(),
3575 (pos-lengthVec*0.8f).toPointF(),
3576 (pos-lengthVec-widthVec).toPointF()
3578 painter->
setPen(miterPen);
3579 painter->setBrush(brush);
3580 painter->drawConvexPolygon(points, 4);
3581 painter->setBrush(brushBackup);
3582 painter->
setPen(penBackup);
3587 QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(),
3589 (pos-lengthVec-widthVec).toPointF()
3591 painter->
setPen(miterPen);
3592 painter->drawPolyline(points, 3);
3593 painter->
setPen(penBackup);
3598 painter->setBrush(brush);
3599 painter->drawEllipse(pos.toPointF(),
mWidth*0.5,
mWidth*0.5);
3600 painter->setBrush(brushBackup);
3605 QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
3606 QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(),
3607 (pos-widthVecPerp-widthVec).toPointF(),
3608 (pos+widthVecPerp-widthVec).toPointF(),
3609 (pos+widthVecPerp+widthVec).toPointF()
3611 painter->
setPen(miterPen);
3612 painter->setBrush(brush);
3613 painter->drawConvexPolygon(points, 4);
3614 painter->setBrush(brushBackup);
3615 painter->
setPen(penBackup);
3620 QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
3621 QPointF points[4] = {(pos-widthVecPerp).toPointF(),
3622 (pos-widthVec).toPointF(),
3623 (pos+widthVecPerp).toPointF(),
3624 (pos+widthVec).toPointF()
3626 painter->
setPen(miterPen);
3627 painter->setBrush(brush);
3628 painter->drawConvexPolygon(points, 4);
3629 painter->setBrush(brushBackup);
3630 painter->
setPen(penBackup);
3635 painter->
drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF());
3640 painter->
drawLine((pos+widthVec).toPointF(), pos.toPointF());
3649 (pos-widthVec-lengthVec*0.2f*(
mInverted?-1:1)).toPointF());
3653 painter->
drawLine((pos+widthVec+lengthVec*0.2f*(
mInverted?-1:1)+dir.normalized()*qMax(1.0f, (
float)painter->pen().widthF())*0.5f).toPointF(),
3654 (pos-widthVec-lengthVec*0.2f*(
mInverted?-1:1)+dir.normalized()*qMax(1.0f, (
float)painter->pen().widthF())*0.5f).toPointF());
3668 draw(painter, pos, QVector2D(qCos(angle), qSin(angle)));
3695 QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis),
3696 mParentAxis(parentAxis)
3699 setParent(parentAxis);
3700 setPen(QPen(QColor(200,200,200), 0, Qt::DotLine));
3787 if (!
mParentAxis) { qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
return; }
3802 if (!
mParentAxis) { qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
return; }
3810 int zeroLineIndex = -1;
3816 for (
int i=lowTick; i <= highTick; ++i)
3830 for (
int i=lowTick; i <= highTick; ++i)
3832 if (i == zeroLineIndex)
continue;
3839 int zeroLineIndex = -1;
3845 for (
int i=lowTick; i <= highTick; ++i)
3859 for (
int i=lowTick; i <= highTick; ++i)
3861 if (i == zeroLineIndex)
continue;
3876 if (!
mParentAxis) { qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
return; }
4007 mOrientation(orientation(type)),
4008 mSelectableParts(spAxis | spTickLabels | spAxisLabel),
4009 mSelectedParts(spNone),
4010 mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
4011 mSelectedBasePen(QPen(Qt::blue, 2)),
4015 mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)),
4016 mLabelColor(Qt::black),
4017 mSelectedLabelColor(Qt::blue),
4020 mAutoTickLabels(true),
4021 mTickLabelType(ltNumber),
4023 mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)),
4024 mTickLabelColor(Qt::black),
4025 mSelectedTickLabelColor(Qt::blue),
4026 mDateTimeFormat(QLatin1String(
"hh:mm:ss\ndd.MM.yy")),
4027 mDateTimeSpec(Qt::LocalTime),
4028 mNumberPrecision(6),
4029 mNumberFormatChar(
'g'),
4030 mNumberBeautifulPowers(true),
4037 mAutoTickStep(true),
4038 mAutoSubTicks(true),
4039 mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
4040 mSelectedTickPen(QPen(Qt::blue, 2)),
4041 mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
4042 mSelectedSubTickPen(QPen(Qt::blue, 2)),
4045 mRangeReversed(false),
4046 mScaleType(stLinear),
4048 mScaleLogBaseLogInv(1.0/qLn(mScaleLogBase)),
4052 mLowestVisibleTick(0),
4053 mHighestVisibleTick(-1),
4054 mCachedMarginValid(false),
4073 }
else if (type ==
atLeft)
4110 result.append(QLatin1Char(
'b'));
4112 result.append(QLatin1Char(
'c'));
4205 qDebug() << Q_FUNC_INFO <<
"Invalid logarithmic scale base (must be greater 1):" << base;
4321 if (alignment == Qt::AlignLeft)
4323 else if (alignment == Qt::AlignRight)
4326 setRange(position-size/2.0, position+size/2.0);
4432 if (approximateCount > 0)
4437 qDebug() << Q_FUNC_INFO <<
"approximateCount must be greater than zero:" << approximateCount;
4703 if (formatCode.isEmpty())
4705 qDebug() << Q_FUNC_INFO <<
"Passed formatCode is empty";
4711 QString allowedFormatChars(QLatin1String(
"eEfgG"));
4712 if (allowedFormatChars.contains(formatCode.at(0)))
4717 qDebug() << Q_FUNC_INFO <<
"Invalid number format code (first char not in 'eEfgG'):" << formatCode;
4720 if (formatCode.length() < 2)
4733 qDebug() << Q_FUNC_INFO <<
"Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode;
4736 if (formatCode.length() < 3)
4743 if (formatCode.at(2) == QLatin1Char(
'c'))
4746 }
else if (formatCode.at(2) == QLatin1Char(
'd'))
4751 qDebug() << Q_FUNC_INFO <<
"Invalid number format code (third char neither 'c' nor 'd'):" << formatCode;
5203 qDebug() << Q_FUNC_INFO <<
"Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center;
5225 int otherPixelSize, ownPixelSize;
5237 double newRangeSize = ratio*otherAxis->
range().
size()*ownPixelSize/(double)otherPixelSize;
5249 QList<QCPAbstractPlottable*> p =
plottables();
5251 bool haveRange =
false;
5252 for (
int i=0; i<p.size(); ++i)
5254 if (!p.at(i)->realVisibility() && onlyVisiblePlottables)
5257 bool currentFoundRange;
5261 if (p.at(i)->keyAxis() ==
this)
5262 plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain);
5264 plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain);
5265 if (currentFoundRange)
5268 newRange = plottableRange;
5270 newRange.
expand(plottableRange);
5278 double center = (newRange.
lower+newRange.
upper)*0.5;
5348 else if (value <= 0 && mRange.upper > 0)
5370 else if (value <= 0 && mRange.upper > 0)
5416 details->setValue(part);
5429 QList<QCPAbstractPlottable*> result;
5447 QList<QCPGraph*> result;
5466 QList<QCPAbstractItem*> result;
5471 QList<QCPItemPosition*> positions =
mParentPlot->
mItems.at(itemId)->positions();
5472 for (
int posId=0; posId<positions.size(); ++posId)
5474 if (positions.at(posId)->keyAxis() ==
this || positions.at(posId)->valueAxis() ==
this)
5498 qDebug() << Q_FUNC_INFO <<
"Invalid margin side passed:" << (int)side;
5513 default: qDebug() << Q_FUNC_INFO <<
"invalid axis type";
return atLeft;
break;
5549 double subTickStep = 0;
5550 double subTickPosition = 0;
5551 int subTickIndex = 0;
5555 for (
int i=lowTick+1; i<=highTick; ++i)
5560 subTickPosition =
mTickVector.at(i-1) + k*subTickStep;
5589 #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) // use fromMSecsSinceEpoch function if available, to gain sub-second accuracy on tick labels (e.g. for format "hh:mm:ss:zzz") 5625 double magnitudeFactor = qPow(10.0, qFloor(qLn(
mTickStep)/qLn(10.0)));
5626 double tickStepMantissa =
mTickStep/magnitudeFactor;
5627 if (tickStepMantissa < 5)
5630 mTickStep = (int)(tickStepMantissa*2)/2.0*magnitudeFactor;
5634 mTickStep = (int)(tickStepMantissa/2.0)*2.0*magnitudeFactor;
5642 int tickcount = lastStep-firstStep+1;
5643 if (tickcount < 0) tickcount = 0;
5645 for (
int i=0; i<tickcount; ++i)
5653 double currentMag = lowerMag;
5656 while (currentMag < mRange.upper && currentMag > 0)
5664 double currentMag = lowerMag;
5667 while (currentMag <
mRange.
upper && currentMag < 0)
5675 qDebug() << Q_FUNC_INFO <<
"Invalid range for logarithmic plot: " <<
mRange.
lower <<
"-" <<
mRange.
upper;
5698 double magnitudeFactor = qPow(10.0, qFloor(qLn(tickStep)/qLn(10.0)));
5699 double tickStepMantissa = tickStep/magnitudeFactor;
5702 double epsilon = 0.01;
5705 double fracPart = modf(tickStepMantissa, &intPartf);
5709 if (fracPart < epsilon || 1.0-fracPart < epsilon)
5711 if (1.0-fracPart < epsilon)
5715 case 1: result = 4;
break;
5716 case 2: result = 3;
break;
5717 case 3: result = 2;
break;
5718 case 4: result = 3;
break;
5719 case 5: result = 4;
break;
5720 case 6: result = 2;
break;
5721 case 7: result = 6;
break;
5722 case 8: result = 3;
break;
5723 case 9: result = 2;
break;
5728 if (qAbs(fracPart-0.5) < epsilon)
5732 case 1: result = 2;
break;
5733 case 2: result = 4;
break;
5734 case 3: result = 4;
break;
5735 case 4: result = 2;
break;
5736 case 5: result = 4;
break;
5737 case 6: result = 4;
break;
5738 case 7: result = 2;
break;
5739 case 8: result = 4;
break;
5740 case 9: result = 4;
break;
5758 if (selectionStateChanged)
5768 if (selectionStateChanged)
5799 QVector<double> subTickPositions;
5800 QVector<double> tickPositions;
5802 tickPositions.reserve(highTick-lowTick+1);
5803 tickLabels.reserve(highTick-lowTick+1);
5808 for (
int i=lowTick; i<=highTick; ++i)
5862 bool lowFound =
false;
5863 bool highFound =
false;
5886 if (!lowFound && highFound)
5887 lowIndex = highIndex+1;
5888 else if (lowFound && !highFound)
5889 highIndex = lowIndex-1;
6012 int lowTick, highTick;
6014 QVector<double> tickPositions;
6016 tickPositions.reserve(highTick-lowTick+1);
6017 tickLabels.reserve(highTick-lowTick+1);
6020 for (
int i=lowTick; i<=highTick; ++i)
6074 basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
6081 substituteExponent(true),
6082 numberMultiplyCross(false),
6087 tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
6088 subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
6090 abbreviateDecimalPowers(false),
6091 reversedEndings(false),
6126 double xCor = 0, yCor = 0;
6139 baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(
axisRect.width()+xCor, yCor));
6141 baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -
axisRect.height()+yCor));
6143 baseLine = QLineF(baseLine.p2(), baseLine.p1());
6183 painter->setBrush(QBrush(
basePen.color()));
6184 QVector2D baseLineVector(baseLine.dx(), baseLine.dy());
6195 oldClipRect = painter->clipRegion().boundingRect();
6198 QSize tickLabelsSize(0, 0);
6206 int distanceToAxis = margin;
6209 for (
int i=0; i<maxLabelIndex; ++i)
6215 painter->setClipRect(oldClipRect);
6219 if (!
label.isEmpty())
6224 labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip,
label);
6227 QTransform oldTransform = painter->transform();
6228 painter->translate((origin.x()-margin-labelBounds.height()), origin.y());
6229 painter->rotate(-90);
6230 painter->drawText(0, 0,
axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6231 painter->setTransform(oldTransform);
6235 QTransform oldTransform = painter->transform();
6236 painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-
axisRect.height());
6237 painter->rotate(90);
6238 painter->drawText(0, 0,
axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6239 painter->setTransform(oldTransform);
6242 painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(),
axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6244 painter->drawText(origin.x(), origin.y()+margin,
axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6248 int selectionTolerance = 0;
6252 qDebug() << Q_FUNC_INFO <<
"mParentPlot is null";
6254 int selAxisInSize = selectionTolerance;
6255 int selTickLabelSize;
6256 int selTickLabelOffset;
6259 selTickLabelSize = (
QCPAxis::orientation(
type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width());
6263 selTickLabelSize = -(
QCPAxis::orientation(
type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width());
6266 int selLabelSize = labelBounds.height();
6313 QSize tickLabelsSize(0, 0);
6324 if (!
label.isEmpty())
6328 bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter,
label);
6387 if (text.isEmpty())
return;
6389 QPointF labelAnchor;
6405 newCachedLabel->
pixmap.fill(Qt::transparent);
6407 cachePainter.
setPen(painter->pen());
6428 painter->drawPixmap(labelAnchor+cachedLabel->
offset, cachedLabel->
pixmap);
6429 finalSize = cachedLabel->
pixmap.size();
6449 drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData);
6454 if (finalSize.width() > tickLabelsSize->width())
6455 tickLabelsSize->setWidth(finalSize.width());
6456 if (finalSize.height() > tickLabelsSize->height())
6457 tickLabelsSize->setHeight(finalSize.height());
6472 QTransform oldTransform = painter->transform();
6473 QFont oldFont = painter->font();
6476 painter->translate(x, y);
6481 if (!labelData.
expPart.isEmpty())
6483 painter->setFont(labelData.
baseFont);
6484 painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.
basePart);
6485 painter->setFont(labelData.
expFont);
6489 painter->setFont(labelData.
baseFont);
6494 painter->setTransform(oldTransform);
6495 painter->setFont(oldFont);
6511 bool useBeautifulPowers =
false;
6515 ePos = text.indexOf(QLatin1Char(
'e'));
6517 useBeautifulPowers =
true;
6522 if (result.
baseFont.pointSizeF() > 0)
6524 if (useBeautifulPowers)
6530 result.
basePart = QLatin1String(
"10");
6533 result.
expPart = text.mid(ePos+1);
6535 while (result.
expPart.length() > 2 && result.
expPart.at(1) == QLatin1Char(
'0'))
6537 if (!result.
expPart.isEmpty() && result.
expPart.at(0) == QLatin1Char(
'+'))
6549 result.
totalBounds = QFontMetrics(result.
baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.
basePart);
6557 QTransform transform;
6615 x = +qSin(radians)*labelData.
totalBounds.height();
6637 x = -qSin(-radians)*labelData.
totalBounds.height()/2.0;
6638 y = -qCos(-radians)*labelData.
totalBounds.height();
6651 x = +qSin(radians)*labelData.
totalBounds.height()/2.0;
6656 y = +qSin(-radians)*labelData.
totalBounds.width();
6665 return QPointF(x, y);
6682 finalSize = cachedLabel->
pixmap.size();
6690 if (finalSize.width() > tickLabelsSize->width())
6691 tickLabelsSize->setWidth(finalSize.width());
6692 if (finalSize.height() > tickLabelsSize->height())
6693 tickLabelsSize->setHeight(finalSize.height());
6848 mAntialiasedFill(true),
6849 mAntialiasedScatters(true),
6850 mAntialiasedErrorBars(false),
6852 mSelectedPen(Qt::black),
6853 mBrush(Qt::NoBrush),
6854 mSelectedBrush(Qt::NoBrush),
6856 mValueAxis(valueAxis),
6861 qDebug() << Q_FUNC_INFO <<
"Parent plot of keyAxis is not the same as that of valueAxis.";
6863 qDebug() << Q_FUNC_INFO <<
"keyAxis and valueAxis must be orthogonal to each other.";
7059 if (!keyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
7073 double center = (newRange.
lower+newRange.
upper)*0.5;
7099 if (!valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid value axis";
return; }
7113 double center = (newRange.
lower+newRange.
upper)*0.5;
7203 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
7225 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPointF(); }
7247 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
7373 double vLengthSqr = v.lengthSquared();
7374 if (!qFuzzyIsNull(vLengthSqr))
7376 double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr;
7378 return (a-p).lengthSquared();
7380 return (b-p).lengthSquared();
7382 return ((a + mu*v)-p).lengthSquared();
7384 return (a-p).lengthSquared();
7396 if (selectionStateChanged)
7397 *selectionStateChanged =
mSelected != selBefore;
7408 if (selectionStateChanged)
7409 *selectionStateChanged =
mSelected != selBefore;
7461 mParentItem(parentItem),
7496 qDebug() << Q_FUNC_INFO <<
"no valid anchor id set:" <<
mAnchorId;
7501 qDebug() << Q_FUNC_INFO <<
"no parent item set";
7519 qDebug() << Q_FUNC_INFO <<
"provided pos is child already" <<
reinterpret_cast<quintptr
>(pos);
7531 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child" <<
reinterpret_cast<quintptr
>(pos);
7547 qDebug() << Q_FUNC_INFO <<
"provided pos is child already" <<
reinterpret_cast<quintptr
>(pos);
7559 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child" <<
reinterpret_cast<quintptr
>(pos);
7633 mPositionTypeX(ptAbsolute),
7634 mPositionTypeY(ptAbsolute),
7714 bool retainPixelPosition =
true;
7716 retainPixelPosition =
false;
7718 retainPixelPosition =
false;
7721 if (retainPixelPosition)
7726 if (retainPixelPosition)
7744 bool retainPixelPosition =
true;
7746 retainPixelPosition =
false;
7748 retainPixelPosition =
false;
7751 if (retainPixelPosition)
7756 if (retainPixelPosition)
7783 return successX && successY;
7796 if (parentAnchor ==
this)
7798 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7803 while (currentParent)
7808 if (currentParentPos ==
this)
7810 qDebug() << Q_FUNC_INFO <<
"can't create recursive parent-child-relationship" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7813 currentParent = currentParentPos->parentAnchorX();
7821 qDebug() << Q_FUNC_INFO <<
"can't set parent to be an anchor which itself depends on this position" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7834 if (keepPixelPosition)
7844 if (keepPixelPosition)
7861 if (parentAnchor ==
this)
7863 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7868 while (currentParent)
7873 if (currentParentPos ==
this)
7875 qDebug() << Q_FUNC_INFO <<
"can't create recursive parent-child-relationship" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7878 currentParent = currentParentPos->parentAnchorY();
7886 qDebug() << Q_FUNC_INFO <<
"can't set parent to be an anchor which itself depends on this position" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7899 if (keepPixelPosition)
7909 if (keepPixelPosition)
7986 result.rx() +=
mAxisRect.data()->left();
7988 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptAxisRectRatio, but no axis rect was defined";
7998 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptPlotCoords, but no axes were defined";
8032 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptAxisRectRatio, but no axis rect was defined";
8042 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptPlotCoords, but no axes were defined";
8083 double x = pixelPoint.x();
8084 double y = pixelPoint.y();
8113 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptAxisRectRatio, but no axis rect was defined";
8119 x =
mKeyAxis.data()->pixelToCoord(x);
8123 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptPlotCoords, but no axes were defined";
8153 y /= (double)
mAxisRect.data()->height();
8155 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptAxisRectRatio, but no axis rect was defined";
8161 x =
mKeyAxis.data()->pixelToCoord(y);
8165 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptPlotCoords, but no axes were defined";
8362 mClipToAxisRect(false),
8366 QList<QCPAxisRect*> rects = parentPlot->
axisRects();
8367 if (rects.size() > 0)
8470 qDebug() << Q_FUNC_INFO <<
"position with name not found:" << name;
8486 for (
int i=0; i<
mAnchors.size(); ++i)
8488 if (
mAnchors.at(i)->name() == name)
8491 qDebug() << Q_FUNC_INFO <<
"anchor with name not found:" << name;
8505 for (
int i=0; i<
mAnchors.size(); ++i)
8507 if (
mAnchors.at(i)->name() == name)
8567 double vLengthSqr = v.lengthSquared();
8568 if (!qFuzzyIsNull(vLengthSqr))
8570 double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr;
8572 return (a-p).lengthSquared();
8574 return (b-p).lengthSquared();
8576 return ((a + mu*v)-p).lengthSquared();
8578 return (a-p).lengthSquared();
8603 QList<QLineF> lines;
8604 lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight())
8605 << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight());
8607 for (
int i=0; i<lines.size(); ++i)
8609 double distSqr =
distSqrToLine(lines.at(i).p1(), lines.at(i).p2(), pos);
8610 if (distSqr < minDistSqr)
8611 minDistSqr = distSqr;
8613 result = qSqrt(minDistSqr);
8618 if (rect.contains(pos))
8636 qDebug() << Q_FUNC_INFO <<
"called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId;
8657 qDebug() << Q_FUNC_INFO <<
"anchor/position with name exists already:" << name;
8691 qDebug() << Q_FUNC_INFO <<
"anchor/position with name exists already:" << name;
8706 if (selectionStateChanged)
8707 *selectionStateChanged =
mSelected != selBefore;
8718 if (selectionStateChanged)
8719 *selectionStateChanged =
mSelected != selBefore;
9047 mAutoAddPlottableToLegend(true),
9051 mSelectionTolerance(8),
9052 mNoAntialiasingOnDrag(false),
9053 mBackgroundBrush(Qt::white, Qt::SolidPattern),
9054 mBackgroundScaled(true),
9055 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
9058 mMultiSelectModifier(Qt::ControlModifier),
9059 mPaintBuffer(size()),
9060 mMouseEventElement(0),
9063 setAttribute(Qt::WA_NoMousePropagation);
9064 setAttribute(Qt::WA_OpaquePaintEvent);
9065 setMouseTracking(
true);
9066 QLocale currentLocale = locale();
9067 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
9068 setLocale(currentLocale);
9095 defaultAxisRect->
setLayer(QLatin1String(
"background"));
9486 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9521 qDebug() << Q_FUNC_INFO <<
"plottable already added to this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
plottable);
9526 qDebug() << Q_FUNC_INFO <<
"plottable not created with this QCustomPlot as parent:" <<
reinterpret_cast<quintptr
>(
plottable);
9537 if (!plottable->
layer())
9553 qDebug() << Q_FUNC_INFO <<
"plottable not in list:" <<
reinterpret_cast<quintptr
>(
plottable);
9578 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9593 for (
int i=c-1; i >= 0; --i)
9617 QList<QCPAbstractPlottable*> result;
9621 result.append(plottable);
9645 if (onlySelectable && !plottable->
selectable())
9649 double currentDistance = plottable->
selectTest(pos,
false);
9650 if (currentDistance >= 0 && currentDistance < resultDistance)
9653 resultDistance = currentDistance;
9658 return resultPlottable;
9681 if (index >= 0 && index <
mGraphs.size())
9686 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9721 if (!keyAxis) keyAxis =
xAxis;
9722 if (!valueAxis) valueAxis =
yAxis;
9723 if (!keyAxis || !valueAxis)
9725 qDebug() << Q_FUNC_INFO <<
"can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)";
9730 qDebug() << Q_FUNC_INFO <<
"passed keyAxis or valueAxis doesn't have this QCustomPlot as parent";
9737 newGraph->
setName(QLatin1String(
"Graph ")+QString::number(
mGraphs.size()));
9766 if (index >= 0 && index <
mGraphs.size())
9782 for (
int i=c-1; i >= 0; --i)
9807 QList<QCPGraph*> result;
9811 result.append(graph);
9826 if (index >= 0 && index <
mItems.size())
9831 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9868 qDebug() << Q_FUNC_INFO <<
"item either already in list or not created with this QCustomPlot as parent:" <<
reinterpret_cast<quintptr
>(
item);
9882 if (
mItems.contains(item))
9889 qDebug() << Q_FUNC_INFO <<
"item not in list:" <<
reinterpret_cast<quintptr
>(
item);
9900 if (index >= 0 && index <
mItems.size())
9904 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9919 for (
int i=c-1; i >= 0; --i)
9941 QList<QCPAbstractItem*> result;
9945 result.append(item);
9974 double currentDistance = item->
selectTest(pos,
false);
9975 if (currentDistance >= 0 && currentDistance < resultDistance)
9978 resultDistance = currentDistance;
9993 return mItems.contains(item);
10008 if (layer->
name() == name)
10022 if (index >= 0 && index <
mLayers.size())
10027 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
10057 qDebug() << Q_FUNC_INFO <<
"layer with name doesn't exist:" << name;
10072 if (!
mLayers.contains(layer))
10074 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
layer);
10109 if (!
mLayers.contains(otherLayer))
10111 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(otherLayer);
10116 qDebug() << Q_FUNC_INFO <<
"A layer exists already with the name" << name;
10142 if (!
mLayers.contains(layer))
10144 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
layer);
10149 qDebug() << Q_FUNC_INFO <<
"can't remove last layer";
10154 int removedIndex = layer->
index();
10155 bool isFirstLayer = removedIndex==0;
10157 QList<QCPLayerable*> children = layer->
children();
10160 for (
int i=children.size()-1; i>=0; --i)
10161 children.at(i)->moveToLayer(targetLayer,
true);
10164 for (
int i=0; i<children.size(); ++i)
10165 children.at(i)->moveToLayer(targetLayer,
false);
10188 if (!
mLayers.contains(layer))
10190 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
layer);
10193 if (!
mLayers.contains(otherLayer))
10195 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(otherLayer);
10229 const QList<QCPAxisRect*> rectList =
axisRects();
10230 if (index >= 0 && index < rectList.size())
10232 return rectList.at(index);
10235 qDebug() << Q_FUNC_INFO <<
"invalid axis rect index" << index;
10247 QList<QCPAxisRect*> result;
10248 QStack<QCPLayoutElement*> elementStack;
10252 while (!elementStack.isEmpty())
10258 elementStack.push(element);
10259 if (
QCPAxisRect *ar = qobject_cast<QCPAxisRect*>(element))
10280 bool searchSubElements =
true;
10281 while (searchSubElements && currentElement)
10283 searchSubElements =
false;
10288 currentElement = subElement;
10289 searchSubElements =
true;
10294 return currentElement;
10306 QList<QCPAxis*> result, allAxes;
10308 allAxes << rect->
axes();
10310 foreach (
QCPAxis *axis, allAxes)
10313 result.append(axis);
10328 QList<QCPLegend*> result;
10330 QStack<QCPLayoutElement*> elementStack;
10334 while (!elementStack.isEmpty())
10340 elementStack.push(subElement);
10341 if (
QCPLegend *leg = qobject_cast<QCPLegend*>(subElement))
10344 result.append(leg);
10394 if (painter.isActive())
10396 painter.setRenderHint(QPainter::HighQualityAntialiasing);
10406 qDebug() << Q_FUNC_INFO <<
"Couldn't activate painter on buffer. This usually happens because QCustomPlot has width or height zero.";
10422 QList<QCPAxis*> allAxes;
10424 allAxes << rect->
axes();
10426 foreach (
QCPAxis *axis, allAxes)
10427 axis->
rescale(onlyVisiblePlottables);
10467 bool QCustomPlot::savePdf(
const QString &fileName,
bool noCosmeticPen,
int width,
int height,
const QString &pdfCreator,
const QString &pdfTitle)
10469 bool success =
false;
10470 #ifdef QT_NO_PRINTER 10472 Q_UNUSED(noCosmeticPen)
10475 qDebug() << Q_FUNC_INFO <<
"Qt was built without printer support (QT_NO_PRINTER). PDF not created.";
10477 int newWidth, newHeight;
10478 if (width == 0 || height == 0)
10480 newWidth = this->width();
10481 newHeight = this->height();
10485 newHeight = height;
10488 QPrinter printer(QPrinter::ScreenResolution);
10489 printer.setOutputFileName(fileName);
10490 printer.setOutputFormat(QPrinter::PdfFormat);
10491 printer.setColorMode(QPrinter::Color);
10492 printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator);
10493 printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle);
10496 #if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) 10497 printer.setFullPage(
true);
10498 printer.setPaperSize(
viewport().size(), QPrinter::DevicePixel);
10500 QPageLayout pageLayout;
10501 pageLayout.setMode(QPageLayout::FullPageMode);
10502 pageLayout.setOrientation(QPageLayout::Portrait);
10503 pageLayout.setMargins(QMarginsF(0, 0, 0, 0));
10504 pageLayout.setPageSize(QPageSize(
viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch));
10505 printer.setPageLayout(pageLayout);
10508 if (printpainter.
begin(&printer))
10519 draw(&printpainter);
10520 printpainter.end();
10524 #endif // QT_NO_PRINTER 10567 return saveRastered(fileName, width, height, scale,
"PNG", quality);
10606 return saveRastered(fileName, width, height, scale,
"JPG", quality);
10642 return saveRastered(fileName, width, height, scale,
"BMP");
10676 QPainter painter(
this);
10713 else if (
QCPAxis *ax = qobject_cast<QCPAxis*>(clickedLayerable))
10715 else if (
QCPAbstractItem *ai = qobject_cast<QCPAbstractItem*>(clickedLayerable))
10717 else if (
QCPLegend *lg = qobject_cast<QCPLegend*>(clickedLayerable))
10721 else if (
QCPPlotTitle *pt = qobject_cast<QCPPlotTitle*>(clickedLayerable))
10726 el->mouseDoubleClickEvent(event);
10755 QWidget::mousePressEvent(event);
10775 QWidget::mouseMoveEvent(event);
10795 bool doReplot =
false;
10799 if (event->button() == Qt::LeftButton)
10804 bool selectionStateChanged =
false;
10815 bool selChanged =
false;
10817 selectionStateChanged |= selChanged;
10825 bool selChanged =
false;
10826 clickedLayerable->
selectEvent(event, additive, details, &selChanged);
10827 selectionStateChanged |= selChanged;
10830 if (selectionStateChanged)
10839 else if (
QCPAxis *ax = qobject_cast<QCPAxis*>(clickedLayerable))
10841 else if (
QCPAbstractItem *ai = qobject_cast<QCPAbstractItem*>(clickedLayerable))
10843 else if (
QCPLegend *lg = qobject_cast<QCPLegend*>(clickedLayerable))
10847 else if (
QCPPlotTitle *pt = qobject_cast<QCPPlotTitle*>(clickedLayerable))
10861 QWidget::mouseReleaseEvent(event);
10876 el->wheelEvent(event);
10878 QWidget::wheelEvent(event);
10906 painter->setClipRect(child->
clipRect().translated(0, -1));
10908 child->
draw(painter);
10992 if (this->legend == legend)
11004 for (
int i=0; i<
mLayers.size(); ++i)
11022 for (
int layerIndex=
mLayers.size()-1; layerIndex>=0; --layerIndex)
11024 const QList<QCPLayerable*> layerables =
mLayers.at(layerIndex)->children();
11027 for (
int i=layerables.size()-1; i>=0; --i)
11029 if (!layerables.at(i)->realVisibility())
11032 double dist = layerables.at(i)->
selectTest(pos, onlySelectable, &details);
11033 if (dist >= 0 && dist < minimumDistance)
11035 minimumDistance = dist;
11036 minimumDistanceLayerable = layerables.at(i);
11037 if (selectionDetails) *selectionDetails = details;
11041 return minimumDistanceLayerable;
11059 QPixmap buffer =
toPixmap(width, height, scale);
11060 if (!buffer.isNull())
11061 return buffer.save(fileName, format, quality);
11077 int newWidth, newHeight;
11078 if (width == 0 || height == 0)
11080 newWidth = this->width();
11081 newHeight = this->height();
11085 newHeight = height;
11087 int scaledWidth = qRound(scale*newWidth);
11088 int scaledHeight = qRound(scale*newHeight);
11090 QPixmap result(scaledWidth, scaledHeight);
11093 painter.
begin(&result);
11094 if (painter.isActive())
11099 if (!qFuzzyCompare(scale, 1.0))
11103 painter.scale(scale, scale);
11112 qDebug() << Q_FUNC_INFO <<
"Couldn't activate painter on pixmap";
11133 int newWidth, newHeight;
11134 if (width == 0 || height == 0)
11136 newWidth = this->width();
11137 newHeight = this->height();
11141 newHeight = height;
11144 if (painter->isActive())
11156 qDebug() << Q_FUNC_INFO <<
"Passed painter is not active";
11198 mColorInterpolation(ciRGB),
11200 mColorBufferInvalidated(true)
11209 return ((other.
mLevelCount == this->mLevelCount) &&
11211 (other.
mPeriodic == this->mPeriodic) &&
11225 qDebug() << Q_FUNC_INFO <<
"n must be greater or equal 2 but was" << n;
11316 qDebug() << Q_FUNC_INFO <<
"null pointer given as data";
11321 qDebug() << Q_FUNC_INFO <<
"null pointer given as scanLine";
11332 for (
int i=0; i<n; ++i)
11334 int index = (int)((data[dataIndexFactor*i]-range.
lower)*posToIndexFactor) %
mLevelCount;
11341 for (
int i=0; i<n; ++i)
11343 int index = (data[dataIndexFactor*i]-range.
lower)*posToIndexFactor;
11355 for (
int i=0; i<n; ++i)
11364 for (
int i=0; i<n; ++i)
12030 for (QMap<double, QColor>::const_iterator it=
mColorStops.constBegin(); it!=
mColorStops.constEnd(); ++it)
12046 double indexToPosFactor = 1.0/(double)(
mLevelCount-1);
12049 double position = i*indexToPosFactor;
12050 QMap<double, QColor>::const_iterator it =
mColorStops.lowerBound(position);
12059 QMap<double, QColor>::const_iterator high = it;
12060 QMap<double, QColor>::const_iterator low = it-1;
12061 double t = (position-low.key())/(high.key()-low.key());
12066 mColorBuffer[i] = qRgb((1-t)*low.value().red() + t*high.value().red(),
12067 (1-t)*low.value().green() + t*high.value().green(),
12068 (1-t)*low.value().blue() + t*high.value().blue());
12073 QColor lowHsv = low.value().toHsv();
12074 QColor highHsv = high.value().toHsv();
12076 double hueDiff = highHsv.hueF()-lowHsv.hueF();
12078 hue = lowHsv.hueF() - t*(1.0-hueDiff);
12079 else if (hueDiff < -0.5)
12080 hue = lowHsv.hueF() + t*(1.0+hueDiff);
12082 hue = lowHsv.hueF() + t*hueDiff;
12083 if (hue < 0) hue += 1.0;
12084 else if (hue >= 1.0) hue -= 1.0;
12085 mColorBuffer[i] = QColor::fromHsvF(hue, (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb();
12233 mBackgroundBrush(Qt::NoBrush),
12234 mBackgroundScaled(true),
12235 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
12237 mRangeDrag(Qt::Horizontal|Qt::Vertical),
12238 mRangeZoom(Qt::Horizontal|Qt::Vertical),
12239 mRangeZoomFactorHorz(0.85),
12240 mRangeZoomFactorVert(0.85),
12254 if (setupDefaultAxes)
12280 QList<QCPAxis*> axesList =
axes();
12281 for (
int i=0; i<axesList.size(); ++i)
12292 return mAxes.value(type).size();
12302 QList<QCPAxis*> ax(
mAxes.value(type));
12303 if (index >= 0 && index < ax.size())
12305 return ax.at(index);
12308 qDebug() << Q_FUNC_INFO <<
"Axis index out of bounds:" << index;
12323 QList<QCPAxis*> result;
12341 QList<QCPAxis*> result;
12342 QHashIterator<QCPAxis::AxisType, QList<QCPAxis*> > it(
mAxes);
12343 while (it.hasNext())
12346 result << it.value();
12375 newAxis =
new QCPAxis(
this, type);
12380 qDebug() << Q_FUNC_INFO <<
"passed axis has different axis type than specified in type parameter";
12385 qDebug() << Q_FUNC_INFO <<
"passed axis doesn't have this axis rect as parent axis rect";
12388 if (
axes().contains(newAxis))
12390 qDebug() << Q_FUNC_INFO <<
"passed axis is already owned by this axis rect";
12400 mAxes[type].append(newAxis);
12414 QList<QCPAxis*> result;
12436 QHashIterator<QCPAxis::AxisType, QList<QCPAxis*> > it(
mAxes);
12437 while (it.hasNext())
12440 if (it.value().contains(axis))
12442 mAxes[it.key()].removeOne(axis);
12443 if (qobject_cast<QCustomPlot*>(
parentPlot()))
12449 qDebug() << Q_FUNC_INFO <<
"Axis isn't in axis rect:" <<
reinterpret_cast<quintptr
>(
axis);
12481 QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
12543 connect(xAxis, SIGNAL(rangeChanged(
QCPRange)), xAxis2, SLOT(setRange(
QCPRange)));
12544 connect(yAxis, SIGNAL(rangeChanged(
QCPRange)), yAxis2, SLOT(setRange(
QCPRange)));
12559 QList<QCPAbstractPlottable*> result;
12579 QList<QCPGraph*> result;
12602 QList<QCPAbstractItem*> result;
12610 QList<QCPItemPosition*> positions =
mParentPlot->
mItems.at(itemId)->positions();
12611 for (
int posId=0; posId<positions.size(); ++posId)
12613 if (positions.at(posId)->axisRect() ==
this ||
12614 positions.at(posId)->keyAxis()->axisRect() ==
this ||
12615 positions.at(posId)->valueAxis()->axisRect() ==
this)
12641 QList<QCPAxis*> allAxes =
axes();
12642 for (
int i=0; i<allAxes.size(); ++i)
12643 allAxes.at(i)->setupTickVectors();
12661 QList<QCPLayoutElement*> result;
12666 result << mInsetLayout->
elements(recursive);
12938 const QList<QCPAxis*> axesList =
mAxes.value(type);
12939 if (axesList.isEmpty())
12942 bool isFirstVisible = !axesList.first()->visible();
12943 for (
int i=1; i<axesList.size(); ++i)
12945 int offset = axesList.at(i-1)->offset() + axesList.at(i-1)->calculateMargin();
12946 if (axesList.at(i)->visible())
12948 if (!isFirstVisible)
12949 offset += axesList.at(i)->tickLengthIn();
12950 isFirstVisible =
false;
12952 axesList.at(i)->setOffset(offset);
12960 qDebug() << Q_FUNC_INFO <<
"Called with side that isn't specified as auto margin";
12966 if (axesList.size() > 0)
12967 return axesList.last()->offset() + axesList.last()->calculateMargin();
12986 if (event->buttons() & Qt::LeftButton)
13024 double diff = rangeDragHorzAxis->pixelToCoord(
mDragStart.x()) - rangeDragHorzAxis->pixelToCoord(event->pos().x());
13028 double diff = rangeDragHorzAxis->pixelToCoord(
mDragStart.x()) / rangeDragHorzAxis->pixelToCoord(event->pos().x());
13039 double diff = rangeDragVertAxis->pixelToCoord(
mDragStart.y()) - rangeDragVertAxis->pixelToCoord(event->pos().y());
13043 double diff = rangeDragVertAxis->pixelToCoord(
mDragStart.y()) / rangeDragVertAxis->pixelToCoord(event->pos().y());
13091 double wheelSteps =
event->delta()/120.0;
13154 mParentLegend(parent),
13155 mFont(parent->font()),
13156 mTextColor(parent->textColor()),
13157 mSelectedFont(parent->selectedFont()),
13158 mSelectedTextColor(parent->selectedTextColor()),
13162 setLayer(QLatin1String(
"legend"));
13247 if (
mRect.contains(pos.toPoint()))
13274 if (selectionStateChanged)
13275 *selectionStateChanged =
mSelected != selBefore;
13286 if (selectionStateChanged)
13287 *selectionStateChanged =
mSelected != selBefore;
13330 mPlottable(plottable)
13376 QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip,
mPlottable->
name());
13377 QRectF iconRect(
mRect.topLeft(), iconSize);
13378 int textHeight = qMax(textRect.height(), iconSize.height());
13382 painter->setClipRect(iconRect, Qt::IntersectClip);
13389 painter->setBrush(Qt::NoBrush);
13390 painter->drawRect(iconRect);
13402 QSize result(0, 0);
13404 QFontMetrics fontMetrics(
getFont());
13406 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip,
mPlottable->
name());
13408 result.setHeight(qMax(textRect.height(), iconSize.height()) +
mMargins.top() +
mMargins.bottom());
13461 setColumnSpacing(10);
13464 setIconSize(32, 18);
13466 setIconTextPadding(7);
13468 setSelectableParts(spLegendBox | spItems);
13469 setSelectedParts(spNone);
13471 setBorderPen(QPen(Qt::black));
13472 setSelectedBorderPen(QPen(Qt::blue, 2));
13473 setIconBorderPen(Qt::NoPen);
13474 setSelectedIconBorderPen(QPen(Qt::blue, 2));
13475 setBrush(Qt::white);
13476 setSelectedBrush(Qt::white);
13492 bool hasSelectedItems =
false;
13493 for (
int i=0; i<itemCount(); ++i)
13495 if (item(i) && item(i)->selected())
13497 hasSelectedItems =
true;
13501 if (hasSelectedItems)
13502 return mSelectedParts | spItems;
13504 return mSelectedParts & ~spItems;
13535 for (
int i=0; i<itemCount(); ++i)
13538 item(i)->setFont(
mFont);
13554 for (
int i=0; i<itemCount(); ++i)
13557 item(i)->setTextColor(color);
13574 mIconSize.setWidth(width);
13575 mIconSize.setHeight(height);
13585 mIconTextPadding = padding;
13596 mIconBorderPen = pen;
13611 if (mSelectableParts != selectable)
13641 SelectableParts newSelected =
selected;
13642 mSelectedParts = this->selectedParts();
13644 if (mSelectedParts != newSelected)
13646 if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems))
13648 qDebug() << Q_FUNC_INFO <<
"spItems flag can not be set, it can only be unset with this function";
13649 newSelected &= ~spItems;
13651 if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems))
13653 for (
int i=0; i<itemCount(); ++i)
13656 item(i)->setSelected(
false);
13659 mSelectedParts = newSelected;
13672 mSelectedBorderPen = pen;
13682 mSelectedIconBorderPen = pen;
13693 mSelectedBrush = brush;
13706 for (
int i=0; i<itemCount(); ++i)
13709 item(i)->setSelectedFont(font);
13723 for (
int i=0; i<itemCount(); ++i)
13726 item(i)->setSelectedTextColor(color);
13748 for (
int i=0; i<itemCount(); ++i)
13765 return elementCount();
13773 for (
int i=0; i<itemCount(); ++i)
13775 if (item == this->item(i))
13789 return itemWithPlottable(plottable);
13801 if (!hasItem(item))
13803 return addElement(rowCount(), 0, item);
13819 bool success =
remove(ali);
13836 bool success =
remove(item);
13846 for (
int i=itemCount()-1; i>=0; --i)
13858 QList<QCPAbstractLegendItem*> result;
13859 for (
int i=0; i<itemCount(); ++i)
13863 if (ali->selected())
13864 result.append(ali);
13895 return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen;
13905 return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush;
13916 painter->setBrush(getBrush());
13917 painter->
setPen(getBorderPen());
13925 if (onlySelectable && !mSelectableParts.testFlag(spLegendBox))
13930 if (details) details->setValue(spLegendBox);
13940 mSelectedParts = selectedParts();
13941 if (details.value<
SelectablePart>() == spLegendBox && mSelectableParts.testFlag(spLegendBox))
13943 SelectableParts selBefore = mSelectedParts;
13944 setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox);
13945 if (selectionStateChanged)
13946 *selectionStateChanged = mSelectedParts != selBefore;
13953 mSelectedParts = selectedParts();
13954 if (mSelectableParts.testFlag(spLegendBox))
13956 SelectableParts selBefore = mSelectedParts;
13957 setSelectedParts(selectedParts() & ~spLegendBox);
13958 if (selectionStateChanged)
13959 *selectionStateChanged = mSelectedParts != selBefore;
13978 Q_UNUSED(parentPlot)
14023 mFont(QFont(QLatin1String(
"sans serif"), 13*1.5, QFont::Bold)),
14025 mSelectedFont(QFont(QLatin1String(
"sans serif"), 13*1.6, QFont::Bold)),
14033 mFont = QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.5, QFont::Bold);
14034 mSelectedFont = QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.6, QFont::Bold);
14046 mFont(QFont(parentPlot->
font().family(), parentPlot->
font().pointSize()*1.5, QFont::Bold)),
14048 mSelectedFont(QFont(parentPlot->
font().family(), parentPlot->
font().pointSize()*1.6, QFont::Bold)),
14155 QFontMetrics metrics(
mFont);
14156 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size();
14165 QFontMetrics metrics(
mFont);
14166 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size();
14168 result.setWidth(QWIDGETSIZE_MAX);
14181 if (selectionStateChanged)
14182 *selectionStateChanged =
mSelected != selBefore;
14193 if (selectionStateChanged)
14194 *selectionStateChanged =
mSelected != selBefore;
14331 mDataScaleType(
QCPAxis::stLinear),
14350 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
14362 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14376 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14396 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14403 double logBaseTransfer = 10;
14404 QString labelTransfer;
14410 logBaseTransfer =
mColorAxis.data()->scaleLogBase();
14425 mColorAxis.data()->setScaleLogBase(logBaseTransfer);
14489 mAxisRect.data()->mGradientImageInvalidated =
true;
14502 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
14528 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14548 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14563 QList<QCPColorMap*> result;
14567 if (cm->colorScale() ==
this)
14581 QList<QCPColorMap*> maps =
colorMaps();
14583 bool haveRange =
false;
14587 for (
int i=0; i<maps.size(); ++i)
14589 if (!maps.at(i)->realVisibility() && onlyVisibleMaps)
14592 if (maps.at(i)->colorScale() ==
this)
14594 bool currentFoundRange =
true;
14595 mapRange = maps.at(i)->data()->dataBounds();
14598 if (mapRange.
lower <= 0 && mapRange.
upper > 0)
14600 else if (mapRange.
lower <= 0 && mapRange.
upper <= 0)
14601 currentFoundRange =
false;
14602 }
else if (sign == -1)
14604 if (mapRange.
upper >= 0 && mapRange.
lower < 0)
14606 else if (mapRange.
upper >= 0 && mapRange.
lower >= 0)
14607 currentFoundRange =
false;
14609 if (currentFoundRange)
14612 newRange = mapRange;
14614 newRange.
expand(mapRange);
14623 double center = (newRange.
lower+newRange.
upper)*0.5;
14644 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14685 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14688 mAxisRect.data()->mousePressEvent(event);
14696 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14699 mAxisRect.data()->mouseMoveEvent(event);
14707 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14710 mAxisRect.data()->mouseReleaseEvent(event);
14718 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14744 mParentColorScale(parentColorScale),
14745 mGradientImageInvalidated(true)
14754 connect(
axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)),
this, SLOT(
axisSelectionChanged(QCPAxis::SelectableParts)));
14755 connect(
axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)),
this, SLOT(
axisSelectableChanged(QCPAxis::SelectableParts)));
14783 bool mirrorHorz =
false;
14784 bool mirrorVert =
false;
14802 if (
rect().isEmpty())
14807 QVector<double> data(n);
14808 for (
int i=0; i<n; ++i)
14813 h =
rect().height();
14815 QVector<QRgb*> pixels;
14816 for (
int y=0; y<h; ++y)
14817 pixels.append(reinterpret_cast<QRgb*>(
mGradientImage.scanLine(y)));
14819 for (
int y=1; y<h; ++y)
14820 memcpy(pixels.at(y), pixels.first(), n*
sizeof(QRgb));
14823 w =
rect().width();
14826 for (
int y=0; y<h; ++y)
14828 QRgb *pixels =
reinterpret_cast<QRgb*
>(
mGradientImage.scanLine(y));
14830 for (
int x=0; x<
w; ++x)
14831 pixels[x] = lineColor;
14847 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis*>(sender()))
14848 if (senderAxis->axisType() == type)
14871 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis*>(sender()))
14872 if (senderAxis->axisType() == type)
14998 setPen(QPen(Qt::blue, 0));
15031 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
15053 int n = key.size();
15054 n = qMin(n, value.size());
15056 for (
int i=0; i<n; ++i)
15058 newData.
key = key[i];
15059 newData.value = value[i];
15060 mData->insertMulti(newData.key, newData);
15076 int n = key.size();
15077 n = qMin(n, value.size());
15078 n = qMin(n, valueError.size());
15080 for (
int i=0; i<n; ++i)
15082 newData.
key = key[i];
15083 newData.value = value[i];
15084 newData.valueErrorMinus = valueError[i];
15085 newData.valueErrorPlus = valueError[i];
15086 mData->insertMulti(key[i], newData);
15099 void QCPGraph::setDataValueError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &valueErrorMinus,
const QVector<double> &valueErrorPlus)
15102 int n = key.size();
15103 n = qMin(n, value.size());
15104 n = qMin(n, valueErrorMinus.size());
15105 n = qMin(n, valueErrorPlus.size());
15107 for (
int i=0; i<n; ++i)
15109 newData.
key = key[i];
15110 newData.value = value[i];
15111 newData.valueErrorMinus = valueErrorMinus[i];
15112 newData.valueErrorPlus = valueErrorPlus[i];
15113 mData->insertMulti(key[i], newData);
15129 int n = key.size();
15130 n = qMin(n, value.size());
15131 n = qMin(n, keyError.size());
15133 for (
int i=0; i<n; ++i)
15135 newData.
key = key[i];
15136 newData.value = value[i];
15137 newData.keyErrorMinus = keyError[i];
15138 newData.keyErrorPlus = keyError[i];
15139 mData->insertMulti(key[i], newData);
15152 void QCPGraph::setDataKeyError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyErrorMinus,
const QVector<double> &keyErrorPlus)
15155 int n = key.size();
15156 n = qMin(n, value.size());
15157 n = qMin(n, keyErrorMinus.size());
15158 n = qMin(n, keyErrorPlus.size());
15160 for (
int i=0; i<n; ++i)
15162 newData.
key = key[i];
15163 newData.value = value[i];
15164 newData.keyErrorMinus = keyErrorMinus[i];
15165 newData.keyErrorPlus = keyErrorPlus[i];
15166 mData->insertMulti(key[i], newData);
15179 void QCPGraph::setDataBothError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyError,
const QVector<double> &valueError)
15182 int n = key.size();
15183 n = qMin(n, value.size());
15184 n = qMin(n, valueError.size());
15185 n = qMin(n, keyError.size());
15187 for (
int i=0; i<n; ++i)
15189 newData.
key = key[i];
15190 newData.value = value[i];
15191 newData.keyErrorMinus = keyError[i];
15192 newData.keyErrorPlus = keyError[i];
15193 newData.valueErrorMinus = valueError[i];
15194 newData.valueErrorPlus = valueError[i];
15195 mData->insertMulti(key[i], newData);
15208 void QCPGraph::setDataBothError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyErrorMinus,
const QVector<double> &keyErrorPlus,
const QVector<double> &valueErrorMinus,
const QVector<double> &valueErrorPlus)
15211 int n = key.size();
15212 n = qMin(n, value.size());
15213 n = qMin(n, valueErrorMinus.size());
15214 n = qMin(n, valueErrorPlus.size());
15215 n = qMin(n, keyErrorMinus.size());
15216 n = qMin(n, keyErrorPlus.size());
15218 for (
int i=0; i<n; ++i)
15220 newData.
key = key[i];
15221 newData.value = value[i];
15222 newData.keyErrorMinus = keyErrorMinus[i];
15223 newData.keyErrorPlus = keyErrorPlus[i];
15224 newData.valueErrorMinus = valueErrorMinus[i];
15225 newData.valueErrorPlus = valueErrorPlus[i];
15226 mData->insertMulti(key[i], newData);
15311 if (targetGraph ==
this)
15313 qDebug() << Q_FUNC_INFO <<
"targetGraph is this graph itself";
15320 qDebug() << Q_FUNC_INFO <<
"targetGraph not in same plot";
15374 mData->unite(dataMap);
15387 mData->insertMulti(data.
key, data);
15402 newData.
value = value;
15403 mData->insertMulti(newData.
key, newData);
15416 int n = qMin(keys.size(), values.size());
15418 for (
int i=0; i<n; ++i)
15420 newData.
key = keys[i];
15421 newData.value = values[i];
15422 mData->insertMulti(newData.key, newData);
15432 QCPDataMap::iterator it =
mData->begin();
15433 while (it !=
mData->end() && it.key() < key)
15434 it =
mData->erase(it);
15443 if (
mData->isEmpty())
return;
15444 QCPDataMap::iterator it =
mData->upperBound(key);
15445 while (it !=
mData->end())
15446 it =
mData->erase(it);
15458 if (fromKey >= toKey ||
mData->isEmpty())
return;
15459 QCPDataMap::iterator it =
mData->upperBound(fromKey);
15460 QCPDataMap::iterator itEnd =
mData->upperBound(toKey);
15461 while (it != itEnd)
15462 it =
mData->erase(it);
15475 mData->remove(key);
15493 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
15495 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
15525 if (
mData->isEmpty())
return;
15528 if (!keyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
15561 if (
mData->isEmpty())
return;
15564 if (!valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid value axis";
return; }
15589 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15590 if (
mKeyAxis.data()->range().size() <= 0 ||
mData->isEmpty())
return;
15594 QVector<QPointF> *lineData =
new QVector<QPointF>;
15595 QVector<QCPData> *scatterData = 0;
15597 scatterData =
new QVector<QCPData>;
15603 #ifdef QCUSTOMPLOT_CHECK_DATA 15604 QCPDataMap::const_iterator it;
15605 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
15610 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"invalid." <<
"Plottable name:" <<
name();
15630 delete scatterData;
15637 if (
mBrush.style() != Qt::NoBrush)
15640 painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0),
mBrush);
15647 painter->
drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0));
15657 scaledStyle.
setPixmap(scaledStyle.
pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
15659 scaledStyle.
drawShape(painter, QRectF(rect).center());
15730 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15731 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as linePixelData";
return; }
15733 QVector<QCPData> lineData;
15735 linePixelData->reserve(lineData.size()+2);
15736 linePixelData->resize(lineData.size());
15741 for (
int i=0; i<lineData.size(); ++i)
15743 (*linePixelData)[i].setX(valueAxis->
coordToPixel(lineData.at(i).value));
15744 (*linePixelData)[i].setY(keyAxis->
coordToPixel(lineData.at(i).key));
15748 for (
int i=0; i<lineData.size(); ++i)
15750 (*linePixelData)[i].setX(keyAxis->
coordToPixel(lineData.at(i).key));
15751 (*linePixelData)[i].setY(valueAxis->
coordToPixel(lineData.at(i).value));
15771 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15772 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
return; }
15774 QVector<QCPData> lineData;
15776 linePixelData->reserve(lineData.size()*2+2);
15777 linePixelData->resize(lineData.size()*2);
15782 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15784 for (
int i=0; i<lineData.size(); ++i)
15787 (*linePixelData)[i*2+0].setX(lastValue);
15788 (*linePixelData)[i*2+0].setY(key);
15789 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15790 (*linePixelData)[i*2+1].setX(lastValue);
15791 (*linePixelData)[i*2+1].setY(key);
15795 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15797 for (
int i=0; i<lineData.size(); ++i)
15800 (*linePixelData)[i*2+0].setX(key);
15801 (*linePixelData)[i*2+0].setY(lastValue);
15802 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15803 (*linePixelData)[i*2+1].setX(key);
15804 (*linePixelData)[i*2+1].setY(lastValue);
15824 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15825 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
return; }
15827 QVector<QCPData> lineData;
15829 linePixelData->reserve(lineData.size()*2+2);
15830 linePixelData->resize(lineData.size()*2);
15835 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15837 for (
int i=0; i<lineData.size(); ++i)
15839 value = valueAxis->
coordToPixel(lineData.at(i).value);
15840 (*linePixelData)[i*2+0].setX(value);
15841 (*linePixelData)[i*2+0].setY(lastKey);
15843 (*linePixelData)[i*2+1].setX(value);
15844 (*linePixelData)[i*2+1].setY(lastKey);
15848 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15850 for (
int i=0; i<lineData.size(); ++i)
15852 value = valueAxis->
coordToPixel(lineData.at(i).value);
15853 (*linePixelData)[i*2+0].setX(lastKey);
15854 (*linePixelData)[i*2+0].setY(value);
15856 (*linePixelData)[i*2+1].setX(lastKey);
15857 (*linePixelData)[i*2+1].setY(value);
15877 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15878 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
return; }
15880 QVector<QCPData> lineData;
15882 linePixelData->reserve(lineData.size()*2+2);
15883 linePixelData->resize(lineData.size()*2);
15887 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15888 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15890 (*linePixelData)[0].setX(lastValue);
15891 (*linePixelData)[0].setY(lastKey);
15892 for (
int i=1; i<lineData.size(); ++i)
15894 key = (keyAxis->
coordToPixel(lineData.at(i).key)+lastKey)*0.5;
15895 (*linePixelData)[i*2-1].setX(lastValue);
15896 (*linePixelData)[i*2-1].setY(key);
15897 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15899 (*linePixelData)[i*2+0].setX(lastValue);
15900 (*linePixelData)[i*2+0].setY(key);
15902 (*linePixelData)[lineData.size()*2-1].setX(lastValue);
15903 (*linePixelData)[lineData.size()*2-1].setY(lastKey);
15906 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15907 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15909 (*linePixelData)[0].setX(lastKey);
15910 (*linePixelData)[0].setY(lastValue);
15911 for (
int i=1; i<lineData.size(); ++i)
15913 key = (keyAxis->
coordToPixel(lineData.at(i).key)+lastKey)*0.5;
15914 (*linePixelData)[i*2-1].setX(key);
15915 (*linePixelData)[i*2-1].setY(lastValue);
15916 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15918 (*linePixelData)[i*2+0].setX(key);
15919 (*linePixelData)[i*2+0].setY(lastValue);
15921 (*linePixelData)[lineData.size()*2-1].setX(lastKey);
15922 (*linePixelData)[lineData.size()*2-1].setY(lastValue);
15942 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15943 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as linePixelData";
return; }
15945 QVector<QCPData> lineData;
15947 linePixelData->resize(lineData.size()*2);
15954 for (
int i=0; i<lineData.size(); ++i)
15957 (*linePixelData)[i*2+0].setX(zeroPointX);
15958 (*linePixelData)[i*2+0].setY(key);
15959 (*linePixelData)[i*2+1].setX(valueAxis->
coordToPixel(lineData.at(i).value));
15960 (*linePixelData)[i*2+1].setY(key);
15966 for (
int i=0; i<lineData.size(); ++i)
15969 (*linePixelData)[i*2+0].setX(key);
15970 (*linePixelData)[i*2+0].setY(zeroPointY);
15971 (*linePixelData)[i*2+1].setX(key);
15972 (*linePixelData)[i*2+1].setY(valueAxis->
coordToPixel(lineData.at(i).value));
16000 painter->
setPen(Qt::NoPen);
16002 painter->drawPolygon(QPolygonF(*lineData));
16007 painter->
setPen(Qt::NoPen);
16026 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
16035 for (
int i=0; i<scatterData->size(); ++i)
16039 for (
int i=0; i<scatterData->size(); ++i)
16049 for (
int i=0; i<scatterData->size(); ++i)
16050 if (!qIsNaN(scatterData->at(i).value))
16054 for (
int i=0; i<scatterData->size(); ++i)
16055 if (!qIsNaN(scatterData->at(i).value))
16072 if (
mainPen().style() != Qt::NoPen &&
mainPen().color().alpha() != 0)
16076 painter->setBrush(Qt::NoBrush);
16095 painter->pen().style() == Qt::SolidLine &&
16100 int lineDataSize = lineData->size();
16101 while (i < lineDataSize)
16103 if (!qIsNaN(lineData->at(i).y()) && !qIsNaN(lineData->at(i).x()))
16104 painter->
drawLine(lineData->at(i-1), lineData->at(i));
16111 int segmentStart = 0;
16113 int lineDataSize = lineData->size();
16114 while (i < lineDataSize)
16116 if (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x()))
16118 painter->drawPolyline(lineData->constData()+segmentStart, i-segmentStart);
16119 segmentStart = i+1;
16124 painter->drawPolyline(lineData->constData()+segmentStart, lineDataSize-segmentStart);
16139 if (
mainPen().style() != Qt::NoPen &&
mainPen().color().alpha() != 0)
16143 pen.setCapStyle(Qt::FlatCap);
16145 painter->setBrush(Qt::NoBrush);
16146 painter->drawLines(*lineData);
16166 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
16168 QCPDataMap::const_iterator lower, upper;
16170 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
16178 maxCount = 2*keyPixelSpan+2;
16186 QCPDataMap::const_iterator it = lower;
16187 QCPDataMap::const_iterator upperEnd = upper+1;
16188 double minValue = it.value().value;
16189 double maxValue = it.value().value;
16190 QCPDataMap::const_iterator currentIntervalFirstPoint = it;
16194 double lastIntervalEndKey = currentIntervalStartKey;
16195 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
16197 int intervalDataCount = 1;
16199 while (it != upperEnd)
16201 if (it.key() < currentIntervalStartKey+keyEpsilon)
16203 if (it.value().value < minValue)
16204 minValue = it.value().value;
16205 else if (it.value().value > maxValue)
16206 maxValue = it.value().value;
16207 ++intervalDataCount;
16210 if (intervalDataCount >= 2)
16212 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon)
16213 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint.value().value));
16214 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue));
16215 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue));
16216 if (it.key() > currentIntervalStartKey+keyEpsilon*2)
16217 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.8, (it-1).value().value));
16219 lineData->append(
QCPData(currentIntervalFirstPoint.key(), currentIntervalFirstPoint.value().value));
16220 lastIntervalEndKey = (it-1).value().key;
16221 minValue = it.value().value;
16222 maxValue = it.value().value;
16223 currentIntervalFirstPoint = it;
16225 if (keyEpsilonVariable)
16226 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
16227 intervalDataCount = 1;
16232 if (intervalDataCount >= 2)
16234 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon)
16235 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint.value().value));
16236 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue));
16237 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue));
16239 lineData->append(
QCPData(currentIntervalFirstPoint.key(), currentIntervalFirstPoint.value().value));
16244 double valueMaxRange = valueAxis->
range().
upper;
16245 double valueMinRange = valueAxis->
range().
lower;
16246 QCPDataMap::const_iterator it = lower;
16247 QCPDataMap::const_iterator upperEnd = upper+1;
16248 double minValue = it.value().value;
16249 double maxValue = it.value().value;
16250 QCPDataMap::const_iterator minValueIt = it;
16251 QCPDataMap::const_iterator maxValueIt = it;
16252 QCPDataMap::const_iterator currentIntervalStart = it;
16256 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
16258 int intervalDataCount = 1;
16260 while (it != upperEnd)
16262 if (it.key() < currentIntervalStartKey+keyEpsilon)
16264 if (it.value().value < minValue && it.value().value > valueMinRange && it.value().value < valueMaxRange)
16266 minValue = it.value().value;
16268 }
else if (it.value().value > maxValue && it.value().value > valueMinRange && it.value().value < valueMaxRange)
16270 maxValue = it.value().value;
16273 ++intervalDataCount;
16276 if (intervalDataCount >= 2)
16280 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0)));
16281 QCPDataMap::const_iterator intervalIt = currentIntervalStart;
16283 while (intervalIt != it)
16285 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt.value().value > valueMinRange && intervalIt.value().value < valueMaxRange)
16286 scatterData->append(intervalIt.value());
16290 }
else if (currentIntervalStart.value().value > valueMinRange && currentIntervalStart.value().value < valueMaxRange)
16291 scatterData->append(currentIntervalStart.value());
16292 minValue = it.value().value;
16293 maxValue = it.value().value;
16294 currentIntervalStart = it;
16296 if (keyEpsilonVariable)
16297 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
16298 intervalDataCount = 1;
16303 if (intervalDataCount >= 2)
16307 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0)));
16308 QCPDataMap::const_iterator intervalIt = currentIntervalStart;
16310 while (intervalIt != it)
16312 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt.value().value > valueMinRange && intervalIt.value().value < valueMaxRange)
16313 scatterData->append(intervalIt.value());
16317 }
else if (currentIntervalStart.value().value > valueMinRange && currentIntervalStart.value().value < valueMaxRange)
16318 scatterData->append(currentIntervalStart.value());
16322 QVector<QCPData> *dataVector = 0;
16324 dataVector = lineData;
16325 else if (scatterData)
16326 dataVector = scatterData;
16329 QCPDataMap::const_iterator it = lower;
16330 QCPDataMap::const_iterator upperEnd = upper+1;
16331 dataVector->reserve(dataCount+2);
16332 while (it != upperEnd)
16334 dataVector->append(it.value());
16338 if (lineData && scatterData)
16339 *scatterData = *dataVector;
16352 if (qIsNaN(data.
value))
16356 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
16374 if (a-y > skipSymbolMargin)
16375 painter->
drawLine(QLineF(x, a, x, y+skipSymbolMargin));
16376 if (y-b > skipSymbolMargin)
16377 painter->
drawLine(QLineF(x, y-skipSymbolMargin, x, b));
16379 painter->
drawLine(QLineF(x, a, x, b));
16381 painter->
drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a));
16382 painter->
drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b));
16393 if (x-a > skipSymbolMargin)
16394 painter->
drawLine(QLineF(a, y, x-skipSymbolMargin, y));
16395 if (b-x > skipSymbolMargin)
16396 painter->
drawLine(QLineF(x+skipSymbolMargin, y, b, y));
16398 painter->
drawLine(QLineF(a, y, b, y));
16400 painter->
drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf));
16401 painter->
drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf));
16415 if (x-a > skipSymbolMargin)
16416 painter->
drawLine(QLineF(a, y, x-skipSymbolMargin, y));
16417 if (b-x > skipSymbolMargin)
16418 painter->
drawLine(QLineF(x+skipSymbolMargin, y, b, y));
16420 painter->
drawLine(QLineF(a, y, b, y));
16422 painter->
drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf));
16423 painter->
drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf));
16434 if (a-y > skipSymbolMargin)
16435 painter->
drawLine(QLineF(x, a, x, y+skipSymbolMargin));
16436 if (y-b > skipSymbolMargin)
16437 painter->
drawLine(QLineF(x, y-skipSymbolMargin, x, b));
16439 painter->
drawLine(QLineF(x, a, x, b));
16441 painter->
drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a));
16442 painter->
drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b));
16463 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
16464 if (
mData->isEmpty())
16466 lower =
mData->constEnd();
16467 upper =
mData->constEnd();
16472 QCPDataMap::const_iterator lbound =
mData->lowerBound(
mKeyAxis.data()->range().lower);
16473 QCPDataMap::const_iterator ubound =
mData->upperBound(
mKeyAxis.data()->range().upper);
16474 bool lowoutlier = lbound !=
mData->constBegin();
16475 bool highoutlier = ubound !=
mData->constEnd();
16477 lower = (lowoutlier ? lbound-1 : lbound);
16478 upper = (highoutlier ? ubound : ubound-1);
16493 if (upper ==
mData->constEnd() && lower ==
mData->constEnd())
16495 QCPDataMap::const_iterator it = lower;
16497 while (it != upper && count < maxCount)
16522 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
16525 if (
mKeyAxis.data()->orientation() == Qt::Vertical)
16544 lineData->remove(lineData->size()-2, 2);
16565 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPointF(); }
16573 point.setY(lowerKey);
16577 point.setY(lowerKey);
16580 point.setX(lowerKey);
16584 point.setX(lowerKey);
16598 point.setY(lowerKey);
16601 point.setX(lowerKey);
16630 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPointF(); }
16638 point.setY(upperKey);
16642 point.setY(upperKey);
16645 point.setX(upperKey);
16649 point.setX(upperKey);
16663 point.setY(upperKey);
16666 point.setX(upperKey);
16689 return QPolygonF();
16693 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPolygonF(); }
16694 if (!
mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"channel fill target key axis invalid";
return QPolygonF(); }
16697 return QPolygonF();
16699 if (lineData->isEmpty())
return QPolygonF();
16700 QVector<QPointF> otherData;
16702 if (otherData.isEmpty())
return QPolygonF();
16703 QVector<QPointF> thisData;
16704 thisData.reserve(lineData->size()+otherData.size());
16705 for (
int i=0; i<lineData->size(); ++i)
16706 thisData << lineData->at(i);
16709 QVector<QPointF> *staticData = &thisData;
16710 QVector<QPointF> *croppedData = &otherData;
16717 if (staticData->first().x() > staticData->last().x())
16719 int size = staticData->size();
16720 for (
int i=0; i<size/2; ++i)
16721 qSwap((*staticData)[i], (*staticData)[size-1-i]);
16723 if (croppedData->first().x() > croppedData->last().x())
16725 int size = croppedData->size();
16726 for (
int i=0; i<size/2; ++i)
16727 qSwap((*croppedData)[i], (*croppedData)[size-1-i]);
16730 if (staticData->first().x() < croppedData->first().x())
16731 qSwap(staticData, croppedData);
16732 int lowBound =
findIndexBelowX(croppedData, staticData->first().x());
16733 if (lowBound == -1)
return QPolygonF();
16734 croppedData->remove(0, lowBound);
16737 if (croppedData->size() < 2)
return QPolygonF();
16739 if (croppedData->at(1).x()-croppedData->at(0).x() != 0)
16740 slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x());
16743 (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x()));
16744 (*croppedData)[0].setX(staticData->first().x());
16747 if (staticData->last().x() > croppedData->last().x())
16748 qSwap(staticData, croppedData);
16749 int highBound =
findIndexAboveX(croppedData, staticData->last().x());
16750 if (highBound == -1)
return QPolygonF();
16751 croppedData->remove(highBound+1, croppedData->size()-(highBound+1));
16754 if (croppedData->size() < 2)
return QPolygonF();
16755 int li = croppedData->size()-1;
16756 if (croppedData->at(li).x()-croppedData->at(li-1).x() != 0)
16757 slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x());
16760 (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x()));
16761 (*croppedData)[li].setX(staticData->last().x());
16768 if (staticData->first().y() < staticData->last().y())
16770 int size = staticData->size();
16771 for (
int i=0; i<size/2; ++i)
16772 qSwap((*staticData)[i], (*staticData)[size-1-i]);
16774 if (croppedData->first().y() < croppedData->last().y())
16776 int size = croppedData->size();
16777 for (
int i=0; i<size/2; ++i)
16778 qSwap((*croppedData)[i], (*croppedData)[size-1-i]);
16781 if (staticData->first().y() > croppedData->first().y())
16782 qSwap(staticData, croppedData);
16783 int lowBound =
findIndexAboveY(croppedData, staticData->first().y());
16784 if (lowBound == -1)
return QPolygonF();
16785 croppedData->remove(0, lowBound);
16788 if (croppedData->size() < 2)
return QPolygonF();
16790 if (croppedData->at(1).y()-croppedData->at(0).y() != 0)
16791 slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y());
16794 (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y()));
16795 (*croppedData)[0].setY(staticData->first().y());
16798 if (staticData->last().y() < croppedData->last().y())
16799 qSwap(staticData, croppedData);
16800 int highBound =
findIndexBelowY(croppedData, staticData->last().y());
16801 if (highBound == -1)
return QPolygonF();
16802 croppedData->remove(highBound+1, croppedData->size()-(highBound+1));
16805 if (croppedData->size() < 2)
return QPolygonF();
16806 int li = croppedData->size()-1;
16807 if (croppedData->at(li).y()-croppedData->at(li-1).y() != 0)
16808 slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y());
16811 (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y()));
16812 (*croppedData)[li].setY(staticData->last().y());
16816 for (
int i=otherData.size()-1; i>=0; --i)
16817 thisData << otherData.at(i);
16818 return QPolygonF(thisData);
16830 for (
int i=data->size()-1; i>=0; --i)
16832 if (data->at(i).x() < x)
16834 if (i<data->size()-1)
16837 return data->size()-1;
16852 for (
int i=0; i<data->size(); ++i)
16854 if (data->at(i).x() > x)
16874 for (
int i=0; i<data->size(); ++i)
16876 if (data->at(i).y() < y)
16899 if (
mData->isEmpty())
16901 qDebug() << Q_FUNC_INFO <<
"requested point distance on graph" <<
mName <<
"without data";
16904 if (
mData->size() == 1)
16907 return QVector2D(dataPoint-pixelPoint).length();
16917 QVector<QCPData> *scatterData =
new QVector<QCPData>;
16921 QPointF ptB =
coordsToPixels(scatterData->at(0).key, scatterData->at(0).value);
16922 for (
int i=1; i<scatterData->size(); ++i)
16925 ptB =
coordsToPixels(scatterData->at(i).key, scatterData->at(i).value);
16926 double currentDistSqr =
distSqrToLine(ptA, ptB, pixelPoint);
16927 if (currentDistSqr < minDistSqr)
16928 minDistSqr = currentDistSqr;
16930 delete scatterData;
16931 return qSqrt(minDistSqr);
16935 QVector<QPointF> *lineData =
new QVector<QPointF>;
16941 for (
int i=0; i<lineData->size()-1; i+=2)
16943 double currentDistSqr =
distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint);
16944 if (currentDistSqr < minDistSqr)
16945 minDistSqr = currentDistSqr;
16950 for (
int i=0; i<lineData->size()-1; ++i)
16952 double currentDistSqr =
distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint);
16953 if (currentDistSqr < minDistSqr)
16954 minDistSqr = currentDistSqr;
16958 return qSqrt(minDistSqr);
16972 for (
int i=data->size()-1; i>=0; --i)
16974 if (data->at(i).y() > y)
16976 if (i<data->size()-1)
16979 return data->size()-1;
16990 return getKeyRange(foundRange, inSignDomain,
true);
17010 bool haveLower =
false;
17011 bool haveUpper =
false;
17013 double current, currentErrorMinus, currentErrorPlus;
17015 if (inSignDomain ==
sdBoth)
17017 QCPDataMap::const_iterator it =
mData->constBegin();
17018 while (it !=
mData->constEnd())
17020 current = it.value().key;
17021 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
17022 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
17023 if (current-currentErrorMinus < range.
lower || !haveLower)
17025 range.
lower = current-currentErrorMinus;
17028 if (current+currentErrorPlus > range.
upper || !haveUpper)
17030 range.
upper = current+currentErrorPlus;
17037 QCPDataMap::const_iterator it =
mData->constBegin();
17038 while (it !=
mData->constEnd())
17040 current = it.value().key;
17041 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
17042 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
17043 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus < 0)
17045 range.
lower = current-currentErrorMinus;
17048 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus < 0)
17050 range.
upper = current+currentErrorPlus;
17055 if ((current < range.
lower || !haveLower) && current < 0)
17057 range.
lower = current;
17060 if ((current > range.
upper || !haveUpper) && current < 0)
17062 range.
upper = current;
17070 QCPDataMap::const_iterator it =
mData->constBegin();
17071 while (it !=
mData->constEnd())
17073 current = it.value().key;
17074 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
17075 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
17076 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus > 0)
17078 range.
lower = current-currentErrorMinus;
17081 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus > 0)
17083 range.
upper = current+currentErrorPlus;
17088 if ((current < range.
lower || !haveLower) && current > 0)
17090 range.
lower = current;
17093 if ((current > range.
upper || !haveUpper) && current > 0)
17095 range.
upper = current;
17103 foundRange = haveLower && haveUpper;
17116 bool haveLower =
false;
17117 bool haveUpper =
false;
17119 double current, currentErrorMinus, currentErrorPlus;
17121 if (inSignDomain ==
sdBoth)
17123 QCPDataMap::const_iterator it =
mData->constBegin();
17124 while (it !=
mData->constEnd())
17126 current = it.value().value;
17127 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
17128 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
17129 if (current-currentErrorMinus < range.
lower || !haveLower)
17131 range.
lower = current-currentErrorMinus;
17134 if (current+currentErrorPlus > range.
upper || !haveUpper)
17136 range.
upper = current+currentErrorPlus;
17143 QCPDataMap::const_iterator it =
mData->constBegin();
17144 while (it !=
mData->constEnd())
17146 current = it.value().value;
17147 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
17148 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
17149 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus < 0)
17151 range.
lower = current-currentErrorMinus;
17154 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus < 0)
17156 range.
upper = current+currentErrorPlus;
17161 if ((current < range.
lower || !haveLower) && current < 0)
17163 range.
lower = current;
17166 if ((current > range.
upper || !haveUpper) && current < 0)
17168 range.
upper = current;
17176 QCPDataMap::const_iterator it =
mData->constBegin();
17177 while (it !=
mData->constEnd())
17179 current = it.value().value;
17180 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
17181 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
17182 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus > 0)
17184 range.
lower = current-currentErrorMinus;
17187 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus > 0)
17189 range.
upper = current+currentErrorPlus;
17194 if ((current < range.
lower || !haveLower) && current > 0)
17196 range.
lower = current;
17199 if ((current > range.
upper || !haveUpper) && current > 0)
17201 range.
upper = current;
17209 foundRange = haveLower && haveUpper;
17301 mPen.setColor(Qt::blue);
17302 mPen.setStyle(Qt::SolidLine);
17303 mBrush.setColor(Qt::blue);
17304 mBrush.setStyle(Qt::NoBrush);
17330 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
17349 void QCPCurve::setData(
const QVector<double> &t,
const QVector<double> &key,
const QVector<double> &value)
17353 n = qMin(n, key.size());
17354 n = qMin(n, value.size());
17356 for (
int i=0; i<n; ++i)
17359 newData.key = key[i];
17360 newData.value = value[i];
17361 mData->insertMulti(newData.t, newData);
17373 int n = key.size();
17374 n = qMin(n, value.size());
17376 for (
int i=0; i<n; ++i)
17379 newData.key = key[i];
17380 newData.value = value[i];
17381 mData->insertMulti(newData.t, newData);
17415 mData->unite(dataMap);
17424 mData->insertMulti(data.
t, data);
17436 newData.
value = value;
17437 mData->insertMulti(newData.
t, newData);
17451 if (!
mData->isEmpty())
17452 newData.
t = (
mData->constEnd()-1).key()+1;
17456 newData.
value = value;
17457 mData->insertMulti(newData.
t, newData);
17464 void QCPCurve::addData(
const QVector<double> &ts,
const QVector<double> &keys,
const QVector<double> &values)
17467 n = qMin(n, keys.size());
17468 n = qMin(n, values.size());
17470 for (
int i=0; i<n; ++i)
17473 newData.key = keys[i];
17474 newData.value = values[i];
17475 mData->insertMulti(newData.t, newData);
17485 QCPCurveDataMap::iterator it =
mData->begin();
17486 while (it !=
mData->end() && it.key() < t)
17487 it =
mData->erase(it);
17496 if (
mData->isEmpty())
return;
17497 QCPCurveDataMap::iterator it =
mData->upperBound(t);
17498 while (it !=
mData->end())
17499 it =
mData->erase(it);
17511 if (fromt >= tot ||
mData->isEmpty())
return;
17512 QCPCurveDataMap::iterator it =
mData->upperBound(fromt);
17513 QCPCurveDataMap::iterator itEnd =
mData->upperBound(tot);
17514 while (it != itEnd)
17515 it =
mData->erase(it);
17547 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
17549 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
17558 if (
mData->isEmpty())
return;
17561 QVector<QPointF> *lineData =
new QVector<QPointF>;
17567 #ifdef QCUSTOMPLOT_CHECK_DATA 17568 QCPCurveDataMap::const_iterator it;
17569 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
17573 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"invalid." <<
"Plottable name:" <<
name();
17581 painter->
setPen(Qt::NoPen);
17583 painter->drawPolygon(QPolygonF(*lineData));
17591 painter->setBrush(Qt::NoBrush);
17594 painter->pen().style() == Qt::SolidLine &&
17599 int lineDataSize = lineData->size();
17600 while (i < lineDataSize)
17602 if (!qIsNaN(lineData->at(i).y()) && !qIsNaN(lineData->at(i).x()))
17603 painter->
drawLine(lineData->at(i-1), lineData->at(i));
17610 int segmentStart = 0;
17612 int lineDataSize = lineData->size();
17613 while (i < lineDataSize)
17615 if (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x()))
17617 painter->drawPolyline(lineData->constData()+segmentStart, i-segmentStart);
17618 segmentStart = i+1;
17623 painter->drawPolyline(lineData->constData()+segmentStart, lineDataSize-segmentStart);
17639 if (
mBrush.style() != Qt::NoBrush)
17642 painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0),
mBrush);
17649 painter->
drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0));
17659 scaledStyle.
setPixmap(scaledStyle.
pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
17661 scaledStyle.
drawShape(painter, QRectF(rect).center());
17680 for (
int i=0; i<pointData->size(); ++i)
17681 if (!qIsNaN(pointData->at(i).x()) && !qIsNaN(pointData->at(i).y()))
17702 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
17705 double strokeMargin = qMax(qreal(1.0), qreal(
mainPen().widthF()*0.75));
17713 QCPCurveDataMap::const_iterator it =
mData->constBegin();
17714 QCPCurveDataMap::const_iterator prevIt =
mData->constEnd()-1;
17715 int prevRegion =
getRegion(prevIt.value().key, prevIt.value().value, rectLeft, rectTop, rectRight, rectBottom);
17716 QVector<QPointF> trailingPoints;
17717 while (it !=
mData->constEnd())
17719 currentRegion =
getRegion(it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17720 if (currentRegion != prevRegion)
17722 if (currentRegion != 5)
17724 QPointF crossA, crossB;
17725 if (prevRegion == 5)
17727 lineData->append(
getOptimizedPoint(currentRegion, it.value().key, it.value().value, prevIt.value().key, prevIt.value().value, rectLeft, rectTop, rectRight, rectBottom));
17729 *lineData <<
getOptimizedCornerPoints(prevRegion, currentRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17730 }
else if (
mayTraverse(prevRegion, currentRegion) &&
17731 getTraverse(prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom, crossA, crossB))
17734 QVector<QPointF> beforeTraverseCornerPoints, afterTraverseCornerPoints;
17735 getTraverseCornerPoints(prevRegion, currentRegion, rectLeft, rectTop, rectRight, rectBottom, beforeTraverseCornerPoints, afterTraverseCornerPoints);
17736 if (it !=
mData->constBegin())
17738 *lineData << beforeTraverseCornerPoints;
17739 lineData->append(crossA);
17740 lineData->append(crossB);
17741 *lineData << afterTraverseCornerPoints;
17744 lineData->append(crossB);
17745 *lineData << afterTraverseCornerPoints;
17746 trailingPoints << beforeTraverseCornerPoints << crossA ;
17750 *lineData <<
getOptimizedCornerPoints(prevRegion, currentRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17754 if (it ==
mData->constBegin())
17755 trailingPoints <<
getOptimizedPoint(prevRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17757 lineData->append(
getOptimizedPoint(prevRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom));
17758 lineData->append(
coordsToPixels(it.value().key, it.value().value));
17762 if (currentRegion == 5)
17764 lineData->append(
coordsToPixels(it.value().key, it.value().value));
17771 prevRegion = currentRegion;
17774 *lineData << trailingPoints;
17795 int QCPCurve::getRegion(
double x,
double y,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom)
const 17801 else if (y < rectBottom)
17805 }
else if (x > rectRight)
17809 else if (y < rectBottom)
17817 else if (y < rectBottom)
17839 QPointF
QCPCurve::getOptimizedPoint(
int otherRegion,
double otherKey,
double otherValue,
double key,
double value,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom)
const 17841 double intersectKey = rectLeft;
17842 double intersectValue = rectTop;
17843 switch (otherRegion)
17847 intersectValue = rectTop;
17848 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17849 if (intersectKey < rectLeft || intersectKey > rectRight)
17851 intersectKey = rectLeft;
17852 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17858 intersectKey = rectLeft;
17859 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17864 intersectValue = rectBottom;
17865 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17866 if (intersectKey < rectLeft || intersectKey > rectRight)
17868 intersectKey = rectLeft;
17869 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17875 intersectValue = rectTop;
17876 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17885 intersectValue = rectBottom;
17886 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17891 intersectValue = rectTop;
17892 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17893 if (intersectKey < rectLeft || intersectKey > rectRight)
17895 intersectKey = rectRight;
17896 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17902 intersectKey = rectRight;
17903 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17908 intersectValue = rectBottom;
17909 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17910 if (intersectKey < rectLeft || intersectKey > rectRight)
17912 intersectKey = rectRight;
17913 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17939 QVector<QPointF>
QCPCurve::getOptimizedCornerPoints(
int prevRegion,
int currentRegion,
double prevKey,
double prevValue,
double key,
double value,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom)
const 17941 QVector<QPointF> result;
17942 switch (prevRegion)
17946 switch (currentRegion)
17955 if ((value-prevValue)/(key-prevKey)*(rectLeft-key)+value < rectBottom)
17966 switch (currentRegion)
17969 case 3: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17970 case 4: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last());
break; }
17971 case 6: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last());
break; }
17972 case 7: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last()); result <<
coordsToPixels(rectRight, rectTop);
break; }
17973 case 9: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectRight, rectBottom);
break; }
17979 switch (currentRegion)
17981 case 2: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17982 case 6: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17986 case 8: { result <<
coordsToPixels(rectLeft, rectBottom) <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
17988 if ((value-prevValue)/(key-prevKey)*(rectRight-key)+value < rectBottom)
17999 switch (currentRegion)
18002 case 7: { result <<
coordsToPixels(rectRight, rectTop);
break; }
18003 case 2: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last());
break; }
18004 case 8: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last());
break; }
18005 case 3: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectBottom);
break; }
18006 case 9: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last()); result <<
coordsToPixels(rectRight, rectBottom);
break; }
18012 switch (currentRegion)
18015 case 7: { result <<
coordsToPixels(rectRight, rectTop);
break; }
18016 case 9: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
18017 case 3: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
18023 switch (currentRegion)
18025 case 3: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
18026 case 9: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
18027 case 2: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last());
break; }
18028 case 8: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
18029 case 1: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectTop);
break; }
18030 case 7: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectRight, rectTop);
break; }
18036 switch (currentRegion)
18038 case 4: { result <<
coordsToPixels(rectRight, rectTop);
break; }
18039 case 8: { result <<
coordsToPixels(rectRight, rectTop);
break; }
18043 case 6: { result <<
coordsToPixels(rectRight, rectTop) <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
18045 if ((value-prevValue)/(key-prevKey)*(rectRight-key)+value < rectBottom)
18056 switch (currentRegion)
18058 case 7: { result <<
coordsToPixels(rectRight, rectTop);
break; }
18059 case 9: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
18060 case 4: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last());
break; }
18061 case 6: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
18062 case 1: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectTop);
break; }
18063 case 3: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectBottom);
break; }
18069 switch (currentRegion)
18071 case 6: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
18072 case 8: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
18075 case 2: { result <<
coordsToPixels(rectRight, rectBottom) <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last());
break; }
18076 case 4: { result <<
coordsToPixels(rectRight, rectBottom) <<
coordsToPixels(rectRight, rectTop); result.append(result.last());
break; }
18078 if ((value-prevValue)/(key-prevKey)*(rectLeft-key)+value < rectBottom)
18105 switch (prevRegion)
18109 switch (currentRegion)
18114 case 3:
return false;
18115 default:
return true;
18120 switch (currentRegion)
18123 case 3:
return false;
18124 default:
return true;
18129 switch (currentRegion)
18134 case 9:
return false;
18135 default:
return true;
18140 switch (currentRegion)
18143 case 7:
return false;
18144 default:
return true;
18147 case 5:
return false;
18150 switch (currentRegion)
18153 case 9:
return false;
18154 default:
return true;
18159 switch (currentRegion)
18164 case 9:
return false;
18165 default:
return true;
18170 switch (currentRegion)
18173 case 9:
return false;
18174 default:
return true;
18179 switch (currentRegion)
18184 case 7:
return false;
18185 default:
return true;
18188 default:
return true;
18206 bool QCPCurve::getTraverse(
double prevKey,
double prevValue,
double key,
double value,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom, QPointF &crossA, QPointF &crossB)
const 18208 QList<QPointF> intersections;
18209 if (qFuzzyIsNull(key-prevKey))
18212 intersections.append(QPointF(key, rectBottom));
18213 intersections.append(QPointF(key, rectTop));
18214 }
else if (qFuzzyIsNull(value-prevValue))
18217 intersections.append(QPointF(rectLeft, value));
18218 intersections.append(QPointF(rectRight, value));
18222 double keyPerValue = (key-prevKey)/(value-prevValue);
18224 gamma = prevKey + (rectTop-prevValue)*keyPerValue;
18225 if (gamma >= rectLeft && gamma <= rectRight)
18226 intersections.append(QPointF(gamma, rectTop));
18228 gamma = prevKey + (rectBottom-prevValue)*keyPerValue;
18229 if (gamma >= rectLeft && gamma <= rectRight)
18230 intersections.append(QPointF(gamma, rectBottom));
18231 double valuePerKey = 1.0/keyPerValue;
18233 gamma = prevValue + (rectLeft-prevKey)*valuePerKey;
18234 if (gamma >= rectBottom && gamma <= rectTop)
18235 intersections.append(QPointF(rectLeft, gamma));
18237 gamma = prevValue + (rectRight-prevKey)*valuePerKey;
18238 if (gamma >= rectBottom && gamma <= rectTop)
18239 intersections.append(QPointF(rectRight, gamma));
18243 if (intersections.size() > 2)
18246 double distSqrMax = 0;
18248 for (
int i=0; i<intersections.size()-1; ++i)
18250 for (
int k=i+1; k<intersections.size(); ++k)
18252 QPointF distPoint = intersections.at(i)-intersections.at(k);
18253 double distSqr = distPoint.x()*distPoint.x()+distPoint.y()+distPoint.y();
18254 if (distSqr > distSqrMax)
18256 pv1 = intersections.at(i);
18257 pv2 = intersections.at(k);
18258 distSqrMax = distSqr;
18262 intersections = QList<QPointF>() << pv1 << pv2;
18263 }
else if (intersections.size() != 2)
18270 if ((key-prevKey)*(intersections.at(1).x()-intersections.at(0).x()) + (value-prevValue)*(intersections.at(1).y()-intersections.at(0).y()) < 0)
18271 intersections.move(0, 1);
18272 crossA =
coordsToPixels(intersections.at(0).x(), intersections.at(0).y());
18273 crossB =
coordsToPixels(intersections.at(1).x(), intersections.at(1).y());
18302 void QCPCurve::getTraverseCornerPoints(
int prevRegion,
int currentRegion,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom, QVector<QPointF> &beforeTraverse, QVector<QPointF> &afterTraverse)
const 18304 switch (prevRegion)
18308 switch (currentRegion)
18310 case 6: { beforeTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
18312 case 8: { beforeTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
18318 switch (currentRegion)
18320 case 7: { afterTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
18321 case 9: { afterTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
18327 switch (currentRegion)
18329 case 4: { beforeTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
18331 case 8: { beforeTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
18337 switch (currentRegion)
18339 case 3: { afterTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
18340 case 9: { afterTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
18347 switch (currentRegion)
18349 case 1: { afterTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
18350 case 7: { afterTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
18356 switch (currentRegion)
18358 case 2: { beforeTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
18360 case 6: { beforeTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
18366 switch (currentRegion)
18368 case 1: { afterTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
18369 case 3: { afterTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
18375 switch (currentRegion)
18377 case 2: { beforeTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
18379 case 4: { beforeTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
18394 if (
mData->isEmpty())
18396 qDebug() << Q_FUNC_INFO <<
"requested point distance on curve" <<
mName <<
"without data";
18399 if (
mData->size() == 1)
18402 return QVector2D(dataPoint-pixelPoint).length();
18406 QVector<QPointF> *lineData =
new QVector<QPointF>;
18409 for (
int i=0; i<lineData->size()-1; ++i)
18411 double currentDistSqr =
distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint);
18412 if (currentDistSqr < minDistSqr)
18413 minDistSqr = currentDistSqr;
18416 return qSqrt(minDistSqr);
18423 bool haveLower =
false;
18424 bool haveUpper =
false;
18428 QCPCurveDataMap::const_iterator it =
mData->constBegin();
18429 while (it !=
mData->constEnd())
18431 current = it.value().key;
18434 if (current < range.
lower || !haveLower)
18436 range.
lower = current;
18439 if (current > range.
upper || !haveUpper)
18441 range.
upper = current;
18448 foundRange = haveLower && haveUpper;
18456 bool haveLower =
false;
18457 bool haveUpper =
false;
18461 QCPCurveDataMap::const_iterator it =
mData->constBegin();
18462 while (it !=
mData->constEnd())
18464 current = it.value().value;
18467 if (current < range.
lower || !haveLower)
18469 range.
lower = current;
18472 if (current > range.
upper || !haveUpper)
18474 range.
upper = current;
18481 foundRange = haveLower && haveUpper;
18557 QObject(parentPlot),
18559 mSpacingType(stAbsolute),
18600 if (index >= 0 && index <
mBars.size())
18602 return mBars.at(index);
18605 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
18631 qDebug() << Q_FUNC_INFO <<
"bars is 0";
18635 if (!
mBars.contains(bars))
18638 qDebug() << Q_FUNC_INFO <<
"bars plottable is already in this bars group:" <<
reinterpret_cast<quintptr
>(
bars);
18654 qDebug() << Q_FUNC_INFO <<
"bars is 0";
18659 if (!
mBars.contains(bars))
18674 qDebug() << Q_FUNC_INFO <<
"bars is 0";
18678 if (
mBars.contains(bars))
18681 qDebug() << Q_FUNC_INFO <<
"bars plottable is not in this bars group:" <<
reinterpret_cast<quintptr
>(
bars);
18693 if (!
mBars.contains(bars))
18694 mBars.append(bars);
18706 mBars.removeOne(bars);
18718 QList<const QCPBars*> baseBars;
18723 if (!baseBars.contains(b))
18724 baseBars.append(b);
18733 int index = baseBars.indexOf(thisBase);
18737 double lowerPixelWidth, upperPixelWidth;
18738 if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2)
18741 }
else if (index < (baseBars.size()-1)/2.0)
18743 if (baseBars.size() % 2 == 0)
18745 startIndex = baseBars.size()/2-1;
18749 startIndex = (baseBars.size()-1)/2-1;
18750 baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18751 result -= qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18752 result -=
getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord);
18754 for (
int i=startIndex; i>index; --i)
18756 baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18757 result -= qAbs(upperPixelWidth-lowerPixelWidth);
18761 baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18762 result -= qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18765 if (baseBars.size() % 2 == 0)
18767 startIndex = baseBars.size()/2;
18771 startIndex = (baseBars.size()-1)/2+1;
18772 baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18773 result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18774 result +=
getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord);
18776 for (
int i=startIndex; i<index; ++i)
18778 baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18779 result += qAbs(upperPixelWidth-lowerPixelWidth);
18783 baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18784 result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18934 mWidthType(wtPlotCoords),
18939 mPen.setColor(Qt::blue);
18940 mPen.setStyle(Qt::SolidLine);
18941 mBrush.setColor(QColor(40, 50, 255, 30));
18942 mBrush.setStyle(Qt::SolidPattern);
19026 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
19048 int n = key.size();
19049 n = qMin(n, value.size());
19051 for (
int i=0; i<n; ++i)
19053 newData.
key = key[i];
19054 newData.value = value[i];
19055 mData->insertMulti(newData.key, newData);
19075 if (bars ==
this)
return;
19078 qDebug() << Q_FUNC_INFO <<
"passed QCPBars* doesn't have same key and value axis as this QCPBars";
19108 if (bars ==
this)
return;
19111 qDebug() << Q_FUNC_INFO <<
"passed QCPBars* doesn't have same key and value axis as this QCPBars";
19131 mData->unite(dataMap);
19140 mData->insertMulti(data.
key, data);
19151 newData.
value = value;
19152 mData->insertMulti(newData.
key, newData);
19161 int n = keys.size();
19162 n = qMin(n, values.size());
19164 for (
int i=0; i<n; ++i)
19166 newData.
key = keys[i];
19167 newData.value = values[i];
19168 mData->insertMulti(newData.key, newData);
19178 QCPBarDataMap::iterator it =
mData->begin();
19179 while (it !=
mData->end() && it.key() < key)
19180 it =
mData->erase(it);
19189 if (
mData->isEmpty())
return;
19190 QCPBarDataMap::iterator it =
mData->upperBound(key);
19191 while (it !=
mData->end())
19192 it =
mData->erase(it);
19204 if (fromKey >= toKey ||
mData->isEmpty())
return;
19205 QCPBarDataMap::iterator it =
mData->upperBound(fromKey);
19206 QCPBarDataMap::iterator itEnd =
mData->upperBound(toKey);
19207 while (it != itEnd)
19208 it =
mData->erase(it);
19221 mData->remove(key);
19239 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
19241 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
19243 QCPBarDataMap::ConstIterator it;
19244 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
19246 if (
getBarPolygon(it.value().key, it.value().value).boundingRect().contains(pos))
19256 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
19257 if (
mData->isEmpty())
return;
19259 QCPBarDataMap::const_iterator it, lower, upperEnd;
19261 for (it = lower; it != upperEnd; ++it)
19264 #ifdef QCUSTOMPLOT_CHECK_DATA 19266 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"of drawn range invalid." <<
"Plottable name:" <<
name();
19268 QPolygonF barPolygon =
getBarPolygon(it.key(), it.value().value);
19273 painter->
setPen(Qt::NoPen);
19275 painter->drawPolygon(barPolygon);
19278 if (
mainPen().style() != Qt::NoPen &&
mainPen().color().alpha() != 0)
19282 painter->setBrush(Qt::NoBrush);
19283 painter->drawPolyline(barPolygon);
19293 painter->setBrush(
mBrush);
19295 QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67);
19296 r.moveCenter(rect.center());
19297 painter->drawRect(r);
19316 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
19317 if (
mData->isEmpty())
19319 lower =
mData->constEnd();
19320 upperEnd =
mData->constEnd();
19326 upperEnd =
mData->upperBound(
mKeyAxis.data()->range().upper);
19327 double lowerPixelBound =
mKeyAxis.data()->coordToPixel(
mKeyAxis.data()->range().lower);
19328 double upperPixelBound =
mKeyAxis.data()->coordToPixel(
mKeyAxis.data()->range().upper);
19329 bool isVisible =
false;
19331 QCPBarDataMap::const_iterator it = lower;
19332 while (it !=
mData->constBegin())
19335 QRectF barBounds =
getBarPolygon(it.value().key, it.value().value).boundingRect();
19336 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
19337 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.right() >= lowerPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.left() <= lowerPixelBound));
19339 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.top() <= lowerPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.bottom() >= lowerPixelBound));
19347 while (it !=
mData->constEnd())
19349 QRectF barBounds =
getBarPolygon(upperEnd.value().key, upperEnd.value().value).boundingRect();
19350 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
19351 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.left() <= upperPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.right() >= upperPixelBound));
19353 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.bottom() >= upperPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.top() <= upperPixelBound));
19372 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPolygonF(); }
19375 double lowerPixelWidth, upperPixelWidth;
19379 double valuePixel = valueAxis->
coordToPixel(base+value);
19385 result << QPointF(keyPixel+lowerPixelWidth, basePixel);
19386 result << QPointF(keyPixel+lowerPixelWidth, valuePixel);
19387 result << QPointF(keyPixel+upperPixelWidth, valuePixel);
19388 result << QPointF(keyPixel+upperPixelWidth, basePixel);
19391 result << QPointF(basePixel, keyPixel+lowerPixelWidth);
19392 result << QPointF(valuePixel, keyPixel+lowerPixelWidth);
19393 result << QPointF(valuePixel, keyPixel+upperPixelWidth);
19394 result << QPointF(basePixel, keyPixel+upperPixelWidth);
19417 qSwap(lower, upper);
19424 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
19430 qSwap(lower, upper);
19432 qDebug() << Q_FUNC_INFO <<
"No key axis or axis rect defined";
19439 double keyPixel =
mKeyAxis.data()->coordToPixel(key);
19445 qDebug() << Q_FUNC_INFO <<
"No key axis defined";
19466 double epsilon = qAbs(key)*1e-6;
19469 QCPBarDataMap::const_iterator it =
mBarBelow.data()->mData->lowerBound(key-epsilon);
19470 QCPBarDataMap::const_iterator itEnd =
mBarBelow.data()->mData->upperBound(key+epsilon);
19471 while (it != itEnd)
19473 if ((positive && it.value().value >
max) ||
19474 (!positive && it.value().value <
max))
19475 max = it.value().value;
19479 return max +
mBarBelow.data()->getStackedBaseValue(key, positive);
19494 if (!lower && !upper)
return;
19500 upper->
mBarBelow.data()->mBarAbove = 0;
19506 lower->
mBarAbove.data()->mBarBelow = 0;
19512 lower->
mBarAbove.data()->mBarBelow = 0;
19515 upper->
mBarBelow.data()->mBarAbove = 0;
19525 bool haveLower =
false;
19526 bool haveUpper =
false;
19529 QCPBarDataMap::const_iterator it =
mData->constBegin();
19530 while (it !=
mData->constEnd())
19532 current = it.value().key;
19535 if (current < range.
lower || !haveLower)
19537 range.
lower = current;
19540 if (current > range.
upper || !haveUpper)
19542 range.
upper = current;
19551 double lowerPixelWidth, upperPixelWidth, keyPixel;
19553 keyPixel =
mKeyAxis.data()->coordToPixel(range.
lower) + lowerPixelWidth;
19560 double lowerPixelWidth, upperPixelWidth, keyPixel;
19562 keyPixel =
mKeyAxis.data()->coordToPixel(range.
upper) + upperPixelWidth;
19567 foundRange = haveLower && haveUpper;
19577 bool haveLower =
true;
19578 bool haveUpper =
true;
19581 QCPBarDataMap::const_iterator it =
mData->constBegin();
19582 while (it !=
mData->constEnd())
19587 if (current < range.
lower || !haveLower)
19589 range.
lower = current;
19592 if (current > range.
upper || !haveUpper)
19594 range.
upper = current;
19685 setPen(QPen(Qt::black));
19687 setMedianPen(QPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap));
19688 setWhiskerPen(QPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap));
19867 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
19869 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
19871 double posKey, posValue;
19889 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
19892 #ifdef QCUSTOMPLOT_CHECK_DATA 19896 qDebug() << Q_FUNC_INFO <<
"Data point at" <<
mKey <<
"of drawn range has invalid data." <<
"Plottable name:" <<
name();
19899 qDebug() << Q_FUNC_INFO <<
"Data point outlier at" <<
mKey <<
"of drawn range invalid." <<
"Plottable name:" <<
name();
19902 QRectF quartileBox;
19906 painter->setClipRect(quartileBox, Qt::IntersectClip);
19920 painter->setBrush(
mBrush);
19921 QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67);
19922 r.moveCenter(rect.center());
19923 painter->drawRect(r);
19940 painter->drawRect(box);
19942 *quartileBox = box;
19965 QLineF backboneMin, backboneMax, barMin, barMax;
19995 if (inSignDomain ==
sdBoth)
20006 foundRange =
false;
20017 foundRange =
false;
20021 foundRange =
false;
20028 QVector<double> values;
20033 bool haveUpper =
false;
20034 bool haveLower =
false;
20037 for (
int i=0; i<values.size(); ++i)
20039 if ((inSignDomain ==
sdNegative && values.at(i) < 0) ||
20040 (inSignDomain ==
sdPositive && values.at(i) > 0) ||
20041 (inSignDomain ==
sdBoth))
20043 if (values.at(i) > upper || !haveUpper)
20045 upper = values.at(i);
20048 if (values.at(i) < lower || !haveLower)
20050 lower = values.at(i);
20056 if (haveLower && haveUpper)
20062 foundRange =
false;
20120 mKeyRange(keyRange),
20121 mValueRange(valueRange),
20124 mDataModified(true)
20154 if (&other !=
this)
20173 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell <
mValueSize)
20182 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex <
mValueSize)
20211 #ifdef __EXCEPTIONS 20215 #ifdef __EXCEPTIONS 20216 }
catch (...) {
mData = 0; }
20221 qDebug() << Q_FUNC_INFO <<
"out of memory for data dimensions "<<
mKeySize <<
"*" <<
mValueSize;
20314 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell <
mValueSize)
20338 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex <
mValueSize)
20366 double minHeight =
mData[0];
20367 double maxHeight =
mData[0];
20369 for (
int i=0; i<dataCount; ++i)
20371 if (
mData[i] > maxHeight)
20372 maxHeight =
mData[i];
20373 if (
mData[i] < minHeight)
20374 minHeight =
mData[i];
20397 for (
int i=0; i<dataCount; ++i)
20562 mDataScaleType(
QCPAxis::stLinear),
20564 mInterpolate(true),
20565 mTightBoundary(false),
20566 mMapImageInvalidated(true)
20586 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
20749 if (recalculateDataBounds)
20777 mLegendIcon = QPixmap::fromImage(
mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode);
20796 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
20798 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
20800 double posKey, posValue;
20820 if (!keyAxis)
return;
20834 const int lineCount = valueSize;
20835 const int rowCount = keySize;
20836 for (
int line=0; line<lineCount; ++line)
20838 QRgb* pixels =
reinterpret_cast<QRgb*
>(
mMapImage.scanLine(lineCount-1-line));
20843 const int lineCount = keySize;
20844 const int rowCount = valueSize;
20845 for (
int line=0; line<lineCount; ++line)
20847 QRgb* pixels =
reinterpret_cast<QRgb*
>(
mMapImage.scanLine(lineCount-1-line));
20866 double halfSampleKey = 0;
20867 double halfSampleValue = 0;
20874 imageRect = imageRect.normalized();
20877 bool smoothBackup = painter->renderHints().testFlag(QPainter::SmoothPixmapTransform);
20878 painter->setRenderHint(QPainter::SmoothPixmapTransform,
mInterpolate);
20879 QRegion clipBackup;
20882 clipBackup = painter->clipRegion();
20886 painter->drawImage(imageRect,
mMapImage.mirrored(mirrorX, mirrorY));
20888 painter->setClipRegion(clipBackup);
20889 painter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup);
20899 QPixmap scaledIcon =
mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation);
20900 QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height());
20901 iconRect.moveCenter(rect.center());
20902 painter->drawPixmap(iconRect.topLeft(), scaledIcon);
20922 else if (result.
lower <= 0 && result.
upper <= 0)
20923 foundRange =
false;
20928 else if (result.
upper >= 0 && result.
lower >= 0)
20929 foundRange =
false;
20944 else if (result.
lower <= 0 && result.
upper <= 0)
20945 foundRange =
false;
20950 else if (result.
upper >= 0 && result.
lower >= 0)
20951 foundRange =
false;
21060 mChartStyle(csOhlc),
21062 mTwoColored(false),
21063 mBrushPositive(QBrush(QColor(210, 210, 255))),
21064 mBrushNegative(QBrush(QColor(255, 210, 210))),
21065 mPenPositive(QPen(QColor(10, 40, 180))),
21066 mPenNegative(QPen(QColor(180, 40, 10)))
21095 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
21115 void QCPFinancial::setData(
const QVector<double> &key,
const QVector<double> &open,
const QVector<double> &high,
const QVector<double> &low,
const QVector<double> &close)
21118 int n = key.size();
21119 n = qMin(n, open.size());
21120 n = qMin(n, high.size());
21121 n = qMin(n, low.size());
21122 n = qMin(n, close.size());
21123 for (
int i=0; i<n; ++i)
21227 mData->unite(dataMap);
21241 mData->insertMulti(data.
key, data);
21268 void QCPFinancial::addData(
const QVector<double> &key,
const QVector<double> &open,
const QVector<double> &high,
const QVector<double> &low,
const QVector<double> &close)
21270 int n = key.size();
21271 n = qMin(n, open.size());
21272 n = qMin(n, high.size());
21273 n = qMin(n, low.size());
21274 n = qMin(n, close.size());
21275 for (
int i=0; i<n; ++i)
21288 QCPFinancialDataMap::iterator it =
mData->begin();
21289 while (it !=
mData->end() && it.key() < key)
21290 it =
mData->erase(it);
21300 if (
mData->isEmpty())
return;
21301 QCPFinancialDataMap::iterator it =
mData->upperBound(key);
21302 while (it !=
mData->end())
21303 it =
mData->erase(it);
21315 if (fromKey >= toKey ||
mData->isEmpty())
return;
21316 QCPFinancialDataMap::iterator it =
mData->upperBound(fromKey);
21317 QCPFinancialDataMap::iterator itEnd =
mData->upperBound(toKey);
21318 while (it != itEnd)
21319 it =
mData->erase(it);
21332 mData->remove(key);
21351 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
21353 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
21356 QCPFinancialDataMap::const_iterator lower, upper;
21358 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
21388 int count = qMin(time.size(), value.size());
21392 QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first());
21393 int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5);
21394 for (
int i=0; i<count; ++i)
21396 int index = qFloor((time.at(i)-timeBinOffset)/timeBinSize+0.5);
21397 if (currentBinIndex == index)
21399 if (value.at(i) < currentBinData.low) currentBinData.low = value.at(i);
21400 if (value.at(i) > currentBinData.high) currentBinData.high = value.at(i);
21403 currentBinData.close = value.at(i);
21404 currentBinData.key = timeBinOffset+(index)*timeBinSize;
21405 map.insert(currentBinData.key, currentBinData);
21410 currentBinData.close = value.at(i-1);
21411 currentBinData.key = timeBinOffset+(index-1)*timeBinSize;
21412 map.insert(currentBinData.key, currentBinData);
21414 currentBinIndex = index;
21415 currentBinData.open = value.at(i);
21416 currentBinData.high = value.at(i);
21417 currentBinData.low = value.at(i);
21428 QCPFinancialDataMap::const_iterator lower, upper;
21430 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
21454 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint()));
21455 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21456 painter->
drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
21457 painter->
drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
21461 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint()));
21462 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21463 painter->
drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
21464 painter->
drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
21467 painter->setBrush(
mBrush);
21469 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21470 painter->
drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
21471 painter->
drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
21480 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint()));
21481 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
21482 painter->
drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21483 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
21487 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint()));
21488 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
21489 painter->
drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21490 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
21493 painter->setBrush(
mBrush);
21495 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
21496 painter->
drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21497 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
21506 bool haveLower =
false;
21507 bool haveUpper =
false;
21510 QCPFinancialDataMap::const_iterator it =
mData->constBegin();
21511 while (it !=
mData->constEnd())
21513 current = it.value().key;
21516 if (current < range.
lower || !haveLower)
21518 range.
lower = current;
21521 if (current > range.
upper || !haveUpper)
21523 range.
upper = current;
21534 foundRange = haveLower && haveUpper;
21542 bool haveLower =
false;
21543 bool haveUpper =
false;
21545 QCPFinancialDataMap::const_iterator it =
mData->constBegin();
21546 while (it !=
mData->constEnd())
21549 if (inSignDomain ==
sdBoth || (inSignDomain ==
sdNegative && it.value().high < 0) || (inSignDomain ==
sdPositive && it.value().high > 0))
21551 if (it.value().high < range.
lower || !haveLower)
21553 range.
lower = it.value().high;
21556 if (it.value().high > range.
upper || !haveUpper)
21558 range.
upper = it.value().high;
21563 if (inSignDomain ==
sdBoth || (inSignDomain ==
sdNegative && it.value().low < 0) || (inSignDomain ==
sdPositive && it.value().low > 0))
21565 if (it.value().low < range.
lower || !haveLower)
21567 range.
lower = it.value().low;
21570 if (it.value().low > range.
upper || !haveUpper)
21572 range.
upper = it.value().low;
21579 foundRange = haveLower && haveUpper;
21593 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
21599 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it)
21607 painter->
setPen(linePen);
21608 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21609 double openPixel = valueAxis->
coordToPixel(it.value().open);
21610 double closePixel = valueAxis->
coordToPixel(it.value().close);
21615 painter->
drawLine(QPointF(keyPixel-keyWidthPixels, openPixel), QPointF(keyPixel, openPixel));
21617 painter->
drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+keyWidthPixels, closePixel));
21621 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it)
21629 painter->
setPen(linePen);
21630 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21631 double openPixel = valueAxis->
coordToPixel(it.value().open);
21632 double closePixel = valueAxis->
coordToPixel(it.value().close);
21637 painter->
drawLine(QPointF(openPixel, keyPixel-keyWidthPixels), QPointF(openPixel, keyPixel));
21639 painter->
drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+keyWidthPixels));
21654 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
21661 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it)
21669 if (it.value().close >= it.value().open)
21683 painter->
setPen(linePen);
21684 painter->setBrush(boxBrush);
21685 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21686 double openPixel = valueAxis->
coordToPixel(it.value().open);
21687 double closePixel = valueAxis->
coordToPixel(it.value().close);
21689 painter->
drawLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->
coordToPixel(qMax(it.value().open, it.value().close))));
21691 painter->
drawLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().low)), QPointF(keyPixel, valueAxis->
coordToPixel(qMin(it.value().open, it.value().close))));
21694 painter->drawRect(QRectF(QPointF(keyPixel-keyWidthPixels, closePixel), QPointF(keyPixel+keyWidthPixels, openPixel)));
21698 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it)
21706 if (it.value().close >= it.value().open)
21720 painter->
setPen(linePen);
21721 painter->setBrush(boxBrush);
21722 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21723 double openPixel = valueAxis->
coordToPixel(it.value().open);
21724 double closePixel = valueAxis->
coordToPixel(it.value().close);
21726 painter->
drawLine(QPointF(valueAxis->
coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->
coordToPixel(qMax(it.value().open, it.value().close)), keyPixel));
21728 painter->
drawLine(QPointF(valueAxis->
coordToPixel(it.value().low), keyPixel), QPointF(valueAxis->
coordToPixel(qMin(it.value().open, it.value().close)), keyPixel));
21731 painter->drawRect(QRectF(QPointF(closePixel, keyPixel-keyWidthPixels), QPointF(openPixel, keyPixel+keyWidthPixels)));
21741 double QCPFinancial::ohlcSelectTest(
const QPointF &pos,
const QCPFinancialDataMap::const_iterator &begin,
const QCPFinancialDataMap::const_iterator &end)
const 21745 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
21748 QCPFinancialDataMap::const_iterator it;
21751 for (it = begin; it != end; ++it)
21753 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21756 if (currentDistSqr < minDistSqr)
21757 minDistSqr = currentDistSqr;
21761 for (it = begin; it != end; ++it)
21763 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21766 if (currentDistSqr < minDistSqr)
21767 minDistSqr = currentDistSqr;
21770 return qSqrt(minDistSqr);
21783 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
21786 QCPFinancialDataMap::const_iterator it;
21789 for (it = begin; it != end; ++it)
21791 double currentDistSqr;
21794 QCPRange boxValueRange(it.value().close, it.value().open);
21795 double posKey, posValue;
21797 if (boxKeyRange.
contains(posKey) && boxValueRange.contains(posValue))
21803 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21804 double highLineDistSqr =
distSqrToLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->
coordToPixel(qMax(it.value().open, it.value().close))), pos);
21805 double lowLineDistSqr =
distSqrToLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().low)), QPointF(keyPixel, valueAxis->
coordToPixel(qMin(it.value().open, it.value().close))), pos);
21806 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
21808 if (currentDistSqr < minDistSqr)
21809 minDistSqr = currentDistSqr;
21813 for (it = begin; it != end; ++it)
21815 double currentDistSqr;
21818 QCPRange boxValueRange(it.value().close, it.value().open);
21819 double posKey, posValue;
21821 if (boxKeyRange.
contains(posKey) && boxValueRange.contains(posValue))
21827 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21828 double highLineDistSqr =
distSqrToLine(QPointF(valueAxis->
coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->
coordToPixel(qMax(it.value().open, it.value().close)), keyPixel), pos);
21829 double lowLineDistSqr =
distSqrToLine(QPointF(valueAxis->
coordToPixel(it.value().low), keyPixel), QPointF(valueAxis->
coordToPixel(qMin(it.value().open, it.value().close)), keyPixel), pos);
21830 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
21832 if (currentDistSqr < minDistSqr)
21833 minDistSqr = currentDistSqr;
21836 return qSqrt(minDistSqr);
21857 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
21858 if (
mData->isEmpty())
21860 lower =
mData->constEnd();
21861 upper =
mData->constEnd();
21866 QCPFinancialDataMap::const_iterator lbound =
mData->lowerBound(
mKeyAxis.data()->range().lower);
21867 QCPFinancialDataMap::const_iterator ubound =
mData->upperBound(
mKeyAxis.data()->range().upper);
21868 bool lowoutlier = lbound !=
mData->constBegin();
21869 bool highoutlier = ubound !=
mData->constEnd();
21871 lower = (lowoutlier ? lbound-1 : lbound);
21872 upper = (highoutlier ? ubound : ubound-1);
21895 point1(createPosition(QLatin1String(
"point1"))),
21896 point2(createPosition(QLatin1String(
"point2")))
21901 setPen(QPen(Qt::black));
21945 double clipPad =
mainPen().widthF();
21948 if (!line.isNull())
21964 return qAbs((base.y()-point.y())*vec.x()-(base.x()-point.x())*vec.y())/vec.length();
21979 if (vec.x() == 0 && vec.y() == 0)
21981 if (qFuzzyIsNull(vec.x()))
21986 gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y();
21987 if (gamma >= 0 && gamma <= rect.width())
21988 result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom());
21989 }
else if (qFuzzyIsNull(vec.y()))
21994 gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x();
21995 if (gamma >= 0 && gamma <= rect.height())
21996 result.setLine(rect.left(), by+gamma, rect.right(), by+gamma);
21999 QList<QVector2D> pointVectors;
22003 gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y();
22004 if (gamma >= 0 && gamma <= rect.width())
22005 pointVectors.append(QVector2D(bx+gamma, by));
22008 by = rect.bottom();
22009 gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y();
22010 if (gamma >= 0 && gamma <= rect.width())
22011 pointVectors.append(QVector2D(bx+gamma, by));
22015 gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x();
22016 if (gamma >= 0 && gamma <= rect.height())
22017 pointVectors.append(QVector2D(bx, by+gamma));
22021 gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x();
22022 if (gamma >= 0 && gamma <= rect.height())
22023 pointVectors.append(QVector2D(bx, by+gamma));
22026 if (pointVectors.size() == 2)
22028 result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF());
22029 }
else if (pointVectors.size() > 2)
22032 double distSqrMax = 0;
22033 QVector2D pv1, pv2;
22034 for (
int i=0; i<pointVectors.size()-1; ++i)
22036 for (
int k=i+1; k<pointVectors.size(); ++k)
22038 double distSqr = (pointVectors.at(i)-pointVectors.at(k)).lengthSquared();
22039 if (distSqr > distSqrMax)
22041 pv1 = pointVectors.at(i);
22042 pv2 = pointVectors.at(k);
22043 distSqrMax = distSqr;
22047 result.setPoints(pv1.toPointF(), pv2.toPointF());
22091 setPen(QPen(Qt::black));
22160 if (startVec.toPoint() == endVec.toPoint())
22164 clipPad = qMax(clipPad, (
double)
mainPen().widthF());
22167 if (!line.isNull())
22171 painter->setBrush(Qt::SolidPattern);
22173 mTail.
draw(painter, startVec, startVec-endVec);
22175 mHead.
draw(painter, endVec, endVec-startVec);
22188 bool containsStart = rect.contains(start.x(), start.y());
22189 bool containsEnd = rect.contains(end.x(), end.y());
22190 if (containsStart && containsEnd)
22191 return QLineF(start.toPointF(), end.toPointF());
22193 QVector2D base =
start;
22194 QVector2D vec = end-
start;
22198 QList<QVector2D> pointVectors;
22200 if (!qFuzzyIsNull(vec.y()))
22205 mu = (by-base.y())/vec.y();
22206 if (mu >= 0 && mu <= 1)
22208 gamma = base.x()-bx + mu*vec.x();
22209 if (gamma >= 0 && gamma <= rect.width())
22210 pointVectors.append(QVector2D(bx+gamma, by));
22214 by = rect.bottom();
22215 mu = (by-base.y())/vec.y();
22216 if (mu >= 0 && mu <= 1)
22218 gamma = base.x()-bx + mu*vec.x();
22219 if (gamma >= 0 && gamma <= rect.width())
22220 pointVectors.append(QVector2D(bx+gamma, by));
22223 if (!qFuzzyIsNull(vec.x()))
22228 mu = (bx-base.x())/vec.x();
22229 if (mu >= 0 && mu <= 1)
22231 gamma = base.y()-by + mu*vec.y();
22232 if (gamma >= 0 && gamma <= rect.height())
22233 pointVectors.append(QVector2D(bx, by+gamma));
22238 mu = (bx-base.x())/vec.x();
22239 if (mu >= 0 && mu <= 1)
22241 gamma = base.y()-by + mu*vec.y();
22242 if (gamma >= 0 && gamma <= rect.height())
22243 pointVectors.append(QVector2D(bx, by+gamma));
22248 pointVectors.append(start);
22250 pointVectors.append(end);
22253 if (pointVectors.size() == 2)
22255 result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF());
22256 }
else if (pointVectors.size() > 2)
22259 double distSqrMax = 0;
22260 QVector2D pv1, pv2;
22261 for (
int i=0; i<pointVectors.size()-1; ++i)
22263 for (
int k=i+1; k<pointVectors.size(); ++k)
22265 double distSqr = (pointVectors.at(i)-pointVectors.at(k)).lengthSquared();
22266 if (distSqr > distSqrMax)
22268 pv1 = pointVectors.at(i);
22269 pv2 = pointVectors.at(k);
22270 distSqrMax = distSqr;
22274 result.setPoints(pv1.toPointF(), pv2.toPointF());
22328 setPen(QPen(Qt::black));
22394 QPainterPath cubicPath(startVec);
22395 cubicPath.cubicTo(startDirVec, endDirVec, endVec);
22397 QPolygonF polygon = cubicPath.toSubpathPolygons().first();
22399 for (
int i=1; i<polygon.size(); ++i)
22401 double distSqr =
distSqrToLine(polygon.at(i-1), polygon.at(i), pos);
22402 if (distSqr < minDistSqr)
22403 minDistSqr = distSqr;
22405 return qSqrt(minDistSqr);
22415 if (QVector2D(endVec-startVec).length() > 1e10f)
22418 QPainterPath cubicPath(startVec);
22419 cubicPath.cubicTo(startDirVec, endDirVec, endVec);
22423 QRect cubicRect = cubicPath.controlPointRect().toRect();
22424 if (cubicRect.isEmpty())
22425 cubicRect.adjust(0, 0, 1, 1);
22426 if (clip.intersects(cubicRect))
22429 painter->drawPath(cubicPath);
22430 painter->setBrush(Qt::SolidPattern);
22432 mTail.
draw(painter, QVector2D(startVec), M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI);
22434 mHead.
draw(painter, QVector2D(endVec), -cubicPath.angleAtPercent(1)/180.0*M_PI);
22471 topRight(
createAnchor(QLatin1String(
"topRight"), aiTopRight)),
22473 bottom(
createAnchor(QLatin1String(
"bottom"), aiBottom)),
22474 bottomLeft(
createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
22480 setPen(QPen(Qt::black));
22540 bool filledRect =
mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0;
22549 if (p1.toPoint() == p2.toPoint())
22551 QRectF rect = QRectF(p1, p2).normalized();
22552 double clipPad =
mainPen().widthF();
22553 QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
22554 if (boundingRect.intersects(
clipRect()))
22558 painter->drawRect(rect);
22568 case aiTop:
return (rect.topLeft()+rect.topRight())*0.5;
22570 case aiRight:
return (rect.topRight()+rect.bottomRight())*0.5;
22571 case aiBottom:
return (rect.bottomLeft()+rect.bottomRight())*0.5;
22573 case aiLeft:
return (rect.topLeft()+rect.bottomLeft())*0.5;
22576 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
22641 setText(QLatin1String(
"text"));
22799 QTransform inputTransform;
22800 inputTransform.translate(positionPixels.x(), positionPixels.y());
22802 inputTransform.translate(-positionPixels.x(), -positionPixels.y());
22803 QPointF rotatedPos = inputTransform.map(pos);
22804 QFontMetrics fontMetrics(
mFont);
22805 QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|
mTextAlignment,
mText);
22808 textBoxRect.moveTopLeft(textPos.toPoint());
22817 QTransform transform = painter->transform();
22818 transform.translate(pos.x(), pos.y());
22822 QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|
mTextAlignment,
mText);
22825 textRect.moveTopLeft(textPos.toPoint()+QPoint(
mPadding.left(),
mPadding.top()));
22826 textBoxRect.moveTopLeft(textPos.toPoint());
22827 double clipPad =
mainPen().widthF();
22828 QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
22829 if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(
clipRect())))
22831 painter->setTransform(transform);
22837 painter->drawRect(textBoxRect);
22839 painter->setBrush(Qt::NoBrush);
22850 QTransform transform;
22851 transform.translate(pos.x(), pos.y());
22854 QFontMetrics fontMetrics(
mainFont());
22855 QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|
mTextAlignment,
mText);
22858 textBoxRect.moveTopLeft(textPos.toPoint());
22859 QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect));
22864 case aiTop:
return (rectPoly.at(0)+rectPoly.at(1))*0.5;
22866 case aiRight:
return (rectPoly.at(1)+rectPoly.at(2))*0.5;
22868 case aiBottom:
return (rectPoly.at(2)+rectPoly.at(3))*0.5;
22870 case aiLeft:
return (rectPoly.at(3)+rectPoly.at(0))*0.5;
22873 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
22889 if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop))
22892 QPointF result = pos;
22893 if (positionAlignment.testFlag(Qt::AlignHCenter))
22894 result.rx() -= rect.width()/2.0;
22895 else if (positionAlignment.testFlag(Qt::AlignRight))
22896 result.rx() -= rect.width();
22897 if (positionAlignment.testFlag(Qt::AlignVCenter))
22898 result.ry() -= rect.height()/2.0;
22899 else if (positionAlignment.testFlag(Qt::AlignBottom))
22900 result.ry() -= rect.height();
22966 topLeftRim(
createAnchor(QLatin1String(
"topLeftRim"), aiTopLeftRim)),
22968 topRightRim(
createAnchor(QLatin1String(
"topRightRim"), aiTopRightRim)),
22970 bottomRightRim(
createAnchor(QLatin1String(
"bottomRightRim"), aiBottomRightRim)),
22972 bottomLeftRim(
createAnchor(QLatin1String(
"bottomLeftRim"), aiBottomLeftRim)),
22974 center(
createAnchor(QLatin1String(
"center"), aiCenter))
22979 setPen(QPen(Qt::black));
23038 double result = -1;
23041 QPointF
center((p1+p2)/2.0);
23042 double a = qAbs(p1.x()-p2.x())/2.0;
23043 double b = qAbs(p1.y()-p2.y())/2.0;
23044 double x = pos.x()-center.x();
23045 double y = pos.y()-center.y();
23048 double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b));
23049 result = qAbs(c-1)*qSqrt(x*x+y*y);
23053 if (x*x/(a*a) + y*y/(b*b) <= 1)
23064 if (p1.toPoint() == p2.toPoint())
23066 QRectF ellipseRect = QRectF(p1, p2).normalized();
23068 if (ellipseRect.intersects(clip))
23072 #ifdef __EXCEPTIONS 23076 painter->drawEllipse(ellipseRect);
23077 #ifdef __EXCEPTIONS 23080 qDebug() << Q_FUNC_INFO <<
"Item too large for memory, setting invisible";
23093 case aiTopLeftRim:
return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2);
23094 case aiTop:
return (rect.topLeft()+rect.topRight())*0.5;
23095 case aiTopRightRim:
return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2);
23096 case aiRight:
return (rect.topRight()+rect.bottomRight())*0.5;
23097 case aiBottomRightRim:
return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2);
23098 case aiBottom:
return (rect.bottomLeft()+rect.bottomRight())*0.5;
23099 case aiBottomLeftRim:
return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2);
23100 case aiLeft:
return (rect.topLeft()+rect.bottomLeft())*0.5;
23101 case aiCenter:
return (rect.topLeft()+rect.bottomRight())*0.5;
23104 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
23157 topRight(
createAnchor(QLatin1String(
"topRight"), aiTopRight)),
23160 bottomLeft(
createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
23168 setScaled(
false, Qt::KeepAspectRatio, Qt::SmoothTransformation);
23182 qDebug() << Q_FUNC_INFO <<
"pixmap is null";
23230 bool flipHorz =
false;
23231 bool flipVert =
false;
23233 double clipPad =
mainPen().style() == Qt::NoPen ? 0 :
mainPen().widthF();
23234 QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
23235 if (boundingRect.intersects(
clipRect()))
23240 if (pen.style() != Qt::NoPen)
23243 painter->setBrush(Qt::NoBrush);
23244 painter->drawRect(rect);
23258 rect.adjust(rect.width(), 0, -rect.width(), 0);
23260 rect.adjust(0, rect.height(), 0, -rect.height());
23264 case aiTop:
return (rect.topLeft()+rect.topRight())*0.5;
23266 case aiRight:
return (rect.topRight()+rect.bottomRight())*0.5;
23267 case aiBottom:
return (rect.bottomLeft()+rect.bottomRight())*0.5;
23269 case aiLeft:
return (rect.topLeft()+rect.bottomLeft())*0.5;;
23272 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
23296 if (finalRect.isNull())
23301 if (flipHorz || flipVert)
23325 bool flipHorz =
false;
23326 bool flipVert =
false;
23330 return QRect(p1, QSize(0, 0));
23333 QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y());
23335 if (newSize.width() < 0)
23338 newSize.rwidth() *= -1;
23339 topLeft.setX(p2.x());
23341 if (newSize.height() < 0)
23344 newSize.rheight() *= -1;
23345 topLeft.setY(p2.y());
23347 QSize scaledSize =
mPixmap.size();
23349 result = QRect(topLeft, scaledSize);
23352 result = QRect(p1,
mPixmap.size());
23355 *flippedHorz = flipHorz;
23357 *flippedVert = flipVert;
23420 setPen(QPen(Qt::black));
23513 qDebug() << Q_FUNC_INFO <<
"graph isn't in same QCustomPlot instance as this item";
23565 if (
clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23566 return qSqrt(qMin(
distSqrToLine(center+QPointF(-w, 0), center+QPointF(w, 0), pos),
23567 distSqrToLine(center+QPointF(0, -w), center+QPointF(0, w), pos)));
23572 return qSqrt(qMin(
distSqrToLine(QPointF(clip.left(), center.y()), QPointF(clip.right(), center.y()), pos),
23573 distSqrToLine(QPointF(center.x(), clip.top()), QPointF(center.x(), clip.bottom()), pos)));
23577 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23580 double centerDist = QVector2D(center-pos).length();
23581 double circleLine =
w;
23582 double result = qAbs(centerDist-circleLine);
23586 if (centerDist <= circleLine)
23595 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23597 QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w));
23598 bool filledRect =
mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0;
23624 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23626 painter->
drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0)));
23627 painter->
drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w)));
23633 if (center.y() > clip.top() && center.y() < clip.bottom())
23634 painter->
drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y()));
23635 if (center.x() > clip.left() && center.x() < clip.right())
23636 painter->
drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom()));
23641 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23642 painter->drawEllipse(center, w, w);
23647 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23648 painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w)));
23674 QCPDataMap::const_iterator first =
mGraph->
data()->constBegin();
23675 QCPDataMap::const_iterator last =
mGraph->
data()->constEnd()-1;
23685 QCPDataMap::const_iterator prevIt = it-1;
23690 if (!qFuzzyCompare((
double)it.key(), (double)prevIt.key()))
23691 slope = (it.value().value-prevIt.value().value)/(it.key()-prevIt.key());
23696 if (
mGraphKey < (prevIt.key()+it.key())*0.5)
23705 QCPDataMap::const_iterator it =
mGraph->
data()->constBegin();
23708 qDebug() << Q_FUNC_INFO <<
"graph has no data";
23710 qDebug() << Q_FUNC_INFO <<
"graph not contained in QCustomPlot instance (anymore)";
23768 center(
createAnchor(QLatin1String(
"center"), aiCenter))
23773 setPen(QPen(Qt::black));
23839 if (leftVec.toPoint() == rightVec.toPoint())
23842 QVector2D widthVec = (rightVec-leftVec)*0.5f;
23843 QVector2D lengthVec(-widthVec.y(), widthVec.x());
23844 lengthVec = lengthVec.normalized()*
mLength;
23845 QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec;
23847 return qSqrt(
distSqrToLine((centerVec-widthVec).toPointF(), (centerVec+widthVec).toPointF(), pos));
23855 if (leftVec.toPoint() == rightVec.toPoint())
23858 QVector2D widthVec = (rightVec-leftVec)*0.5f;
23859 QVector2D lengthVec(-widthVec.y(), widthVec.x());
23860 lengthVec = lengthVec.normalized()*
mLength;
23861 QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec;
23863 QPolygon boundingPoly;
23864 boundingPoly << leftVec.toPoint() << rightVec.toPoint()
23865 << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint();
23867 if (clip.intersects(boundingPoly.boundingRect()))
23874 painter->
drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF());
23875 painter->
drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF());
23876 painter->
drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23881 painter->setBrush(Qt::NoBrush);
23883 path.moveTo((centerVec+widthVec+lengthVec).toPointF());
23884 path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF());
23885 path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23886 painter->drawPath(path);
23891 painter->setBrush(Qt::NoBrush);
23893 path.moveTo((centerVec+widthVec+lengthVec).toPointF());
23894 path.cubicTo((centerVec+widthVec-lengthVec*0.8f).toPointF(), (centerVec+0.4f*widthVec+lengthVec).toPointF(), centerVec.toPointF());
23895 path.cubicTo((centerVec-0.4f*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8f).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23896 painter->drawPath(path);
23901 painter->
setPen(Qt::NoPen);
23902 painter->setBrush(QBrush(
mainPen().color()));
23904 path.moveTo((centerVec+widthVec+lengthVec).toPointF());
23906 path.cubicTo((centerVec+widthVec-lengthVec*0.8f).toPointF(), (centerVec+0.4f*widthVec+0.8f*lengthVec).toPointF(), centerVec.toPointF());
23907 path.cubicTo((centerVec-0.4f*widthVec+0.8f*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8f).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23909 path.cubicTo((centerVec-widthVec-lengthVec*0.5f).toPointF(), (centerVec-0.2f*widthVec+1.2f*lengthVec).toPointF(), (centerVec+lengthVec*0.2f).toPointF());
23910 path.cubicTo((centerVec+0.2f*widthVec+1.2f*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5f).toPointF(), (centerVec+widthVec+lengthVec).toPointF());
23912 painter->drawPath(path);
23924 if (leftVec.toPoint() == rightVec.toPoint())
23925 return leftVec.toPointF();
23927 QVector2D widthVec = (rightVec-leftVec)*0.5f;
23928 QVector2D lengthVec(-widthVec.y(), widthVec.x());
23929 lengthVec = lengthVec.normalized()*
mLength;
23930 QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec;
23935 return centerVec.toPointF();
23937 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
void setOutliers(const QVector< double > &values)
QList< QList< QCPLayoutElement * > > mElements
virtual int elementCount() const
void drawShape(QCPPainter *painter, QPointF pos) const
QCP::AntialiasedElements mNotAADragBackup
void setType(PositionType type)
QCPLayoutElement(QCustomPlot *parentPlot=0)
bool getTraverse(double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom, QPointF &crossA, QPointF &crossB) const
QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale)
virtual QCPLayoutElement * elementAt(int index) const
void itemClick(QCPAbstractItem *item, QMouseEvent *event)
void drawSubGridLines(QCPPainter *painter) const
void addElement(QCPLayoutElement *element, Qt::Alignment alignment)
QCPItemPosition * position(const QString &name) const
void insertRow(int newIndex)
A margin group allows synchronization of margin sides if working with multiple layout elements...
QList< QCPGraph * > mGraphs
QCPGraph * addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0)
virtual ~QCPAxisPainterPrivate()
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setSubTickLengthIn(int inside)
void setMargins(const QMargins &margins)
0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width...
QList< QCPLayoutElement * > elements(QCP::MarginSide side) const
void setWhiskerBarPen(const QPen &pen)
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true)
void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const
Qt::Orientations mRangeDrag
A plus shaped crosshair which spans the complete axis rect.
static const double maxRange
void setPeriodic(bool enabled)
void setLevelCount(int n)
QColor mainTextColor() const
QRgb color(double position, const QCPRange &range, bool logarithmic=false)
Whether to use immediate repaint or queued update depends on whether the plotting hint QCP::phForceRe...
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setInsetPlacement(int index, InsetPlacement placement)
Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts)
bool isInvalidData(double value)
The negative sign domain, i.e. numbers smaller than zero.
virtual void updateMapImage()
virtual void update(UpdatePhase phase)
int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const
QCPColorGradient gradient() const
QCPAxis * rangeZoomAxis(Qt::Orientation orientation)
void setDateTimeFormat(const QString &format)
void setText(const QString &text)
void selectableChanged(bool selectable)
void setLowerEnding(const QCPLineEnding &ending)
Open-High-Low-Close bar representation.
bool clipToAxisRect() const
virtual QRect clipRect() const
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
QCPItemPosition *const end
void updateAxesOffset(QCPAxis::AxisType type)
QCPColorMapData * mMapData
QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable)
virtual void draw(QCPPainter *painter)
int plottableCount() const
QCPLayout * mParentLayout
void setAutoTickLabels(bool on)
double cell(int keyIndex, int valueIndex)
Q_SLOT void setSelected(bool selected)
void setMinimumMargins(const QMargins &margins)
QCPAxis(QCPAxisRect *parent, AxisType type)
void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0)
PainterModes modes() const
QCPRange dataRange() const
void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true)
void setKeySize(int keySize)
QMap< double, QCPData > QCPDataMap
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void remove(QCPBars *bars)
void removeDataAfter(double key)
QCP::AntialiasedElements antialiasedElements() const
void setMaximumSize(const QSize &size)
Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the ...
static QCPFinancialDataMap timeSeriesToOhlc(const QVector< double > &time, const QVector< double > &value, double timeBinSize, double timeBinOffset=0)
Holds the data of one single data point for QCPCurve.
void mouseMove(QMouseEvent *event)
QCPRange keyRange() const
No line is drawn between data points (e.g. only scatters)
QCustomPlot(QWidget *parent=0)
virtual int calculateAutoSubTickCount(double tickStep) const
void setParentLayerable(QCPLayerable *parentLayerable)
QCPItemBracket(QCustomPlot *parentPlot)
QCPLineEnding tail() const
void rescaleKeyAxis(bool onlyEnlarge=false) const
bool mNumberBeautifulPowers
QCPItemAnchor *const center
A legend item representing a plottable with an icon and the plottable name.
QHash< QCP::MarginSide, QCPMarginGroup * > mMarginGroups
Bar spacing is given by a fraction of the axis rect size.
bool antialiasing() const
void setType(QCPAxis::AxisType type)
void setIconTextPadding(int padding)
each data point is represented by a line parallel to the value axis, which reaches from the data poin...
QCPItemPosition *const start
void selectionChanged(bool selected)
int numberPrecision() const
virtual QList< QCPLayoutElement * > elements(bool recursive) const
void expandTo(int newRowCount, int newColumnCount)
SelectableParts selectedParts() const
QByteArray mLabelParameterHash
0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fix...
bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const
void setMedianPen(const QPen &pen)
QList< QCPAbstractPlottable * > selectedPlottables() const
void selectionChanged(bool selected)
Q_SLOT bool setLayer(QCPLayer *layer)
QList< QCPGraph * > graphs() const
QCPAbstractPlottable * plottable()
bool contains(double value) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void visibleTickBounds(int &lowIndex, int &highIndex) const
The axis backbone and tick marks.
double realLength() const
virtual void mouseMoveEvent(QMouseEvent *event)
QCPBarDataMap * data() const
QCPLineEnding lowerEnding
EndingStyle style() const
Bar spacing is in key coordinates and thus scales with the key axis range.
virtual void draw(QCPPainter *painter)
QCPItemAnchor * anchor(const QString &name) const
void drawGridLines(QCPPainter *painter) const
void setSpacingType(SpacingType spacingType)
virtual void draw(QCPPainter *painter)
void setSelectedTickLabelFont(const QFont &font)
void setOffset(int offset)
QColor mSelectedTickLabelColor
void setBasePen(const QPen &pen)
bool hasPlottable(QCPAbstractPlottable *plottable) const
void setVisible(bool visible)
The tracer is not visible.
virtual QPointF anchorPixelPoint(int anchorId) const
virtual void drawImpulsePlot(QCPPainter *painter, QVector< QPointF > *lineData) const
void setSelectedBorderPen(const QPen &pen)
void setPixmap(const QPixmap &pixmap)
QColor getTickLabelColor() const
QCPItemPosition *const topLeft
SelectableParts mSelectedParts
custom painter operations are performed per scatter (As QPainterPath, see setCustomPath) ...
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
The abstract base class for all entries in a QCPLegend.
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const
QFont mSelectedTickLabelFont
void setHead(const QCPLineEnding &head)
bool remove(QCPLayoutElement *element)
{ssPeace.png} a circle, with one vertical and two downward diagonal lines
Tick labels (numbers) of this axis (as a whole, not individually)
bool mAntialiasedZeroLine
void setStyle(BracketStyle style)
virtual void draw(QCPPainter *painter)
void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event)
QColor getTextColor() const
void addChild(QCPLayerable *layerable, bool prepend)
void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end)
double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const
void setPenPositive(const QPen &pen)
static AxisType marginSideToAxisType(QCP::MarginSide side)
0x0001 Axis base line and tick marks
QCPItemAnchor * createAnchor(const QString &name, int anchorId)
Q_SLOT void setDataRange(const QCPRange &dataRange)
void setName(const QString &name)
QPainterPath customPath() const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void setRowStretchFactors(const QList< double > &factors)
virtual void draw(QCPPainter *painter)
void setRangeReversed(bool reversed)
QPointF upperFillBasePoint(double upperKey) const
void setSelectedBasePen(const QPen &pen)
Responsible for drawing the grid of a QCPAxis.
Qt::Alignment positionAlignment() const
QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes) ...
QCPItemAnchor * parentAnchor() const
QVector< QString > tickLabels
void addData(const QCPFinancialDataMap &dataMap)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setWhiskerWidth(double width)
void dataRangeChanged(QCPRange newRange)
void setTextAlignment(Qt::Alignment alignment)
const QCPRange range() const
QCPColorGradient mGradient
QList< QCPGraph * > graphs() const
void setSelectedBrush(const QBrush &brush)
void setSelectedSubTickPen(const QPen &pen)
void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
virtual void mouseReleaseEvent(QMouseEvent *event)
QCPColorMapData * data() const
bool noAntialiasingOnDrag() const
QRect axisSelectionBox() const
bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1)
virtual void wheelEvent(QWheelEvent *event)
void setCustomPath(const QPainterPath &customPath)
void removeDataBefore(double key)
QList< QCPItemPosition * > mPositions
void setShape(ScatterShape shape)
QCP::PlottingHints plottingHints() const
QCustomPlot * mParentPlot
QColor mSelectedTextColor
void setBackgroundScaled(bool scaled)
Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white.
void setTickLabels(bool show)
An anchor of an item to which positions can be attached to.
void setSelectedPen(const QPen &pen)
Qt::Orientations mRangeZoom
void setBrush(const QBrush &brush)
virtual int calculateAutoMargin(QCP::MarginSide side)
void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
QCPAxis * keyAxis() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QPointF anchorPixelPoint(int anchorId) const
Phase in which the margins are calculated and set.
Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts)
void setSelectedIconBorderPen(const QPen &pen)
Static positioning in pixels, starting from the top left corner of the viewport/widget.
void setAntialiasedScatters(bool enabled)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
void setRangeZoom(Qt::Orientations orientations)
void setLowerQuartile(double value)
QCPItemRect(QCustomPlot *parentPlot)
QCPItemAnchor * mParentAnchorX
QCache< QString, CachedLabel > mLabelCache
void mouseRelease(QMouseEvent *event)
void setSelectedTextColor(const QColor &color)
A brace with angled edges.
void setSelectedPen(const QPen &pen)
QCPItemPosition *const right
void setWhiskerPen(const QPen &pen)
void setAdaptiveSampling(bool enabled)
void setAutoTickStep(bool on)
int findIndexAboveY(const QVector< QPointF > *data, double y) const
QVector< double > subTickPositions
void setSubTickCount(int count)
void rangeChanged(const QCPRange &newRange)
void setAutoTicks(bool on)
A plus shaped crosshair with limited size.
void rescaleDataRange(bool onlyVisibleMaps)
void mouseDoubleClick(QMouseEvent *event)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
QCPPlotTitle(QCustomPlot *parentPlot)
void setupFullAxesBox(bool connectRanges=false)
void getPreparedData(QVector< QCPData > *lineData, QVector< QCPData > *scatterData) const
QCPItemLine(QCustomPlot *parentPlot)
virtual void mouseReleaseEvent(QMouseEvent *event)
void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical)
QCPFinancialDataMap * mData
Q_SLOT void setSelectableParts(const SelectableParts &selectableParts)
QCPAxis * addAxis(QCPAxis::AxisType type, QCPAxis *axis=0)
double tickLabelRotation() const
QCPLineEnding head() const
static bool validRange(double lower, double upper)
Base class for all drawable objects.
virtual void draw(QCPPainter *painter)
QPixmap mBackgroundPixmap
void setAutoSubTicks(bool on)
VESPUCCI_EXPORT arma::uword max(arma::uword a, arma::uword b)
Vespucci::Math::max.
void setInterpolating(bool enabled)
virtual void drawWhiskers(QCPPainter *painter) const
void setValueAxis(QCPAxis *axis)
bool mGradientImageInvalidated
void setBackground(const QPixmap &pm)
double getPixelSpacing(const QCPBars *bars, double keyCoord)
void setPadding(int padding)
A plottable representing a bar chart in a plot.
void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const
const QCP::Interactions interactions() const
bool removeGraph(QCPGraph *graph)
QVector< double > mTickVector
void setRange(const QCPRange &keyRange, const QCPRange &valueRange)
0x080 All other objects are selectable (e.g. your own derived layerables, the plot title...
QList< QCPAbstractPlottable * > plottables() const
void setCoords(double key, double value)
void addChild(QCP::MarginSide side, QCPLayoutElement *element)
T diff(const T &X, arma::uword deriv_order=1)
Vespucci::Math::diff.
void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) ...
friend class QCPItemAnchor
Q_SLOT void setSelectable(bool selectable)
void setSelectedPen(const QPen &pen)
void setWidth(double width)
void loadPreset(GradientPreset preset)
void moveAbove(QCPBars *bars)
virtual QCP::Interaction selectionCategory() const
virtual void mousePressEvent(QMouseEvent *event)
void setSize(int keySize, int valueSize)
void moveBelow(QCPBars *bars)
void setScaleLogBase(double base)
void setScatterStyle(const QCPScatterStyle &style)
virtual void mouseMoveEvent(QMouseEvent *event)
void setInteraction(const QCP::Interaction &interaction, bool enabled=true)
void setRangeUpper(double upper)
void setModes(PainterModes modes)
QCPItemTracer(QCustomPlot *parentPlot)
void recalculateDataBounds()
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void getStepCenterPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
QColor mSelectedTextColor
void titleClick(QMouseEvent *event, QCPPlotTitle *title)
virtual QRect clipRect() const
virtual QCP::Interaction selectionCategory() const
void layerChanged(QCPLayer *newLayer)
virtual bool addToLegend()
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const =0
bool addElement(int row, int column, QCPLayoutElement *element)
void setStyle(EndingStyle style)
QPointer< QCPBars > mBarBelow
void setValueSize(int valueSize)
virtual ~QCPLayoutElement()
QList< QCPLayerable * > children() const
void setTickLabelRotation(double degrees)
QCPScatterStyle mScatterStyle
void setTypeX(PositionType type)
0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixma...
QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual void deselectEvent(bool *selectionStateChanged)
A layout that arranges child elements in a grid.
void setPen(const QPen &pen)
virtual void mousePressEvent(QMouseEvent *event)
void setFont(const QFont &font)
void setColor(const QColor &color)
void selectionChangedByUser()
0x08 Axis is horizontal and on the bottom side of the axis rect
bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0)
QPointer< QCPBars > mBarAbove
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPScatterStyle mOutlierStyle
void setUpperEnding(const QCPLineEnding &ending)
void setPixmap(const QPixmap &pixmap)
Tick coordinate is regarded as a date/time (seconds since 1970-01-01T00:00:00 UTC) and will be displa...
void setWidth(double width)
void getTraverseCornerPoints(int prevRegion, int currentRegion, double rectLeft, double rectTop, double rectRight, double rectBottom, QVector< QPointF > &beforeTraverse, QVector< QPointF > &afterTraverse) const
virtual QSize minimumSizeHint() const
virtual QCP::Interaction selectionCategory() const
QCPItemText(QCustomPlot *parentPlot)
QList< QCPLayer * > mLayers
void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title)
void setRangeDrag(Qt::Orientations orientations)
QCP::AntialiasedElements mNotAntialiasedElements
QCPItemAnchor *const bottom
0x0040 Main lines of items
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void removeChild(QCPLayerable *layerable)
QCPAxisRect * axisRect() const
virtual QCPLayoutElement * takeAt(int index)
virtual QCP::Interaction selectionCategory() const
void removeData(double fromKey, double toKey)
no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) ...
void removeDataBefore(double key)
bool begin(QPaintDevice *device)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const
virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize)
void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false)
void getLinePlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
QCPLineEnding upperEnding() const
The abstract base class for all data representing objects in a plot.
QCP::MarginSides mAutoMargins
void setColorScale(QCPColorScale *colorScale)
QCPColorGradient inverted() const
Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion ...
QRectF insetRect(int index) const
QCPRange sanitizedForLogScale() const
void setSelectedBrush(const QBrush &brush)
void setBackground(const QPixmap &pm)
virtual QByteArray generateLabelParameterHash() const
void setAutoTickCount(int approximateCount)
void releaseElement(QCPLayoutElement *el)
void removeChildX(QCPItemPosition *pos)
QCPItemAnchor *const left
QPointer< QCPAxis > mValueAxis
void setSubTickLengthOut(int outside)
void setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
QList< QCPBars * > bars() const
void removeData(double fromt, double tot)
void setTwoColored(bool twoColored)
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint)
QPointF lowerFillBasePoint(double lowerKey) const
bool moveToLayer(QCPLayer *layer, bool prepend)
QPointer< QCPAxis > mColorAxis
0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) ...
void setSubGridPen(const QPen &pen)
virtual QSize minimumSizeHint() const
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void removeDataAfter(double t)
QList< QCPAbstractLegendItem * > selectedItems() const
void setAntialiasedSubGrid(bool enabled)
virtual ~QCPItemStraightLine()
Tick labels will be displayed outside the axis rect.
virtual void draw(QCPPainter *painter)
QCPItemAnchor * parentAnchorY() const
Continuous lightness from black over icey colors to white (suited for non-biased data representation)...
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
line is drawn as steps where the step height is the value of the left data point
void selectionChanged(const QCPAxis::SelectableParts &parts)
virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const
QCPItemPosition *const endDir
void setErrorBarSize(double size)
0x02 Axis is vertical and on the right side of the axis rect
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
An approximation of the visible light spectrum (creates banding illusion but allows more precise magn...
void setBackgroundScaled(bool scaled)
void setTickLabelFont(const QFont &font)
QCPItemPosition *const bottomRight
QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange)
int subTickLengthIn() const
QCPColorGradient mGradient
void setTextColor(const QColor &color)
virtual ~QCPItemEllipse()
Bar width is in absolute pixels.
int tickLengthOut() const
void getScatterPlotData(QVector< QCPData > *scatterData) const
Qt::AspectRatioMode aspectRatioMode() const
QList< QCPAxis * > axes() const
QCustomPlot * mParentPlot
bool removeLayer(QCPLayer *layer)
void setSelectedLabelFont(const QFont &font)
void getPixelWidth(double key, double &lower, double &upper) const
QCPColorScale * colorScale() const
A plottable representing a graph in a plot.
void applyFillAntialiasingHint(QCPPainter *painter) const
QCPItemPosition *const start
int iconTextPadding() const
The abstract base class for all items in a plot.
QCPAbstractLegendItem(QCPLegend *parent)
QCPLayoutInset * mInsetLayout
void setData(double key, double value, double z)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const =0
Q_SLOT void setSelectable(bool selectable)
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance.
QRect tickLabelsSelectionBox() const
void setPadding(const QMargins &padding)
Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power...
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
Q_SLOT void setSelectable(bool selectable)
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
QCPLegend * mParentLegend
QPointer< QCPAxis > mKeyAxis
QVector< int > getSectionSizes(QVector< int > maxSizes, QVector< int > minSizes, QVector< double > stretchFactors, int totalSize) const
void getVisibleDataBounds(QCPFinancialDataMap::const_iterator &lower, QCPFinancialDataMap::const_iterator &upper) const
virtual QSize maximumSizeHint() const
QRect mTickLabelsSelectionBox
void setRangeLower(double lower)
void setBrush(const QBrush &brush)
QCPItemCurve(QCustomPlot *parentPlot)
QCPColorScale(QCustomPlot *parentPlot)
QPointer< QCPAxis > mRangeZoomHorzAxis
QCPItemAnchor *const right
bool mNoAntialiasingOnDrag
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
virtual void wheelEvent(QWheelEvent *event)
void setMedian(double value)
void setAntialiasing(bool enabled)
VESPUCCI_EXPORT void position(arma::uword index, arma::uword n_rows, arma::uword n_cols, arma::uword &i, arma::uword &j)
Vespucci::Math::position Find row and column numbers for index.
void setPen(const QPen &pen)
virtual QSize minimumSizeHint() const
0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see QCPAbstractItem) ...
virtual void draw(QCPPainter *painter)
Candlestick representation.
void setMinimum(double value)
void setWidth(double width)
void getMinimumRowColSizes(QVector< int > *minColWidths, QVector< int > *minRowHeights) const
void setBrushNegative(const QBrush &brush)
Manages a single axis inside a QCustomPlot.
QCPLineEnding tail() const
QCPAxis::AxisType type() const
double upperQuartile() const
QCPBarsGroup * barsGroup() const
Q_SLOT void setSelectable(bool selectable)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
double lowerQuartile() const
void drawLine(const QLineF &line)
QList< QCPAbstractItem * > selectedItems() const
Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allo...
void draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const
void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical)
int commonMargin(QCP::MarginSide side) const
void setTickPen(const QPen &pen)
void setMaximum(double value)
void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const
QCPColorScale * mParentColorScale
void setPen(const QPen &pen)
void setColorStops(const QMap< double, QColor > &colorStops)
virtual int elementCount() const
QCPLayer * layer(const QString &name) const
A filled arrow head with a straight/flat back (a triangle)
void getImpulsePlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
PositionType type() const
int findIndexAboveX(const QVector< QPointF > *data, double x) const
Represents the visual appearance of scatter points.
virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const
double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const
void setOutlierStyle(const QCPScatterStyle &style)
Manages a legend inside a QCustomPlot.
bool mAntialiasedErrorBars
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QList< QCPLayerable * > mChildren
QSet< QCPItemPosition * > mChildrenY
void insert(int i, QCPBars *bars)
QCPLineEnding lowerEnding() const
void setCell(int keyIndex, int valueIndex, double z)
bool addItem(QCPAbstractItem *item)
PositionType mPositionTypeY
QCPLayerable * parentLayerable() const
QVector< QPointF > getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const
virtual QSize maximumSizeHint() const
virtual void drawLinePlot(QCPPainter *painter, QVector< QPointF > *lineData) const
QPointer< QCPColorScaleAxisRectPrivate > mAxisRect
void setInsetRect(int index, const QRectF &rect)
line is drawn as steps where the step is in between two data points
void setTextColor(const QColor &color)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual bool take(QCPLayoutElement *element)=0
void getStepLeftPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
bool addPlottable(QCPAbstractPlottable *plottable)
Qt::AspectRatioMode mBackgroundScaledMode
double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const
void setBrush(const QBrush &brush)
0x0200 Borders of fills (e.g. under or between graphs)
bool abbreviateDecimalPowers
0x004 The user can select multiple objects by holding the modifier set by QCustomPlot::setMultiSelect...
QCPAbstractPlottable * plottable()
void removeData(double fromKey, double toKey)
QCPItemAnchor *const bottomRight
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
void setSpacing(double spacing)
QPointer< QCPAxis > mValueAxis
Bar width is in key coordinates and thus scales with the key axis range.
void addData(const QCPCurveDataMap &dataMap)
void setRowSpacing(int pixels)
QCPRange valueRange() const
QCPItemPosition * createPosition(const QString &name)
void setMinimumSize(const QSize &size)
QCPRange mDragStartVertRange
QVector< double > mSubTickVector
void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end)
QPen getSubTickPen() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setKeyAxis(QCPAxis *axis)
QLineF getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const
QPolygonF getBarPolygon(double key, double value) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
A layer that may contain objects, to control the rendering order.
Qt::Orientation orientation() const
Continuous lightness from black over firey colors to white (suited for non-biased data representation...
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void setPen(const QPen &pen)
QCPItemPosition *const position
void rescaleDataRange(bool recalculateDataBounds=false)
void setInverted(bool inverted)
LabelSide tickLabelSide() const
void setAutoMargins(QCP::MarginSides sides)
virtual void axisRemoved(QCPAxis *axis)
0x00 Default mode for painting on screen devices
void setTickVector(const QVector< double > &vec)
QFont getLabelFont() const
Error bars for both key and value dimensions of the data point are shown.
SpacingType spacingType() const
The abstract base class for all objects that form the layout system.
QCPBarsGroup(QCustomPlot *parentPlot)
QColor getLabelColor() const
void setGraph(QCPGraph *graph)
void mousePress(QMouseEvent *event)
Continuous lightness from black to white (suited for non-biased data representation) ...
virtual void update(UpdatePhase phase)
void setFont(const QFont &font)
virtual void draw(QCPPainter *painter)
int findIndexBelowX(const QVector< QPointF > *data, double x) const
QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis)
void plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event)
QCPRange expanded(const QCPRange &otherRange) const
QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
void applyScattersAntialiasingHint(QCPPainter *painter) const
QCPAxis * keyAxis() const
void setOuterRect(const QRect &rect)
void setPen(const QPen &pen)
bool mayTraverse(int prevRegion, int currentRegion) const
QCPLayer(QCustomPlot *parentPlot, const QString &layerName)
void setLineStyle(LineStyle ls)
void setDataBothError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError, const QVector< double > &valueError)
QCPColorGradient gradient() const
void setPen(const QPen &pen)
virtual QPointF anchorPixelPoint(int anchorId) const
void setUpperQuartile(double value)
void updateLayerIndices() const
QCPLineEnding upperEnding
void selectableChanged(bool selectable)
void setTextColor(const QColor &color)
Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts)
void getMaximumRowColSizes(QVector< int > *maxColWidths, QVector< int > *maxRowHeights) const
void insertColumn(int newIndex)
void setColumnSpacing(int pixels)
QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const
Qt::AspectRatioMode mAspectRatioMode
QCPItemStraightLine(QCustomPlot *parentPlot)
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false)
QPen selectedIconBorderPen() const
virtual void draw(QCPPainter *painter)=0
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPItemAnchor * parentAnchorX() const
int findIndexBelowY(const QVector< QPointF > *data, double y) const
virtual QList< QCPLayoutElement * > elements(bool recursive) const
virtual ~QCPAbstractItem()
virtual bool removeFromLegend() const
QCPBarsGroup * mBarsGroup
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
QMap< double, QCPBarData > QCPBarDataMap
QCPItemAnchor *const left
void removeData(double fromKey, double toKey)
virtual void draw(QCPPainter *painter)
virtual void drawOutliers(QCPPainter *painter) const
double getStackedBaseValue(double key, bool positive) const
virtual void updateLayout()
void setTightBoundary(bool enabled)
bool operator==(const QCPColorGradient &other) const
QList< QCPAxis * > addAxes(QCPAxis::AxisTypes types)
bool autoSubTicks() const
void setWidthType(WidthType widthType)
virtual QPointF pixelPoint() const
A brace with round edges.
A layout that places child elements aligned to the border or arbitrarily positioned.
void setData(QCPColorMapData *data, bool copy=false)
virtual void deselectEvent(bool *selectionStateChanged)
QPen getIconBorderPen() const
void setViewport(const QRect &rect)
0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) ...
virtual void drawMedian(QCPPainter *painter) const
void setStyle(TracerStyle style)
void setNoAntialiasingOnDrag(bool enabled)
double scaleLogBase() const
Handles the different ending decorations for line-like items.
A color scale for use with color coding data such as QCPColorMap.
QCPDataMap * data() const
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void removeFillBasePoints(QVector< QPointF > *lineData) const
virtual void update(UpdatePhase phase)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCP::Interaction selectionCategory() const
QCP::PlottingHints mPlottingHints
Holds the data of one single data point for QCPGraph.
QCPAxis * valueAxis() const
QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const
Error bars for the key dimension of the data point are shown.
virtual QSize minimumSizeHint() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCPItemPosition * toQCPItemPosition()
QPointer< QCPAxisRect > mClipAxisRect
void applyDefaultAntialiasingHint(QCPPainter *painter) const
bool mAntialiasedScatters
QVector< QString > mTickVectorLabels
int getMarginValue(const QMargins &margins, QCP::MarginSide side)
The positive sign domain, i.e. numbers greater than zero.
void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
void setPixelPoint(const QPointF &pixelPoint)
QList< QCPAbstractPlottable * > mPlottables
QCustomPlot * parentPlot() const
void applyTo(QCPPainter *painter, const QPen &defaultPen) const
QPainter subclass used internally.
void append(QCPBars *bars)
Qt::TransformationMode transformationMode() const
void setTickLength(int inside, int outside=0)
QCPCurveDataMap * data() const
void setAntialiasedErrorBars(bool enabled)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Q_SLOT void setSelected(bool selected)
virtual QPointF anchorPixelPoint(int anchorId) const
QSet< QCPItemPosition * > mChildrenX
Qt::TimeSpec mDateTimeSpec
WidthType widthType() const
QCPItemEllipse(QCustomPlot *parentPlot)
{ssCrossCircle.png} a circle with a cross inside
void setPlottingHints(const QCP::PlottingHints &hints)
void coordsToPixels(double key, double value, double &x, double &y) const
void setErrorBarSkipSymbol(bool enabled)
void drawBackground(QCPPainter *painter)
double data(double key, double value)
double boundingDistance() const
QCPItemAnchor *const bottom
QCPGrid(QCPAxis *parentAxis)
virtual bool take(QCPLayoutElement *element)
Q_SLOT void setSelected(bool selected)
void setColorInterpolation(ColorInterpolation interpolation)
QCPLineEnding head() const
{ssDot.png} a single pixel (use ssDisc or ssCircle if you want a round shape with a certain radius) ...
virtual void drawFill(QCPPainter *painter, QVector< QPointF > *lineData) const
double pointDistance(const QPointF &pixelPoint) const
void setChartStyle(ChartStyle style)
void setBarsGroup(QCPBarsGroup *barsGroup)
virtual void mouseMoveEvent(QMouseEvent *event)
void setDateTimeSpec(const Qt::TimeSpec &timeSpec)
QVector< QRgb > mColorBuffer
void registerBars(QCPBars *bars)
QCPAxisRect * axisRect() const
QCPAbstractItem * mParentItem
{ssPlusSquare.png} a square with a plus inside
A filled diamond (45° rotated square)
void setIconBorderPen(const QPen &pen)
void removeChildY(QCPItemPosition *pos)
Colors suitable to represent different elevations on geographical maps.
int selectionTolerance() const
void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const
void setSelectedFont(const QFont &font)
virtual QCP::Interaction selectionCategory() const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setNumberPrecision(int precision)
QRect labelSelectionBox() const
static const double minRange
void removeDataBefore(double t)
QList< QCPAbstractItem * > items() const
void setSelectedPen(const QPen &pen)
QCPLayer * currentLayer() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
QVector< double > mOutliers
Tick coordinate is regarded as normal number and will be displayed as such. (see setNumberFormat) ...
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
QPointer< QCPAxis > mRangeZoomVertAxis
void setKeyRange(const QCPRange &keyRange)
{ssTriangle.png} an equilateral triangle, standing on baseline
{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) ...
void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
void rescaleAxes(bool onlyEnlarge=false) const
0x0020 Main lines of plottables (excluding error bars, see element aeErrorBars)
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
bool autoTickStep() const
LabelType tickLabelType() const
void setData(QCPBarDataMap *data, bool copy=false)
static void connectBars(QCPBars *lower, QCPBars *upper)
QCPBars * barBelow() const
bool rangeReversed() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setBrush(const QBrush &brush)
virtual void deselectEvent(bool *selectionStateChanged)
void setTickVectorLabels(const QVector< QString > &vec)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
A bar perpendicular to the line.
Q_SLOT void setSelectedParts(const SelectableParts &selectedParts)
void dataRangeChanged(QCPRange newRange)
void setRangeDrag(bool enabled)
data points are connected by a straight line
Final phase in which the layout system places the rects of the elements.
0x01 Axis is vertical and on the left side of the axis rect
void setLabelColor(const QColor &color)
void setAntialiasedFill(bool enabled)
QCP::AntialiasedElements mAntialiasedElements
void selectableChanged(bool selectable)
int getRegion(double x, double y, double rectLeft, double rectTop, double rectRight, double rectBottom) const
QLineF getRectClippedStraightLine(const QVector2D &point1, const QVector2D &vec, const QRect &rect) const
QCPItemPosition *const topLeft
QMap< double, QCPFinancialData > QCPFinancialDataMap
void setHead(const QCPLineEnding &head)
void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements)
QCPItemAnchor *const bottom
bool mAutoAddPlottableToLegend
void setAntialiased(bool enabled)
void setSelectedBrush(const QBrush &brush)
QCustomPlot * parentPlot() const
virtual QPointF anchorPixelPoint(int anchorId) const
VESPUCCI_EXPORT arma::uword min(arma::uword a, arma::uword b)
Vespucci::Math::min.
void scaleRange(double factor, double center)
void getCurveData(QVector< QPointF > *lineData) const
void setData(QCPCurveDataMap *data, bool copy=false)
double baseLog(double value) const
QCPItemPixmap(QCustomPlot *parentPlot)
QCPLayout * layout() const
QCPAxis * rangeDragAxis(Qt::Orientation orientation)
bool savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0, const QString &pdfCreator=QString(), const QString &pdfTitle=QString())
QCPAxisRect * axisRect(int index=0) const
QCPColorGradient(GradientPreset preset=gpCold)
void rescaleValueAxis(bool onlyEnlarge=false) const
void setRowStretchFactor(int row, double factor)
cmplx FADDEEVA() w(cmplx z, double relerr)
bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1)
QCPAbstractPlottable * plottableAt(const QPointF &pos, bool onlySelectable=false) const
void setBarWidth(int width)
QList< double > mColumnStretchFactors
bool mMapImageInvalidated
BracketStyle style() const
QList< QCPGraph * > selectedGraphs() const
bool removeItem(QCPAbstractItem *item)
void drawBackground(QCPPainter *painter)
A layout element displaying a plot title text.
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual bool take(QCPLayoutElement *element)
Bar width is given by a fraction of the axis rect size.
void setInterpolate(bool enabled)
SelectableParts selectedParts() const
void setPen(const QPen &pen)
Q_SLOT void deselectAll()
QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis)
QPointer< QCPColorScale > mColorScale
void setTickLabelSide(LabelSide side)
QCPLayoutInset * insetLayout() const
QPointer< QCPAxis > mRangeDragVertAxis
The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot...
virtual ~QCPItemBracket()
void removeChild(QCP::MarginSide side, QCPLayoutElement *element)
void setBrush(const QBrush &brush)
virtual QCPLayoutElement * takeAt(int index)
void setSelectionTolerance(int pixels)
void setSelectedPen(const QPen &pen)
void setDataKeyError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError)
QPointer< QCPAxis > mRangeDragHorzAxis
void setPen(const QPen &pen)
static AxisType opposite(AxisType type)
virtual void draw(QCPPainter *painter)
double pixelToCoord(double value) const
QMap< double, QColor > mColorStops
{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
QStack< bool > mAntialiasingStack
void addData(const QCPBarDataMap &dataMap)
void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Phase used for any type of preparation that needs to be done before margin calculation and layout...
virtual void draw(QCPPainter *painter)
void setTickStep(double step)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove)
void selectableChanged(bool selectable)
void setTickLabelType(LabelType type)
double mRangeZoomFactorHorz
Q_SLOT void setDataRange(const QCPRange &dataRange)
virtual int calculateAutoMargin(QCP::MarginSide side)
void setSelectedTextColor(const QColor &color)
double mScaleLogBaseLogInv
void setTickLengthOut(int outside)
double rangeZoomFactor(Qt::Orientation orientation)
QCPItemPosition *const point1
void setMultiSelectModifier(Qt::KeyboardModifier modifier)
QPen getBorderPen() const
void removeDataAfter(double key)
QList< QCPColorMap * > colorMaps() const
bool hasItem(QCPAbstractLegendItem *item) const
virtual void legendRemoved(QCPLegend *legend)
virtual void deselectEvent(bool *selectionStateChanged)
void unregisterBars(QCPBars *bars)
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const =0
virtual void drawScatterPlot(QCPPainter *painter, QVector< QCPData > *scatterData) const
void setSelectedTickPen(const QPen &pen)
QCPAxis::ScaleType mDataScaleType
void setSelectedFont(const QFont &font)
void moveRange(double diff)
void setLabelFont(const QFont &font)
A bar perpendicular to the line, pointing out to only one side (to which side can be changed with set...
virtual void mousePressEvent(QMouseEvent *event)
0x002 Legend items individually (see selectedItems)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
QCPAxis::ScaleType mDataScaleType
QList< QCPLegend * > selectedLegends() const
double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const
QCPAbstractItem * item() const
virtual void updateLayout()
void addChildY(QCPItemPosition *pos)
{ssPlusCircle.png} a circle with a plus inside
void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum)
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void setRotation(double degrees)
void setSubTickPen(const QPen &pen)
{ssCrossSquare.png} a square with a cross inside
QHash< QCPAxis::AxisType, QList< QCPAxis * > > mAxes
QCPItemAnchor *const right
void setLength(double length)
Data points are connected with a straight line.
void removeDataBefore(double key)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const =0
Dynamic positioning at a plot coordinate defined by two axes (see setAxes).
void addFillBasePoints(QVector< QPointF > *lineData) const
void setNumberFormat(const QString &formatCode)
SelectableParts mSelectableParts
void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const
QCPItemPosition *const startDir
virtual void draw(QCPPainter *painter)
ErrorType errorType() const
QCPRange sanitizedForLinScale() const
void setLineStyle(LineStyle style)
virtual QRect clipRect() const
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle ...
void scaleTypeChanged(QCPAxis::ScaleType scaleType)
QCPLayoutElement * element(int row, int column) const
QCPAxisPainterPrivate(QCustomPlot *parentPlot)
Qt::Alignment insetAlignment(int index) const
void getPlotData(QVector< QPointF > *lineData, QVector< QCPData > *scatterData) const
virtual QPointF pixelPoint() const
double basePow(double value) const
SelectablePart getPartAt(const QPointF &pos) const
virtual void draw(QCPPainter *painter)
void setTail(const QCPLineEnding &tail)
Holds the two-dimensional data of a QCPColorMap plottable.
bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
virtual void update(UpdatePhase phase)
void setSelectedFont(const QFont &font)
QList< QCPAbstractItem * > mItems
int autoTickCount() const
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom, QCPAxisRect::setRangeZoomAxes)
QCPAbstractLegendItem * item(int index) const
virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=0) const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
QString numberFormat() const
void setTickLengthIn(int inside)
double mRangeZoomFactorVert
void setSelectedColor(const QColor &color)
void setSelectedPen(const QPen &pen)
void setErrorType(ErrorType errorType)
void setRangeZoomFactor(double horizontalFactor, double verticalFactor)
void setSelectedBrush(const QBrush &brush)
Q_SLOT void setScaleType(QCPAxis::ScaleType type)
void setClipToAxisRect(bool clip)
TracerStyle style() const
void plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event)
void setColumnStretchFactors(const QList< double > &factors)
a custom pixmap specified by setPixmap, centered on the data point coordinates
void mouseWheel(QWheelEvent *event)
bool addItem(QCPAbstractLegendItem *item)
Continuous lightness from black over weak blueish colors to white (suited for non-biased data represe...
void setMarginValue(QMargins &margins, QCP::MarginSide side, int value)
void setPen(const QPen &pen)
QFont getTickLabelFont() const
QCPAxisPainterPrivate * mAxisPainter
virtual void updateLayout()
void setMode(PainterMode mode, bool enabled=true)
The abstract base class for layouts.
void setSubGridVisible(bool visible)
void setDataValueError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &valueError)
Holds the data of one single data point for QCPFinancial.
void setTickLabelPadding(int padding)
virtual void drawScatterPlot(QCPPainter *painter, const QVector< QPointF > *pointData) const
virtual void resizeEvent(QResizeEvent *event)
double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const
void setSelectedLabelColor(const QColor &color)
QCPItemPosition *const bottomRight
None of the selectable parts.
void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group)
QCPLayoutElement * layoutElementAt(const QPointF &pos) const
void setInteractions(const QCP::Interactions &interactions)
void setBrush(const QBrush &brush)
void selectionChanged(bool selected)
0x04 Axis is horizontal and on the top side of the axis rect
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
bool realVisibility() const
QCPItemAnchor *const left
QCPAbstractPlottable * mPlottable
QCPAbstractPlottable * plottable(int index)
ColorInterpolation mColorInterpolation
QCPPlottableLegendItem * itemWithPlottable(const QCPAbstractPlottable *plottable) const
QCPItemAnchor *const bottomLeft
QCPAxis * axis(QCPAxis::AxisType type, int index=0) const
{ssTriangleInverted.png} an equilateral triangle, standing on corner
virtual void draw(QCPPainter *painter)
void setLength(double length)
A plottable representing a two-dimensional color map in a plot.
Layer is inserted above other layer.
void rescale(bool onlyVisiblePlottables=false)
QHash< QCP::MarginSide, QList< QCPLayoutElement * > > mChildren
void setPlottingHint(QCP::PlottingHint hint, bool enabled=true)
QCPAxis * valueAxis() const
QPointer< QCPAxis > mKeyAxis
Both sign domains, including zero, i.e. all (rational) numbers.
InsetPlacement insetPlacement(int index) const
QString dateTimeFormat() const
void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation)
void setColumnStretchFactor(int column, double factor)
void setSelectedPen(const QPen &pen)
bool setCurrentLayer(const QString &name)
QCPItemPosition *const position
void setAxisRect(QCPAxisRect *axisRect)
int tickLabelPadding() const
void addChildX(QCPItemPosition *pos)
QCPAxis::LabelSide tickLabelSide
void getStepRightPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
QPointer< QCPLayerable > mParentLayerable
QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis)
int subTickLengthOut() const
QList< QCPAbstractPlottable * > plottables() const
QCPItemAnchor *const topLeft
Queues the refresh such that it is performed at a slightly delayed point in time after the replot...
Color channels red, green and blue are linearly interpolated.
virtual void draw(QCPPainter *painter)
const QPolygonF getChannelFillPolygon(const QVector< QPointF > *lineData) const
QCPItemAnchor *const right
Tick labels will be displayed inside the axis rect and clipped to the inner axis rect.
void setSelectedFont(const QFont &font)
QList< double > mRowStretchFactors
void setInsetAlignment(int index, Qt::Alignment alignment)
double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const
void setPen(const QPen &pen)
QPixmap mScaledBackgroundPixmap
QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis)
bool removeAxis(QCPAxis *axis)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Qt::TimeSpec dateTimeSpec() const
void setRangeZoom(bool enabled)
QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId=-1)
void setAutoAddPlottableToLegend(bool on)
QPointer< QCPAxisRect > mAxisRect
void setClipAxisRect(QCPAxisRect *rect)
Qt::TransformationMode mTransformationMode
virtual int calculateMargin()
void setText(const QString &text)
void setPen(const QPen &pen)
QVector< double > tickPositions
QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true)
void selectionChanged(bool selected)
void setSelectedTextColor(const QColor &color)
virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const
void removeDataAfter(double key)
void expand(const QCPRange &otherRange)
QCPAbstractItem * itemAt(const QPointF &pos, bool onlySelectable=false) const
QCPRange dataBounds() const
QCPLayerable * layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const
A non-filled arrow head with open back.
void setSelectedPen(const QPen &pen)
void setBorderPen(const QPen &pen)
SelectableParts selectableParts() const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void setZeroLinePen(const QPen &pen)
QCPItemPosition *const point2
bool hasAnchor(const QString &name) const
Bar spacing is in absolute pixels.
void gradientChanged(QCPColorGradient newGradient)
void selectableChanged(const QCPAxis::SelectableParts &parts)
virtual void draw(QCPPainter *painter)
void setIconSize(const QSize &size)
virtual void mouseReleaseEvent(QMouseEvent *event)
void setBaseValue(double baseValue)
QCPItemAnchor * mParentAnchorY
virtual QSize maximumSizeHint() const
0x0400 Zero-lines, see QCPGrid::setZeroLinePen
virtual QRect clipRect() const
void setData(QCPDataMap *data, bool copy=false)
bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove)
void setSelectedPen(const QPen &pen)
double coordToPixel(double value) const
void applyErrorBarsAntialiasingHint(QCPPainter *painter) const
void setScatterStyle(const QCPScatterStyle &style)
QList< QCPAxis * > axes(QCPAxis::AxisTypes types) const
virtual ~QCPItemPosition()
Manages the position of an item.
void adoptElement(QCPLayoutElement *el)
void setValueRange(const QCPRange &valueRange)
bool hasItem(QCPAbstractItem *item) const
QPen iconBorderPen() const
QCPItemPosition *const end
A curly brace with varying stroke width giving a calligraphic impression.
QList< QCPAbstractItem * > items() const
void setSize(double size)
QPixmap mBackgroundPixmap
void setGraphKey(double key)
Defines a color gradient for use with e.g. QCPColorMap.
QCPMarginGroup(QCustomPlot *parentPlot)
void setErrorPen(const QPen &pen)
virtual QSize sizeHint() const
void setTypeY(PositionType type)
QCPMarginGroup * marginGroup(QCP::MarginSide side) const
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
QPixmap mScaledBackgroundPixmap
QCPAbstractItem(QCustomPlot *parentPlot)
void setSubTickLength(int inside, int outside=0)
void setBrushPositive(const QBrush &brush)
QMap< double, QColor > colorStops() const
A bar that is skewed (skew controllable via setLength)
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
Represents the range an axis is encompassing.
QCPRange dataRange() const
QCPLayoutGrid * mPlotLayout
void setAntialiasedZeroLine(bool enabled)
virtual void draw(QCPPainter *painter)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void getVisibleDataBounds(QCPBarDataMap::const_iterator &lower, QCPBarDataMap::const_iterator &upperEnd) const
virtual QPointF anchorPixelPoint(int anchorId) const
void setPositionAlignment(Qt::Alignment alignment)
void setData(QCPFinancialDataMap *data, bool copy=false)
QList< QCPItemAnchor * > mAnchors
QCPRange mDragStartHorzRange
QCPScatterStyle mScatterStyle
Groups multiple QCPBars together so they appear side by side.
virtual void deselectEvent(bool *selectionStateChanged)
0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts)
void initializeParentPlot(QCustomPlot *parentPlot)
void setSelectedBrush(const QBrush &brush)
void setSelectedTickLabelColor(const QColor &color)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
virtual void generateAutoTicks()
bool removePlottable(QCPAbstractPlottable *plottable)
void setTail(const QCPLineEnding &tail)
void setTickLabelColor(const QColor &color)
void setSize(double size)
void setBrush(const QBrush &brush)
ScaleType scaleType() const
Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and pha...
void pixelsToCoords(double x, double y, double &key, double &value) const
void setSelectedPen(const QPen &pen)
QCPItemPosition *const topLeft
bool removeItem(int index)
SelectableParts selectableParts() const
virtual void draw(QCPPainter *painter)
virtual void deselectEvent(bool *selectionStateChanged)
virtual void draw(QCPPainter *painter)
virtual QCPLayoutElement * elementAt(int index) const
friend class QCPPlottableLegendItem
QCPFinancialDataMap * data() const
virtual void setupTickVectors()
PositionType mPositionTypeX
void addData(const QCPDataMap &dataMap)
Qt::Alignment mPositionAlignment
QList< QCPAxisRect * > axisRects() const
Holds multiple axes and arranges them in a rectangular shape.
void setPen(const QPen &pen)
virtual ~QCPLayoutInset()
virtual void paintEvent(QPaintEvent *event)
{ssDiamond.png} a diamond
QCPAxisRect * clipAxisRect() const
QCP::AntialiasedElements mAADragBackup
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QCPColorMapData & operator=(const QCPColorMapData &other)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
void toPainter(QCPPainter *painter, int width=0, int height=0)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QPixmap toPixmap(int width=0, int height=0, double scale=1.0)
virtual QSize minimumSizeHint() const
Qt::KeyboardModifier mMultiSelectModifier
void setPenNegative(const QPen &pen)
void setLabel(const QString &str)
QPointer< QCPLayoutElement > mMouseEventElement
virtual void draw(QCPPainter *painter)
QCP::AntialiasedElements notAntialiasedElements() const
void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements)
QMap< double, QCPCurveData > QCPCurveDataMap
Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18))
Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts)
void sizeConstraintsChanged() const
Q_SLOT void setRange(const QCPRange &range)
QList< QCPAxis * > selectedAxes() const
A filled arrow head with an indented back.
line is drawn as steps where the step height is the value of the right data point ...
virtual void deselectEvent(bool *selectionStateChanged)
QCP::Interactions mInteractions
QCPItemAnchor *const topRight
void gradientChanged(QCPColorGradient newGradient)
Qt::Alignment mTextAlignment
void setLabel(const QString &str)
QLatin1Char mNumberFormatChar
int axisCount(QCPAxis::AxisType type) const
QCPItemPosition *const left
bool mColorBufferInvalidated
int axisRectCount() const
QCustomPlot * mParentPlot
QPointer< QCPGraph > mChannelFillGraph
virtual void draw(QCPPainter *painter)
void updateGradientImage()
AxisType axisType() const
void setChannelFillGraph(QCPGraph *targetGraph)
void setWidth(double width)
double keyPixelOffset(const QCPBars *bars, double keyCoord)
void setFont(const QFont &font)
bool hasElement(int row, int column)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
QCustomPlot * mParentPlot
ScatterShape shape() const
void setSelectedBrush(const QBrush &brush)
void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const
void setPen(const QPen &pen)
QCPItemPosition *const bottomRight
Error bars for the value dimension of the data point are shown.
Qt::AspectRatioMode mBackgroundScaledMode
virtual void wheelEvent(QWheelEvent *event)
Q_SLOT void setSelected(bool selected)
QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0)
virtual void draw(QCPPainter *painter)
double pointDistance(const QPointF &pixelPoint) const
virtual void draw(QCPPainter *painter)
QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis)
Holds the data of one single data point (one bar) for QCPBars.
QColor mSelectedLabelColor
void setFont(const QFont &font)
void setColorStopAt(double position, const QColor &color)
void setLabelPadding(int padding)