13 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
14 #include <QtGui/QPrintEngine>
15 #include <QtGui/QPrinter>
16 #include <QtGui/QToolTip>
18 #include <QtPrintSupport/QPrintEngine>
19 #include <QtPrintSupport/QPrinter>
20 #include <QtWidgets/QToolTip>
46 : QPainter(), mModes(pmDefault), mIsAntialiasing(false) {
60 : QPainter(device), mModes(pmDefault), mIsAntialiasing(false) {
62 QT_VERSION_CHECK(5, 0, \
66 if (isActive()) setRenderHint(QPainter::NonCosmeticDefaultPen);
79 QPainter::setPen(pen);
91 QPainter::setPen(
color);
103 QPainter::setPen(penStyle);
118 QPainter::drawLine(line);
120 QPainter::drawLine(line.toLine());
131 setRenderHint(QPainter::Antialiasing, enabled);
141 translate(-0.5, -0.5);
164 bool result = QPainter::begin(device);
166 QT_VERSION_CHECK(5, 0, \
170 if (
result) setRenderHint(QPainter::NonCosmeticDefaultPen);
181 if (!enabled &&
mModes.testFlag(mode))
183 else if (enabled && !
mModes.testFlag(mode))
214 qDebug() << Q_FUNC_INFO <<
"Unbalanced save/restore";
223 if (qFuzzyIsNull(pen().widthF())) {
329 mPenDefined(false) {}
343 mPenDefined(false) {}
371 mBrush(QBrush(fill)),
398 mPenDefined(pen.style() != Qt::NoPen) {}
410 mPenDefined(false) {}
430 mCustomPath(customPath),
431 mPenDefined(pen.style() != Qt::NoPen) {}
509 const QPen &defaultPen)
const {
511 painter->setBrush(
mBrush);
531 double w =
mSize / 2.0;
536 painter->
drawLine(QPointF(
x,
y), QPointF(
x + 0.0001,
y));
550 painter->drawEllipse(QPointF(
x,
y), w, w);
554 QBrush b = painter->brush();
555 painter->setBrush(painter->pen().color());
556 painter->drawEllipse(QPointF(
x,
y), w, w);
557 painter->setBrush(b);
574 painter->
drawLine(QLineF(
x - w * 0.707,
y - w * 0.707,
575 x + w * 0.707,
y + w * 0.707));
576 painter->
drawLine(QLineF(
x - w * 0.707,
y + w * 0.707,
577 x + w * 0.707,
y - w * 0.707));
582 QLineF(
x - w,
y + 0.755 * w,
x + w,
y + 0.755 * w));
583 painter->
drawLine(QLineF(
x + w,
y + 0.755 * w,
x,
y - 0.977 * w));
584 painter->
drawLine(QLineF(
x,
y - 0.977 * w,
x - w,
y + 0.755 * w));
589 QLineF(
x - w,
y - 0.755 * w,
x + w,
y - 0.755 * w));
590 painter->
drawLine(QLineF(
x + w,
y - 0.755 * w,
x,
y + 0.977 * w));
591 painter->
drawLine(QLineF(
x,
y + 0.977 * w,
x - w,
y - 0.755 * w));
595 painter->
drawLine(QLineF(
x - w,
y - w,
x + w * 0.95,
y + w * 0.95));
596 painter->
drawLine(QLineF(
x - w,
y + w * 0.95,
x + w * 0.95,
y - w));
607 painter->
drawLine(QLineF(
x - w * 0.707,
y - w * 0.707,
608 x + w * 0.670,
y + w * 0.670));
609 painter->
drawLine(QLineF(
x - w * 0.707,
y + w * 0.670,
610 x + w * 0.670,
y - w * 0.707));
611 painter->drawEllipse(QPointF(
x,
y), w, w);
617 painter->drawEllipse(QPointF(
x,
y), w, w);
622 painter->
drawLine(QLineF(
x,
y,
x - w * 0.707,
y + w * 0.707));
623 painter->
drawLine(QLineF(
x,
y,
x + w * 0.707,
y + w * 0.707));
624 painter->drawEllipse(QPointF(
x,
y), w, w);
628 painter->drawPixmap(
x -
mPixmap.width() * 0.5,
633 QTransform oldTransform = painter->transform();
634 painter->translate(
x,
y);
637 painter->setTransform(oldTransform);
724 : QObject(parentPlot),
725 mParentPlot(parentPlot),
747 qDebug() << Q_FUNC_INFO
748 <<
"The parent plot's mCurrentLayer will be a dangling "
749 "pointer. Should have been set to a valid layer or 0 "
782 qDebug() << Q_FUNC_INFO <<
"layerable is already child of this layer"
783 <<
reinterpret_cast<quintptr
>(layerable);
797 qDebug() << Q_FUNC_INFO <<
"layerable is not child of this layer"
798 <<
reinterpret_cast<quintptr
>(layerable);
920 mParentLayerable(parentLayerable),
924 if (targetLayer.isEmpty())
925 setLayer(mParentPlot->currentLayer());
926 else if (!setLayer(targetLayer))
927 qDebug() << Q_FUNC_INFO <<
"setting QCPlayerable initial layer to"
928 << targetLayer <<
"failed.";
963 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
969 qDebug() << Q_FUNC_INFO <<
"there is no layer with name" << layerName;
1044 bool onlySelectable,
1045 QVariant *details)
const {
1047 Q_UNUSED(onlySelectable)
1072 qDebug() << Q_FUNC_INFO
1073 <<
"called with mParentPlot already initialized";
1077 if (!
parentPlot) qDebug() << Q_FUNC_INFO <<
"called with parentPlot zero";
1109 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
1113 qDebug() << Q_FUNC_INFO <<
"layer" <<
layer->
name()
1114 <<
"is not in same QCustomPlot as this layerable";
1136 bool localAntialiased,
1235 const QVariant &details,
1236 bool *selectionStateChanged) {
1240 Q_UNUSED(selectionStateChanged)
1256 Q_UNUSED(selectionStateChanged)
1341 result.expand(otherRange);
1360 double rangeFac = 1
e-3;
1362 sanitizedRange.normalize();
1367 if (sanitizedRange.lower == 0.0 && sanitizedRange.upper != 0.0) {
1369 if (rangeFac < sanitizedRange.upper * rangeFac)
1370 sanitizedRange.lower = rangeFac;
1372 sanitizedRange.lower = sanitizedRange.upper * rangeFac;
1374 else if (sanitizedRange.lower != 0.0 && sanitizedRange.upper == 0.0) {
1376 if (-rangeFac > sanitizedRange.lower * rangeFac)
1377 sanitizedRange.upper = -rangeFac;
1379 sanitizedRange.upper = sanitizedRange.lower * rangeFac;
1380 }
else if (sanitizedRange.lower < 0 && sanitizedRange.upper > 0) {
1383 if (-sanitizedRange.lower > sanitizedRange.upper) {
1385 if (-rangeFac > sanitizedRange.lower * rangeFac)
1386 sanitizedRange.upper = -rangeFac;
1388 sanitizedRange.upper = sanitizedRange.lower * rangeFac;
1391 if (rangeFac < sanitizedRange.upper * rangeFac)
1392 sanitizedRange.lower = rangeFac;
1394 sanitizedRange.lower = sanitizedRange.upper * rangeFac;
1399 return sanitizedRange;
1408 sanitizedRange.normalize();
1409 return sanitizedRange;
1516 : QObject(parentPlot), mParentPlot(parentPlot) {
1517 mChildren.insert(
QCP::msLeft, QList<QCPLayoutElement *>());
1518 mChildren.insert(
QCP::msRight, QList<QCPLayoutElement *>());
1519 mChildren.insert(
QCP::msTop, QList<QCPLayoutElement *>());
1520 mChildren.insert(
QCP::msBottom, QList<QCPLayoutElement *>());
1530 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement *>> it(
mChildren);
1531 while (it.hasNext()) {
1533 if (!it.value().isEmpty())
return false;
1545 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement *>> it(
mChildren);
1546 while (it.hasNext()) {
1548 const QList<QCPLayoutElement *>
elements = it.value();
1549 for (
int i =
elements.size() - 1; i >= 0; --i)
1572 for (
int i = 0; i <
elements.size(); ++i) {
1573 if (!
elements.at(i)->autoMargins().testFlag(side))
continue;
1575 elements.at(i)->calculateAutoMargin(side),
1593 qDebug() << Q_FUNC_INFO
1594 <<
"element is already child of this margin group side"
1595 <<
reinterpret_cast<quintptr
>(element);
1607 if (!
mChildren[side].removeOne(element))
1608 qDebug() << Q_FUNC_INFO
1609 <<
"element is not child of this margin group side"
1610 <<
reinterpret_cast<quintptr
>(element);
1713 mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX),
1715 mOuterRect(0, 0, 0, 0),
1716 mMargins(0, 0, 0, 0),
1717 mMinimumMargins(0, 0, 0, 0),
1724 if (qobject_cast<QCPLayout *>(
1862 QVector<QCP::MarginSide> sideVector;
1868 for (
int i = 0; i < sideVector.size(); ++i) {
1908 QList<QCP::MarginSide> allMarginSides =
1972 return QList<QCPLayoutElement *>();
1988 bool onlySelectable,
1989 QVariant *details)
const {
1992 if (onlySelectable)
return -1;
1998 qDebug() << Q_FUNC_INFO <<
"parent plot not defined";
2133 for (
int i = 0; i < elCount; ++i) {
2141 QList<QCPLayoutElement *>
result;
2142 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
2147 for (
int i = 0; i < c; ++i) {
2194 if (
take(element)) {
2225 if (QWidget *w = qobject_cast<QWidget *>(parent()))
2226 w->updateGeometry();
2227 else if (
QCPLayout *l = qobject_cast<QCPLayout *>(parent()))
2228 l->sizeConstraintsChanged();
2264 el->setParent(
this);
2267 qDebug() << Q_FUNC_INFO <<
"Null element passed";
2289 qDebug() << Q_FUNC_INFO <<
"Null element passed";
2328 QVector<int> minSizes,
2329 QVector<double> stretchFactors,
2330 int totalSize)
const {
2331 if (maxSizes.size() != minSizes.size() ||
2332 minSizes.size() != stretchFactors.size()) {
2333 qDebug() << Q_FUNC_INFO
2334 <<
"Passed vector sizes aren't equal:" << maxSizes << minSizes
2336 return QVector<int>();
2338 if (stretchFactors.isEmpty())
return QVector<int>();
2339 int sectionCount = stretchFactors.size();
2340 QVector<double> sectionSizes(sectionCount);
2344 for (
int i = 0; i < sectionCount; ++i) minSizeSum += minSizes.at(i);
2345 if (totalSize < minSizeSum) {
2348 for (
int i = 0; i < sectionCount; ++i) {
2349 stretchFactors[i] = minSizes.at(i);
2354 QList<int> minimumLockedSections;
2355 QList<int> unfinishedSections;
2356 for (
int i = 0; i < sectionCount; ++i) unfinishedSections.append(i);
2357 double freeSize = totalSize;
2359 int outerIterations = 0;
2360 while (!unfinishedSections.isEmpty() &&
2367 int innerIterations = 0;
2368 while (!unfinishedSections.isEmpty() &&
2377 double nextMax = 1e12;
2378 for (
int i = 0; i < unfinishedSections.size(); ++i) {
2379 int secId = unfinishedSections.at(i);
2381 (maxSizes.at(secId) - sectionSizes.at(secId)) /
2382 stretchFactors.at(secId);
2383 if (hitsMaxAt < nextMax) {
2384 nextMax = hitsMaxAt;
2392 double stretchFactorSum = 0;
2393 for (
int i = 0; i < unfinishedSections.size(); ++i)
2394 stretchFactorSum += stretchFactors.at(unfinishedSections.at(i));
2395 double nextMaxLimit = freeSize / stretchFactorSum;
2400 for (
int i = 0; i < unfinishedSections.size(); ++i) {
2401 sectionSizes[unfinishedSections.at(i)] +=
2402 nextMax * stretchFactors.at(unfinishedSections.at(
2404 freeSize -= nextMax *
2405 stretchFactors.at(unfinishedSections.at(i));
2407 unfinishedSections.removeOne(
2413 for (
int i = 0; i < unfinishedSections.size(); ++i)
2414 sectionSizes[unfinishedSections.at(i)] +=
2416 stretchFactors.at(unfinishedSections.at(
2418 unfinishedSections.clear();
2421 if (innerIterations == sectionCount * 2)
2422 qDebug() << Q_FUNC_INFO
2423 <<
"Exceeded maximum expected inner iteration count, "
2424 "layouting aborted. Input was:"
2425 << maxSizes << minSizes << stretchFactors << totalSize;
2429 bool foundMinimumViolation =
false;
2430 for (
int i = 0; i < sectionSizes.size(); ++i) {
2431 if (minimumLockedSections.contains(i))
continue;
2432 if (sectionSizes.at(i) <
2435 sectionSizes[i] = minSizes.at(i);
2436 foundMinimumViolation =
true;
2438 minimumLockedSections.append(i);
2441 if (foundMinimumViolation) {
2442 freeSize = totalSize;
2443 for (
int i = 0; i < sectionCount; ++i) {
2444 if (!minimumLockedSections.contains(
2447 unfinishedSections.append(i);
2449 freeSize -= sectionSizes.at(
2455 for (
int i = 0; i < unfinishedSections.size(); ++i)
2456 sectionSizes[unfinishedSections.at(i)] = 0;
2459 if (outerIterations == sectionCount * 2)
2460 qDebug() << Q_FUNC_INFO
2461 <<
"Exceeded maximum expected outer iteration count, "
2462 "layouting aborted. Input was:"
2463 << maxSizes << minSizes << stretchFactors << totalSize;
2465 QVector<int>
result(sectionCount);
2466 for (
int i = 0; i < sectionCount; ++i)
2467 result[i] = qRound(sectionSizes.at(i));
2516 if (row >= 0 && row <
mElements.size()) {
2517 if (column >= 0 && column <
mElements.first().size()) {
2521 qDebug() << Q_FUNC_INFO
2522 <<
"Requested cell is empty. Row:" << row
2523 <<
"Column:" << column;
2525 qDebug() << Q_FUNC_INFO <<
"Invalid column. Row:" << row
2526 <<
"Column:" << column;
2528 qDebug() << Q_FUNC_INFO <<
"Invalid row. Row:" << row
2529 <<
"Column:" << column;
2572 qDebug() << Q_FUNC_INFO
2573 <<
"There is already an element in the specified "
2577 qDebug() << Q_FUNC_INFO
2578 <<
"Can't add null element to row/column:" << row << column;
2612 qDebug() << Q_FUNC_INFO
2613 <<
"Invalid stretch factor, must be positive:" << factor;
2615 qDebug() << Q_FUNC_INFO <<
"Invalid column:" << column;
2636 qDebug() << Q_FUNC_INFO
2637 <<
"Invalid stretch factor, must be positive:"
2643 qDebug() << Q_FUNC_INFO
2644 <<
"Column count not equal to passed stretch factor count:"
2661 if (row >= 0 && row <
rowCount()) {
2665 qDebug() << Q_FUNC_INFO
2666 <<
"Invalid stretch factor, must be positive:" << factor;
2668 qDebug() << Q_FUNC_INFO <<
"Invalid row:" << row;
2689 qDebug() << Q_FUNC_INFO
2690 <<
"Invalid stretch factor, must be positive:"
2696 qDebug() << Q_FUNC_INFO
2697 <<
"Row count not equal to passed stretch factor count:"
2733 mElements.append(QList<QCPLayoutElement *>());
2737 int newColCount = qMax(
columnCount(), newColumnCount);
2738 for (
int i = 0; i <
rowCount(); ++i) {
2761 if (newIndex < 0) newIndex = 0;
2765 QList<QCPLayoutElement *> newRow;
2787 if (newIndex < 0) newIndex = 0;
2791 for (
int row = 0; row <
rowCount(); ++row)
2797 QVector<int> minColWidths, minRowHeights, maxColWidths, maxRowHeights;
2805 mRect.width() - totalColSpacing);
2806 QVector<int> rowHeights =
getSectionSizes(maxRowHeights, minRowHeights,
2808 mRect.height() - totalRowSpacing);
2811 int yOffset =
mRect.top();
2812 for (
int row = 0; row <
rowCount(); ++row) {
2813 if (row > 0) yOffset += rowHeights.at(row - 1) +
mRowSpacing;
2814 int xOffset =
mRect.left();
2818 mElements.at(row).at(col)->setOuterRect(
2819 QRect(xOffset, yOffset, colWidths.at(col),
2820 rowHeights.at(row)));
2843 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
2857 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
2859 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
2865 QList<QCPLayoutElement *>
result;
2868 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
2869 result.reserve(colC * rowC);
2871 for (
int row = 0; row < rowC; ++row) {
2872 for (
int col = 0; col < colC; ++col) {
2878 for (
int i = 0; i < c; ++i) {
2891 for (
int row =
rowCount() - 1; row >= 0; --row) {
2892 bool hasElements =
false;
2911 for (
int col =
columnCount() - 1; col >= 0; --col) {
2912 bool hasElements =
false;
2913 for (
int row = 0; row <
rowCount(); ++row) {
2921 for (
int row = 0; row <
rowCount(); ++row)
2929 QVector<int> minColWidths, minRowHeights;
2932 for (
int i = 0; i < minColWidths.size(); ++i)
2933 result.rwidth() += minColWidths.at(i);
2934 for (
int i = 0; i < minRowHeights.size(); ++i)
2935 result.rheight() += minRowHeights.at(i);
2945 QVector<int> maxColWidths, maxRowHeights;
2949 for (
int i = 0; i < maxColWidths.size(); ++i)
2951 qMin(
result.width() + maxColWidths.at(i), QWIDGETSIZE_MAX));
2952 for (
int i = 0; i < maxRowHeights.size(); ++i)
2954 qMin(
result.height() + maxRowHeights.at(i), QWIDGETSIZE_MAX));
2976 QVector<int> *minRowHeights)
const {
2978 *minRowHeights = QVector<int>(
rowCount(), 0);
2979 for (
int row = 0; row <
rowCount(); ++row) {
2982 QSize minHint =
mElements.at(row).at(col)->minimumSizeHint();
2983 QSize min =
mElements.at(row).at(col)->minimumSize();
2984 QSize
final(min.width() > 0 ? min.width() : minHint.width(),
2985 min.height() > 0 ? min.height() : minHint.height());
2986 if (minColWidths->at(col) <
final.width())
2987 (*minColWidths)[col] =
final.width();
2988 if (minRowHeights->at(row) <
final.height())
2989 (*minRowHeights)[row] =
final.height();
3009 QVector<int> *maxRowHeights)
const {
3010 *maxColWidths = QVector<int>(
columnCount(), QWIDGETSIZE_MAX);
3011 *maxRowHeights = QVector<int>(
rowCount(), QWIDGETSIZE_MAX);
3012 for (
int row = 0; row <
rowCount(); ++row) {
3015 QSize maxHint =
mElements.at(row).at(col)->maximumSizeHint();
3016 QSize max =
mElements.at(row).at(col)->maximumSize();
3017 QSize
final(max.width() < QWIDGETSIZE_MAX ? max.width()
3019 max.height() < QWIDGETSIZE_MAX ? max.height()
3020 : maxHint.height());
3021 if (maxColWidths->at(col) >
final.width())
3022 (*maxColWidths)[col] =
final.width();
3023 if (maxRowHeights->at(row) >
final.height())
3024 (*maxRowHeights)[row] =
final.height();
3084 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3098 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3111 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3127 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3143 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3164 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3169 for (
int i = 0; i <
mElements.size(); ++i) {
3171 QSize finalMinSize, finalMaxSize;
3172 QSize minSizeHint =
mElements.at(i)->minimumSizeHint();
3173 QSize maxSizeHint =
mElements.at(i)->maximumSizeHint();
3174 finalMinSize.setWidth(
mElements.at(i)->minimumSize().width() > 0
3175 ?
mElements.at(i)->minimumSize().width()
3176 : minSizeHint.width());
3177 finalMinSize.setHeight(
mElements.at(i)->minimumSize().height() > 0
3178 ?
mElements.at(i)->minimumSize().height()
3179 : minSizeHint.height());
3180 finalMaxSize.setWidth(
mElements.at(i)->maximumSize().width() <
3182 ?
mElements.at(i)->maximumSize().width()
3183 : maxSizeHint.width());
3184 finalMaxSize.setHeight(
mElements.at(i)->maximumSize().height() <
3186 ?
mElements.at(i)->maximumSize().height()
3187 : maxSizeHint.height());
3194 if (
insetRect.size().width() < finalMinSize.width())
3195 insetRect.setWidth(finalMinSize.width());
3196 if (
insetRect.size().height() < finalMinSize.height())
3197 insetRect.setHeight(finalMinSize.height());
3198 if (
insetRect.size().width() > finalMaxSize.width())
3199 insetRect.setWidth(finalMaxSize.width());
3200 if (
insetRect.size().height() > finalMaxSize.height())
3201 insetRect.setHeight(finalMaxSize.height());
3205 if (al.testFlag(Qt::AlignLeft))
3207 else if (al.testFlag(Qt::AlignRight))
3211 finalMinSize.width() *
3213 if (al.testFlag(Qt::AlignTop))
3215 else if (al.testFlag(Qt::AlignBottom))
3219 finalMinSize.height() *
3231 if (index >= 0 && index <
mElements.size())
3247 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
3261 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
3263 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
3279 bool onlySelectable,
3280 QVariant *details)
const {
3282 if (onlySelectable)
return -1;
3284 for (
int i = 0; i <
mElements.size(); ++i) {
3288 if (
mElements.at(i)->realVisibility() &&
3289 mElements.at(i)->selectTest(pos, onlySelectable) >= 0)
3314 mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4));
3317 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
3342 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
3376 : mStyle(esNone), mWidth(8), mLength(10), mInverted(false) {}
3385 : mStyle(style), mWidth(
width), mLength(length), mInverted(inverted) {}
3497 const QVector2D &pos,
3498 const QVector2D &dir)
const {
3501 QVector2D lengthVec(dir.normalized());
3502 if (lengthVec.isNull()) lengthVec = QVector2D(1, 0);
3503 QVector2D widthVec(-lengthVec.y(), lengthVec.x());
3507 QPen penBackup = painter->pen();
3508 QBrush brushBackup = painter->brush();
3509 QPen miterPen = penBackup;
3510 miterPen.setJoinStyle(Qt::MiterJoin);
3511 QBrush brush(painter->pen().color(), Qt::SolidPattern);
3516 QPointF
points[3] = {pos.toPointF(),
3517 (pos - lengthVec + widthVec).toPointF(),
3518 (pos - lengthVec - widthVec).toPointF()};
3519 painter->
setPen(miterPen);
3520 painter->setBrush(brush);
3521 painter->drawConvexPolygon(
points, 3);
3522 painter->setBrush(brushBackup);
3523 painter->
setPen(penBackup);
3527 QPointF
points[4] = {pos.toPointF(),
3528 (pos - lengthVec + widthVec).toPointF(),
3529 (pos - lengthVec * 0.8f).toPointF(),
3530 (pos - lengthVec - widthVec).toPointF()};
3531 painter->
setPen(miterPen);
3532 painter->setBrush(brush);
3533 painter->drawConvexPolygon(
points, 4);
3534 painter->setBrush(brushBackup);
3535 painter->
setPen(penBackup);
3539 QPointF
points[3] = {(pos - lengthVec + widthVec).toPointF(),
3541 (pos - lengthVec - widthVec).toPointF()};
3542 painter->
setPen(miterPen);
3543 painter->drawPolyline(
points, 3);
3544 painter->
setPen(penBackup);
3548 painter->setBrush(brush);
3549 painter->drawEllipse(pos.toPointF(),
mWidth * 0.5,
mWidth * 0.5);
3550 painter->setBrush(brushBackup);
3554 QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
3555 QPointF
points[4] = {(pos - widthVecPerp + widthVec).toPointF(),
3556 (pos - widthVecPerp - widthVec).toPointF(),
3557 (pos + widthVecPerp - widthVec).toPointF(),
3558 (pos + widthVecPerp + widthVec).toPointF()};
3559 painter->
setPen(miterPen);
3560 painter->setBrush(brush);
3561 painter->drawConvexPolygon(
points, 4);
3562 painter->setBrush(brushBackup);
3563 painter->
setPen(penBackup);
3567 QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
3568 QPointF
points[4] = {(pos - widthVecPerp).toPointF(),
3569 (pos - widthVec).toPointF(),
3570 (pos + widthVecPerp).toPointF(),
3571 (pos + widthVec).toPointF()};
3572 painter->
setPen(miterPen);
3573 painter->setBrush(brush);
3574 painter->drawConvexPolygon(
points, 4);
3575 painter->setBrush(brushBackup);
3576 painter->
setPen(penBackup);
3580 painter->
drawLine((pos + widthVec).toPointF(),
3581 (pos - widthVec).toPointF());
3585 painter->
drawLine((pos + widthVec).toPointF(), pos.toPointF());
3589 if (qFuzzyIsNull(painter->pen().widthF()) &&
3593 painter->
drawLine((pos + widthVec +
3594 lengthVec * 0.2f * (
mInverted ? -1 : 1))
3597 lengthVec * 0.2f * (
mInverted ? -1 : 1))
3605 lengthVec * 0.2f * (
mInverted ? -1 : 1) +
3607 qMax(1.0f, (
float)painter->pen().widthF()) *
3611 lengthVec * 0.2f * (
mInverted ? -1 : 1) +
3613 qMax(1.0f, (
float)painter->pen().widthF()) *
3629 const QVector2D &pos,
3630 double angle)
const {
3631 draw(painter, pos, QVector2D(qCos(angle), qSin(angle)));
3660 :
QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis),
3661 mParentAxis(parentAxis) {
3664 setParent(parentAxis);
3665 setPen(QPen(QColor(200, 200, 200), 0, Qt::DotLine));
3666 setSubGridPen(QPen(QColor(220, 220, 220), 0, Qt::DotLine));
3667 setZeroLinePen(QPen(QColor(200, 200, 200), 0, Qt::SolidLine));
3668 setSubGridVisible(
false);
3669 setAntialiased(
false);
3670 setAntialiasedSubGrid(
false);
3671 setAntialiasedZeroLine(
false);
3740 qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
3756 qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
3765 int zeroLineIndex = -1;
3773 for (
int i = lowTick; i <= highTick; ++i) {
3788 for (
int i = lowTick; i <= highTick; ++i) {
3789 if (i == zeroLineIndex)
3797 int zeroLineIndex = -1;
3805 for (
int i = lowTick; i <= highTick; ++i) {
3820 for (
int i = lowTick; i <= highTick; ++i) {
3821 if (i == zeroLineIndex)
3838 qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
3977 :
QCPLayerable(parent->parentPlot(), QString(), parent),
3982 mOrientation(orientation(
type)),
3983 mSelectableParts(spAxis | spTickLabels | spAxisLabel),
3984 mSelectedParts(spNone),
3985 mBasePen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
3986 mSelectedBasePen(QPen(Qt::
blue, 2)),
3989 mLabelFont(mParentPlot->font()),
3991 QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)),
3992 mLabelColor(Qt::
black),
3993 mSelectedLabelColor(Qt::
blue),
3996 mAutoTickLabels(true),
3997 mTickLabelType(ltNumber),
3998 mTickLabelFont(mParentPlot->font()),
3999 mSelectedTickLabelFont(QFont(mTickLabelFont.family(),
4000 mTickLabelFont.pointSize(),
4002 mTickLabelColor(Qt::
black),
4003 mSelectedTickLabelColor(Qt::
blue),
4004 mDateTimeFormat(QLatin1String(
"hh:mm:ss\ndd.MM.yy")),
4005 mDateTimeSpec(Qt::LocalTime),
4006 mNumberPrecision(6),
4007 mNumberFormatChar(
'g'),
4008 mNumberBeautifulPowers(true),
4015 mAutoTickStep(true),
4016 mAutoSubTicks(true),
4017 mTickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
4018 mSelectedTickPen(QPen(Qt::
blue, 2)),
4019 mSubTickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
4020 mSelectedSubTickPen(QPen(Qt::
blue, 2)),
4023 mRangeReversed(false),
4024 mScaleType(stLinear),
4026 mScaleLogBaseLogInv(1.0 / qLn(mScaleLogBase)),
4029 mAxisPainter(new QCPAxisPainterPrivate(parent->parentPlot())),
4030 mLowestVisibleTick(0),
4031 mHighestVisibleTick(-1),
4032 mCachedMarginValid(false),
4035 setAntialiased(
false);
4036 setLayer(mParentPlot
4041 if (
type == atTop) {
4042 setTickLabelPadding(3);
4044 }
else if (
type == atRight) {
4045 setTickLabelPadding(7);
4046 setLabelPadding(12);
4047 }
else if (
type == atBottom) {
4048 setTickLabelPadding(3);
4050 }
else if (
type == atLeft) {
4051 setTickLabelPadding(5);
4052 setLabelPadding(10);
4080 result.append(QLatin1Char(
'b'));
4152 qDebug() << Q_FUNC_INFO
4153 <<
"Invalid logarithmic scale base (must be greater 1):"
4264 Qt::AlignmentFlag alignment) {
4265 if (alignment == Qt::AlignLeft)
4267 else if (alignment == Qt::AlignRight)
4365 if (approximateCount > 0) {
4369 qDebug() << Q_FUNC_INFO
4370 <<
"approximateCount must be greater than zero:"
4371 << approximateCount;
4538 if (!qFuzzyIsNull(degrees -
mAxisPainter->tickLabelRotation)) {
4539 mAxisPainter->tickLabelRotation = qBound(-90.0, degrees, 90.0);
4629 if (formatCode.isEmpty()) {
4630 qDebug() << Q_FUNC_INFO <<
"Passed formatCode is empty";
4636 QString allowedFormatChars(QLatin1String(
"eEfgG"));
4637 if (allowedFormatChars.contains(formatCode.at(0))) {
4640 qDebug() << Q_FUNC_INFO
4641 <<
"Invalid number format code (first char not in 'eEfgG'):"
4645 if (formatCode.length() < 2) {
4652 if (formatCode.at(1) == QLatin1Char(
'b') &&
4657 qDebug() << Q_FUNC_INFO
4658 <<
"Invalid number format code (second char not 'b' or first "
4659 "char neither 'e' nor 'g'):"
4663 if (formatCode.length() < 3) {
4669 if (formatCode.at(2) == QLatin1Char(
'c')) {
4671 }
else if (formatCode.at(2) == QLatin1Char(
'd')) {
4674 qDebug() << Q_FUNC_INFO
4675 <<
"Invalid number format code (third char neither 'c' nor "
5096 qDebug() << Q_FUNC_INFO
5097 <<
"Center of scaling operation doesn't lie in same "
5098 "logarithmic sign domain as range:"
5121 int otherPixelSize, ownPixelSize;
5133 double newRangeSize = ratio * otherAxis->
range().
size() * ownPixelSize /
5134 (double)otherPixelSize;
5145 QList<QCPAbstractPlottable *> p =
plottables();
5147 bool haveRange =
false;
5148 for (
int i = 0; i < p.size(); ++i) {
5149 if (!p.at(i)->realVisibility() && onlyVisiblePlottables)
continue;
5151 bool currentFoundRange;
5157 if (p.at(i)->keyAxis() ==
this)
5159 p.at(i)->getKeyRange(currentFoundRange, signDomain);
5162 p.at(i)->getValueRange(currentFoundRange, signDomain);
5163 if (currentFoundRange) {
5165 newRange = plottableRange;
5167 newRange.
expand(plottableRange);
5178 double center = (newRange.
lower + newRange.
upper) *
5272 else if (value <= 0 &&
5308 else if (value <= 0 &&
5343 if (
mAxisPainter->axisSelectionBox().contains(pos.toPoint()))
5345 else if (
mAxisPainter->tickLabelsSelectionBox().contains(pos.toPoint()))
5347 else if (
mAxisPainter->labelSelectionBox().contains(pos.toPoint()))
5355 bool onlySelectable,
5356 QVariant *details)
const {
5362 if (details) details->setValue(part);
5374 QList<QCPAbstractPlottable *>
result;
5391 QList<QCPGraph *>
result;
5410 QList<QCPAbstractItem *>
result;
5414 QList<QCPItemPosition *> positions =
5416 for (
int posId = 0; posId < positions.size(); ++posId) {
5417 if (positions.at(posId)->keyAxis() ==
this ||
5418 positions.at(posId)->valueAxis() ==
this) {
5444 qDebug() << Q_FUNC_INFO <<
"Invalid margin side passed:" << (int)side;
5467 qDebug() << Q_FUNC_INFO <<
"invalid axis type";
5503 double subTickStep = 0;
5504 double subTickPosition = 0;
5505 int subTickIndex = 0;
5512 for (
int i = lowTick + 1; i <= highTick; ++i) {
5516 subTickPosition =
mTickVector.at(i - 1) + k * subTickStep;
5542 QT_VERSION_CHECK(4, 7, \
5552 QDateTime::fromMSecsSinceEpoch(
mTickVector.at(i) * 1000)
5591 double magnitudeFactor =
5595 double tickStepMantissa =
mTickStep / magnitudeFactor;
5596 if (tickStepMantissa < 5) {
5598 mTickStep = (int)(tickStepMantissa * 2) / 2.0 * magnitudeFactor;
5602 (int)(tickStepMantissa / 2.0) * 2.0 * magnitudeFactor;
5613 int tickcount = lastStep - firstStep + 1;
5614 if (tickcount < 0) tickcount = 0;
5616 for (
int i = 0; i < tickcount; ++i)
5624 double currentMag = lowerMag;
5637 double currentMag = lowerMag;
5651 qDebug() << Q_FUNC_INFO
5652 <<
"Invalid range for logarithmic plot: " <<
mRange.
lower
5678 double magnitudeFactor = qPow(
5680 qFloor(qLn(
tickStep) / qLn(10.0)));
5682 double tickStepMantissa =
tickStep / magnitudeFactor;
5685 double epsilon = 0.01;
5688 double fracPart = modf(tickStepMantissa, &intPartf);
5692 if (fracPart < epsilon || 1.0 - fracPart < epsilon) {
5693 if (1.0 - fracPart < epsilon) ++intPart;
5725 if (qAbs(fracPart - 0.5) < epsilon)
5768 const QVariant &details,
5769 bool *selectionStateChanged) {
5775 if (selectionStateChanged)
5784 if (selectionStateChanged)
5815 QVector<double> subTickPositions;
5817 QVector<double> tickPositions;
5820 tickPositions.reserve(highTick - lowTick + 1);
5825 for (
int i = lowTick; i <= highTick; ++i) {
5882 bool lowFound =
false;
5883 bool highFound =
false;
5894 for (
int i =
mTickVector.size() - 1; i >= 0; --i) {
5902 if (!lowFound && highFound)
5903 lowIndex = highIndex + 1;
5904 else if (lowFound && !highFound)
5905 highIndex = lowIndex - 1;
6026 int lowTick, highTick;
6028 QVector<double> tickPositions;
6031 tickPositions.reserve(highTick - lowTick + 1);
6034 for (
int i = lowTick; i <= highTick; ++i) {
6082 QCPAxisPainterPrivate::QCPAxisPainterPrivate(
QCustomPlot *parentPlot)
6084 basePen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
6088 tickLabelPadding(0),
6089 tickLabelRotation(0),
6090 tickLabelSide(
QCPAxis::lsOutside),
6091 substituteExponent(true),
6092 numberMultiplyCross(false),
6096 subTickLengthOut(0),
6097 tickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
6098 subTickPen(QPen(Qt::
black, 0, Qt::SolidLine, Qt::SquareCap)),
6100 abbreviateDecimalPowers(false),
6101 reversedEndings(false),
6102 mParentPlot(parentPlot),
6106 QCPAxisPainterPrivate::~QCPAxisPainterPrivate() {}
6115 void QCPAxisPainterPrivate::draw(
QCPPainter *painter) {
6116 QByteArray newHash = generateLabelParameterHash();
6117 if (newHash != mLabelParameterHash) {
6118 mLabelCache.clear();
6119 mLabelParameterHash = newHash;
6154 painter->
setPen(basePen);
6156 baseLine.setPoints(
origin + QPointF(xCor, yCor),
6157 origin + QPointF(axisRect.width() + xCor, yCor));
6159 baseLine.setPoints(
origin + QPointF(xCor, yCor),
6160 origin + QPointF(xCor, -axisRect.height() + yCor));
6161 if (reversedEndings)
6162 baseLine = QLineF(baseLine.p2(),
6168 if (!tickPositions.isEmpty()) {
6169 painter->
setPen(tickPen);
6175 for (
int i = 0; i < tickPositions.size(); ++i)
6177 QLineF(tickPositions.at(i) + xCor,
6178 origin.y() - tickLengthOut * tickDir + yCor,
6179 tickPositions.at(i) + xCor,
6180 origin.y() + tickLengthIn * tickDir + yCor));
6182 for (
int i = 0; i < tickPositions.size(); ++i)
6184 QLineF(
origin.x() - tickLengthOut * tickDir + xCor,
6185 tickPositions.at(i) + yCor,
6186 origin.x() + tickLengthIn * tickDir + xCor,
6187 tickPositions.at(i) + yCor));
6192 if (!subTickPositions.isEmpty()) {
6193 painter->
setPen(subTickPen);
6200 for (
int i = 0; i < subTickPositions.size(); ++i)
6202 QLineF(subTickPositions.at(i) + xCor,
6203 origin.y() - subTickLengthOut * tickDir + yCor,
6204 subTickPositions.at(i) + xCor,
6205 origin.y() + subTickLengthIn * tickDir + yCor));
6207 for (
int i = 0; i < subTickPositions.size(); ++i)
6209 QLineF(
origin.x() - subTickLengthOut * tickDir + xCor,
6210 subTickPositions.at(i) + yCor,
6211 origin.x() + subTickLengthIn * tickDir + xCor,
6212 subTickPositions.at(i) + yCor));
6215 margin += qMax(0, qMax(tickLengthOut, subTickLengthOut));
6221 painter->setBrush(QBrush(basePen.color()));
6222 QVector2D baseLineVector(baseLine.dx(), baseLine.dy());
6224 lowerEnding.draw(painter,
6225 QVector2D(baseLine.p1()) -
6226 baseLineVector.normalized() *
6227 lowerEnding.realLength() *
6228 (lowerEnding.inverted() ? -1 : 1),
6231 upperEnding.draw(painter,
6232 QVector2D(baseLine.p2()) +
6233 baseLineVector.normalized() *
6234 upperEnding.realLength() *
6235 (upperEnding.inverted() ? -1 : 1),
6244 oldClipRect = painter->clipRegion().boundingRect();
6245 painter->setClipRect(axisRect);
6247 QSize tickLabelsSize(0, 0);
6249 if (!tickLabels.isEmpty()) {
6251 painter->setFont(tickLabelFont);
6252 painter->
setPen(QPen(tickLabelColor));
6253 const int maxLabelIndex = qMin(tickPositions.size(), tickLabels.size());
6254 int distanceToAxis = margin;
6257 -(qMax(tickLengthIn, subTickLengthIn) + tickLabelPadding);
6258 for (
int i = 0; i < maxLabelIndex; ++i)
6259 placeTickLabel(painter, tickPositions.at(i), distanceToAxis,
6260 tickLabels.at(i), &tickLabelsSize);
6263 ? tickLabelsSize.height()
6264 : tickLabelsSize.width();
6270 if (!label.isEmpty()) {
6271 margin += labelPadding;
6272 painter->setFont(labelFont);
6273 painter->
setPen(QPen(labelColor));
6274 labelBounds = painter->fontMetrics().boundingRect(
6275 0, 0, 0, 0, Qt::TextDontClip, label);
6277 QTransform oldTransform = painter->transform();
6278 painter->translate((
origin.x() - margin - labelBounds.height()),
6280 painter->rotate(-90);
6281 painter->drawText(0, 0, axisRect.height(), labelBounds.height(),
6282 Qt::TextDontClip | Qt::AlignCenter, label);
6283 painter->setTransform(oldTransform);
6285 QTransform oldTransform = painter->transform();
6286 painter->translate((
origin.x() + margin + labelBounds.height()),
6287 origin.y() - axisRect.height());
6288 painter->rotate(90);
6289 painter->drawText(0, 0, axisRect.height(), labelBounds.height(),
6290 Qt::TextDontClip | Qt::AlignCenter, label);
6291 painter->setTransform(oldTransform);
6293 painter->drawText(
origin.x(),
6294 origin.y() - margin - labelBounds.height(),
6295 axisRect.width(), labelBounds.height(),
6296 Qt::TextDontClip | Qt::AlignCenter, label);
6298 painter->drawText(
origin.x(),
origin.y() + margin, axisRect.width(),
6299 labelBounds.height(),
6300 Qt::TextDontClip | Qt::AlignCenter, label);
6304 int selectionTolerance = 0;
6306 selectionTolerance = mParentPlot->selectionTolerance();
6308 qDebug() << Q_FUNC_INFO <<
"mParentPlot is null";
6309 int selAxisOutSize =
6310 qMax(qMax(tickLengthOut, subTickLengthOut), selectionTolerance);
6311 int selAxisInSize = selectionTolerance;
6312 int selTickLabelSize;
6313 int selTickLabelOffset;
6316 ? tickLabelsSize.height()
6317 : tickLabelsSize.width());
6318 selTickLabelOffset =
6319 qMax(tickLengthOut, subTickLengthOut) + tickLabelPadding;
6322 ? tickLabelsSize.height()
6323 : tickLabelsSize.width());
6324 selTickLabelOffset =
6325 -(qMax(tickLengthIn, subTickLengthIn) + tickLabelPadding);
6327 int selLabelSize = labelBounds.height();
6328 int selLabelOffset =
6329 qMax(tickLengthOut, subTickLengthOut) +
6331 ? tickLabelPadding + selTickLabelSize
6335 mAxisSelectionBox.setCoords(
origin.x() - selAxisOutSize, axisRect.top(),
6336 origin.x() + selAxisInSize,
6338 mTickLabelsSelectionBox.setCoords(
6339 origin.x() - selTickLabelOffset - selTickLabelSize,
6340 axisRect.top(),
origin.x() - selTickLabelOffset,
6342 mLabelSelectionBox.setCoords(
6343 origin.x() - selLabelOffset - selLabelSize, axisRect.top(),
6344 origin.x() - selLabelOffset, axisRect.bottom());
6346 mAxisSelectionBox.setCoords(
origin.x() - selAxisInSize, axisRect.top(),
6347 origin.x() + selAxisOutSize,
6349 mTickLabelsSelectionBox.setCoords(
6350 origin.x() + selTickLabelOffset + selTickLabelSize,
6351 axisRect.top(),
origin.x() + selTickLabelOffset,
6353 mLabelSelectionBox.setCoords(
6354 origin.x() + selLabelOffset + selLabelSize, axisRect.top(),
6355 origin.x() + selLabelOffset, axisRect.bottom());
6357 mAxisSelectionBox.setCoords(
6358 axisRect.left(),
origin.y() - selAxisOutSize, axisRect.right(),
6359 origin.y() + selAxisInSize);
6360 mTickLabelsSelectionBox.setCoords(
6362 origin.y() - selTickLabelOffset - selTickLabelSize,
6363 axisRect.right(),
origin.y() - selTickLabelOffset);
6364 mLabelSelectionBox.setCoords(
6365 axisRect.left(),
origin.y() - selLabelOffset - selLabelSize,
6366 axisRect.right(),
origin.y() - selLabelOffset);
6368 mAxisSelectionBox.setCoords(axisRect.left(),
origin.y() - selAxisInSize,
6370 origin.y() + selAxisOutSize);
6371 mTickLabelsSelectionBox.setCoords(
6373 origin.y() + selTickLabelOffset + selTickLabelSize,
6374 axisRect.right(),
origin.y() + selTickLabelOffset);
6375 mLabelSelectionBox.setCoords(
6376 axisRect.left(),
origin.y() + selLabelOffset + selLabelSize,
6377 axisRect.right(),
origin.y() + selLabelOffset);
6379 mAxisSelectionBox = mAxisSelectionBox.normalized();
6380 mTickLabelsSelectionBox = mTickLabelsSelectionBox.normalized();
6381 mLabelSelectionBox = mLabelSelectionBox.normalized();
6397 if (!tickPositions.isEmpty())
6398 result += qMax(0, qMax(tickLengthOut, subTickLengthOut));
6402 QSize tickLabelsSize(0, 0);
6403 if (!tickLabels.isEmpty()) {
6404 for (
int i = 0; i < tickLabels.size(); ++i)
6405 getMaxTickLabelSize(tickLabelFont, tickLabels.at(i),
6408 ? tickLabelsSize.height()
6409 : tickLabelsSize.width();
6410 result += tickLabelPadding;
6416 if (!label.isEmpty()) {
6417 QFontMetrics fontMetrics(labelFont);
6419 bounds = fontMetrics.boundingRect(
6421 Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, label);
6422 result += bounds.height() + labelPadding;
6435 void QCPAxisPainterPrivate::clearCache() { mLabelCache.clear(); }
6445 QByteArray QCPAxisPainterPrivate::generateLabelParameterHash()
const {
6447 result.append(QByteArray::number(tickLabelRotation));
6448 result.append(QByteArray::number((
int)tickLabelSide));
6449 result.append(QByteArray::number((
int)substituteExponent));
6450 result.append(QByteArray::number((
int)numberMultiplyCross));
6451 result.append(tickLabelColor.name().toLatin1() +
6452 QByteArray::number(tickLabelColor.alpha(), 16));
6453 result.append(tickLabelFont.toString().toLatin1());
6478 void QCPAxisPainterPrivate::placeTickLabel(
QCPPainter *painter,
6481 const QString &text,
6482 QSize *tickLabelsSize) {
6485 if (text.isEmpty())
return;
6487 QPointF labelAnchor;
6490 labelAnchor = QPointF(axisRect.left() - distanceToAxis -
offset,
6494 labelAnchor = QPointF(axisRect.right() + distanceToAxis +
offset,
6503 axisRect.bottom() + distanceToAxis +
offset);
6507 !painter->
modes().testFlag(
6510 CachedLabel *cachedLabel =
6511 mLabelCache.take(text);
6514 cachedLabel =
new CachedLabel;
6515 TickLabelData labelData = getTickLabelData(painter->font(), text);
6516 cachedLabel->offset = getTickLabelDrawOffset(labelData) +
6517 labelData.rotatedTotalBounds.topLeft();
6518 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size());
6519 cachedLabel->pixmap.fill(Qt::transparent);
6520 QCPPainter cachePainter(&cachedLabel->pixmap);
6521 cachePainter.setPen(painter->pen());
6523 &cachePainter, -labelData.rotatedTotalBounds.topLeft().x(),
6524 -labelData.rotatedTotalBounds.topLeft().y(), labelData);
6528 bool labelClippedByBorder =
false;
6531 labelClippedByBorder =
6532 labelAnchor.x() + cachedLabel->offset.x() +
6533 cachedLabel->pixmap.width() >
6534 viewportRect.right() ||
6535 labelAnchor.x() + cachedLabel->offset.x() <
6536 viewportRect.left();
6538 labelClippedByBorder =
6539 labelAnchor.y() + cachedLabel->offset.y() +
6540 cachedLabel->pixmap.height() >
6541 viewportRect.bottom() ||
6542 labelAnchor.y() + cachedLabel->offset.y() <
6545 if (!labelClippedByBorder) {
6546 painter->drawPixmap(labelAnchor + cachedLabel->offset,
6547 cachedLabel->pixmap);
6548 finalSize = cachedLabel->pixmap.size();
6550 mLabelCache.insert(text,
6555 TickLabelData labelData = getTickLabelData(painter->font(), text);
6556 QPointF finalPosition = labelAnchor + getTickLabelDrawOffset(labelData);
6559 bool labelClippedByBorder =
false;
6562 labelClippedByBorder =
6564 (labelData.rotatedTotalBounds.width() +
6565 labelData.rotatedTotalBounds.left()) >
6566 viewportRect.right() ||
6568 labelData.rotatedTotalBounds.left() <
6569 viewportRect.left();
6571 labelClippedByBorder =
6573 (labelData.rotatedTotalBounds.height() +
6574 labelData.rotatedTotalBounds.top()) >
6575 viewportRect.bottom() ||
6576 finalPosition.y() + labelData.rotatedTotalBounds.top() <
6579 if (!labelClippedByBorder) {
6580 drawTickLabel(painter, finalPosition.x(), finalPosition.y(),
6582 finalSize = labelData.rotatedTotalBounds.size();
6587 if (finalSize.width() > tickLabelsSize->width())
6588 tickLabelsSize->setWidth(finalSize.width());
6589 if (finalSize.height() > tickLabelsSize->height())
6590 tickLabelsSize->setHeight(finalSize.height());
6603 void QCPAxisPainterPrivate::drawTickLabel(
6607 const TickLabelData &labelData)
const {
6609 QTransform oldTransform = painter->transform();
6610 QFont oldFont = painter->font();
6613 painter->translate(
x,
y);
6614 if (!qFuzzyIsNull(tickLabelRotation)) painter->rotate(tickLabelRotation);
6617 if (!labelData.expPart
6620 painter->setFont(labelData.baseFont);
6621 painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.basePart);
6622 painter->setFont(labelData.expFont);
6623 painter->drawText(labelData.baseBounds.width() + 1, 0,
6624 labelData.expBounds.width(),
6625 labelData.expBounds.height(), Qt::TextDontClip,
6628 painter->setFont(labelData.baseFont);
6629 painter->drawText(0, 0, labelData.totalBounds.width(),
6630 labelData.totalBounds.height(),
6631 Qt::TextDontClip | Qt::AlignHCenter,
6632 labelData.basePart);
6636 painter->setTransform(oldTransform);
6637 painter->setFont(oldFont);
6649 QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(
6650 const QFont &font,
const QString &text)
const {
6654 bool useBeautifulPowers =
false;
6656 if (substituteExponent) {
6657 ePos = text.indexOf(QLatin1Char(
'e'));
6658 if (ePos > -1) useBeautifulPowers =
true;
6664 if (
result.baseFont.pointSizeF() >
6667 result.baseFont.setPointSizeF(
6668 result.baseFont.pointSizeF() +
6672 if (useBeautifulPowers) {
6675 result.basePart = text.left(ePos);
6678 if (abbreviateDecimalPowers &&
result.basePart == QLatin1String(
"1"))
6679 result.basePart = QLatin1String(
"10");
6681 result.basePart += (numberMultiplyCross ? QString(QChar(215))
6682 : QString(QChar(183))) +
6683 QLatin1String(
"10");
6684 result.expPart = text.mid(ePos + 1);
6686 while (
result.expPart.length() > 2 &&
6690 result.expPart.remove(1, 1);
6691 if (!
result.expPart.isEmpty() &&
6692 result.expPart.at(0) == QLatin1Char(
'+'))
6693 result.expPart.remove(0, 1);
6696 if (
result.expFont.pointSize() > 0)
6697 result.expFont.setPointSize(
result.expFont.pointSize() * 0.75);
6699 result.expFont.setPixelSize(
result.expFont.pixelSize() * 0.75);
6702 .boundingRect(0, 0, 0, 0, Qt::TextDontClip,
6705 .boundingRect(0, 0, 0, 0, Qt::TextDontClip,
6708 0, 0,
result.expBounds.width() + 2,
6716 QFontMetrics(
result.baseFont)
6717 .boundingRect(0, 0, 0, 0,
6718 Qt::TextDontClip | Qt::AlignHCenter,
6721 result.totalBounds.moveTopLeft(QPoint(
6728 if (!qFuzzyIsNull(tickLabelRotation)) {
6729 QTransform transform;
6730 transform.rotate(tickLabelRotation);
6731 result.rotatedTotalBounds =
6732 transform.mapRect(
result.rotatedTotalBounds);
6749 QPointF QCPAxisPainterPrivate::getTickLabelDrawOffset(
6750 const TickLabelData &labelData)
const {
6762 bool doRotation = !qFuzzyIsNull(tickLabelRotation);
6764 qFuzzyCompare(qAbs(tickLabelRotation),
6767 double radians = tickLabelRotation / 180.0 *
M_PI;
6775 if (tickLabelRotation > 0) {
6776 x = -qCos(radians) * labelData.totalBounds.width();
6777 y = flip ? -labelData.totalBounds.width() / 2.0
6778 : -qSin(radians) * labelData.totalBounds.width() -
6780 labelData.totalBounds.height() /
6783 x = -qCos(-radians) * labelData.totalBounds.width() -
6784 qSin(-radians) * labelData.totalBounds.height();
6785 y = flip ? +labelData.totalBounds.width() / 2.0
6786 : +qSin(-radians) * labelData.totalBounds.width() -
6788 labelData.totalBounds.height() /
6792 x = -labelData.totalBounds.width();
6793 y = -labelData.totalBounds.height() / 2.0;
6802 if (tickLabelRotation > 0) {
6803 x = +qSin(radians) * labelData.totalBounds.height();
6804 y = flip ? -labelData.totalBounds.width() / 2.0
6805 : -qCos(radians) * labelData.totalBounds.height() /
6809 y = flip ? +labelData.totalBounds.width() / 2.0
6810 : -qCos(-radians) * labelData.totalBounds.height() /
6815 y = -labelData.totalBounds.height() / 2.0;
6824 if (tickLabelRotation > 0) {
6825 x = -qCos(radians) * labelData.totalBounds.width() +
6826 qSin(radians) * labelData.totalBounds.height() / 2.0;
6827 y = -qSin(radians) * labelData.totalBounds.width() -
6828 qCos(radians) * labelData.totalBounds.height();
6830 x = -qSin(-radians) * labelData.totalBounds.height() / 2.0;
6831 y = -qCos(-radians) * labelData.totalBounds.height();
6834 x = -labelData.totalBounds.width() / 2.0;
6835 y = -labelData.totalBounds.height();
6844 if (tickLabelRotation > 0) {
6845 x = +qSin(radians) * labelData.totalBounds.height() / 2.0;
6848 x = -qCos(-radians) * labelData.totalBounds.width() -
6849 qSin(-radians) * labelData.totalBounds.height() / 2.0;
6850 y = +qSin(-radians) * labelData.totalBounds.width();
6853 x = -labelData.totalBounds.width() / 2.0;
6858 return QPointF(
x,
y);
6869 void QCPAxisPainterPrivate::getMaxTickLabelSize(
const QFont &font,
6870 const QString &text,
6871 QSize *tickLabelsSize)
const {
6876 mLabelCache.contains(
6879 const CachedLabel *cachedLabel = mLabelCache.object(text);
6880 finalSize = cachedLabel->pixmap.size();
6883 TickLabelData labelData = getTickLabelData(font, text);
6884 finalSize = labelData.rotatedTotalBounds.size();
6888 if (finalSize.width() > tickLabelsSize->width())
6889 tickLabelsSize->setWidth(finalSize.width());
6890 if (finalSize.height() > tickLabelsSize->height())
6891 tickLabelsSize->setHeight(finalSize.height());
7065 :
QCPLayerable(keyAxis->parentPlot(), QString(), keyAxis->axisRect()),
7067 mAntialiasedFill(true),
7068 mAntialiasedScatters(true),
7069 mAntialiasedErrorBars(false),
7071 mSelectedPen(Qt::
black),
7072 mBrush(Qt::NoBrush),
7073 mSelectedBrush(Qt::NoBrush),
7075 mValueAxis(valueAxis),
7079 qDebug() << Q_FUNC_INFO
7080 <<
"Parent plot of keyAxis is not the same as that of "
7083 qDebug() << Q_FUNC_INFO
7084 <<
"keyAxis and valueAxis must be orthogonal to each other.";
7269 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
7287 double center = (newRange.
lower + newRange.
upper) *
7317 qDebug() << Q_FUNC_INFO <<
"invalid value axis";
7335 double center = (newRange.
lower + newRange.
upper) *
7402 return mKeyAxis.data()->axisRect()->rect() &
7431 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
7450 double value)
const {
7454 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
7480 double &value)
const {
7484 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
7504 double &value)
const {
7609 const QPointF &point)
const {
7615 double vLengthSqr = v.lengthSquared();
7616 if (!qFuzzyIsNull(vLengthSqr)) {
7617 double mu = QVector2D::dotProduct(p -
a, v) / vLengthSqr;
7619 return (
a - p).lengthSquared();
7621 return (b - p).lengthSquared();
7623 return ((
a + mu * v) - p).lengthSquared();
7625 return (
a - p).lengthSquared();
7631 const QVariant &details,
7632 bool *selectionStateChanged) {
7638 if (selectionStateChanged)
7639 *selectionStateChanged =
mSelected != selBefore;
7648 if (selectionStateChanged)
7649 *selectionStateChanged =
mSelected != selBefore;
7705 mParentPlot(parentPlot),
7706 mParentItem(parentItem),
7707 mAnchorId(anchorId) {}
7736 qDebug() << Q_FUNC_INFO <<
"no valid anchor id set:" <<
mAnchorId;
7740 qDebug() << Q_FUNC_INFO <<
"no parent item set";
7757 qDebug() << Q_FUNC_INFO <<
"provided pos is child already"
7758 <<
reinterpret_cast<quintptr
>(pos);
7769 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child"
7770 <<
reinterpret_cast<quintptr
>(pos);
7785 qDebug() << Q_FUNC_INFO <<
"provided pos is child already"
7786 <<
reinterpret_cast<quintptr
>(pos);
7797 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child"
7798 <<
reinterpret_cast<quintptr
>(pos);
7881 mPositionTypeX(ptAbsolute),
7882 mPositionTypeY(ptAbsolute),
7886 mParentAnchorY(0) {}
7960 bool retainPixelPosition =
true;
7963 retainPixelPosition =
false;
7966 retainPixelPosition =
false;
7969 if (retainPixelPosition) pixel =
pixelPoint();
7990 bool retainPixelPosition =
true;
7993 retainPixelPosition =
false;
7996 retainPixelPosition =
false;
7999 if (retainPixelPosition) pixel =
pixelPoint();
8031 bool keepPixelPosition) {
8034 return successX && successY;
8046 bool keepPixelPosition) {
8049 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor"
8055 while (currentParent) {
8060 if (currentParentPos ==
this) {
8061 qDebug() << Q_FUNC_INFO
8062 <<
"can't create recursive parent-child-relationship"
8066 currentParent = currentParentPos->parentAnchorX();
8073 qDebug() << Q_FUNC_INFO
8074 <<
"can't set parent to be an anchor which itself "
8075 "depends on this position"
8089 if (keepPixelPosition) pixelP =
pixelPoint();
8096 if (keepPixelPosition)
8112 bool keepPixelPosition) {
8115 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor"
8121 while (currentParent) {
8126 if (currentParentPos ==
this) {
8127 qDebug() << Q_FUNC_INFO
8128 <<
"can't create recursive parent-child-relationship"
8132 currentParent = currentParentPos->parentAnchorY();
8139 qDebug() << Q_FUNC_INFO
8140 <<
"can't set parent to be an anchor which itself "
8141 "depends on this position"
8155 if (keepPixelPosition) pixelP =
pixelPoint();
8162 if (keepPixelPosition)
8236 qDebug() << Q_FUNC_INFO
8237 <<
"Item position type x is ptAxisRectRatio, but no "
8238 "axis rect was defined";
8245 mValueAxis.data()->orientation() == Qt::Horizontal)
8248 qDebug() << Q_FUNC_INFO
8249 <<
"Item position type x is ptPlotCoords, but no axes "
8278 qDebug() << Q_FUNC_INFO
8279 <<
"Item position type y is ptAxisRectRatio, but no "
8280 "axis rect was defined";
8287 mValueAxis.data()->orientation() == Qt::Vertical)
8290 qDebug() << Q_FUNC_INFO
8291 <<
"Item position type y is ptPlotCoords, but no axes "
8355 qDebug() << Q_FUNC_INFO
8356 <<
"Item position type x is ptAxisRectRatio, but no "
8357 "axis rect was defined";
8364 mValueAxis.data()->orientation() == Qt::Horizontal)
8367 qDebug() << Q_FUNC_INFO
8368 <<
"Item position type x is ptPlotCoords, but no axes "
8395 qDebug() << Q_FUNC_INFO
8396 <<
"Item position type y is ptAxisRectRatio, but no "
8397 "axis rect was defined";
8404 mValueAxis.data()->orientation() == Qt::Vertical)
8407 qDebug() << Q_FUNC_INFO
8408 <<
"Item position type y is ptPlotCoords, but no axes "
8608 mClipToAxisRect(false),
8611 QList<QCPAxisRect *> rects = parentPlot->
axisRects();
8612 if (rects.size() > 0) {
8613 setClipToAxisRect(
true);
8614 setClipAxisRect(rects.first());
8705 for (
int i = 0; i <
mPositions.size(); ++i) {
8708 qDebug() << Q_FUNC_INFO <<
"position with name not found:" <<
name;
8723 for (
int i = 0; i <
mAnchors.size(); ++i) {
8726 qDebug() << Q_FUNC_INFO <<
"anchor with name not found:" <<
name;
8740 for (
int i = 0; i <
mAnchors.size(); ++i) {
8796 const QPointF &point)
const {
8802 double vLengthSqr = v.lengthSquared();
8803 if (!qFuzzyIsNull(vLengthSqr)) {
8804 double mu = QVector2D::dotProduct(p -
a, v) / vLengthSqr;
8806 return (
a - p).lengthSquared();
8808 return (b - p).lengthSquared();
8810 return ((
a + mu * v) - p).lengthSquared();
8812 return (
a - p).lengthSquared();
8833 bool filledRect)
const {
8837 QList<QLineF> lines;
8838 lines << QLineF(rect.topLeft(), rect.topRight())
8839 << QLineF(rect.bottomLeft(), rect.bottomRight())
8840 << QLineF(rect.topLeft(), rect.bottomLeft())
8841 << QLineF(rect.topRight(), rect.bottomRight());
8842 double minDistSqr = std::numeric_limits<double>::max();
8843 for (
int i = 0; i < lines.size(); ++i) {
8844 double distSqr =
distSqrToLine(lines.at(i).p1(), lines.at(i).p2(), pos);
8845 if (distSqr < minDistSqr) minDistSqr = distSqr;
8847 result = qSqrt(minDistSqr);
8851 if (rect.contains(pos))
8870 qDebug() << Q_FUNC_INFO
8871 <<
"called on item which shouldn't have any anchors (this method "
8872 "not reimplemented). anchorId"
8895 qDebug() << Q_FUNC_INFO
8896 <<
"anchor/position with name exists already:" <<
name;
8933 qDebug() << Q_FUNC_INFO
8934 <<
"anchor/position with name exists already:" <<
name;
8944 const QVariant &details,
8945 bool *selectionStateChanged) {
8951 if (selectionStateChanged)
8952 *selectionStateChanged =
mSelected != selBefore;
8961 if (selectionStateChanged)
8962 *selectionStateChanged =
mSelected != selBefore;
9318 mAutoAddPlottableToLegend(true),
9322 mSelectionTolerance(8),
9323 mNoAntialiasingOnDrag(false),
9324 mBackgroundBrush(Qt::
white, Qt::SolidPattern),
9325 mBackgroundScaled(true),
9326 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
9329 mMultiSelectModifier(Qt::ControlModifier),
9330 mPaintBuffer(
size()),
9331 mMouseEventElement(0),
9332 mReplotting(false) {
9333 setAttribute(Qt::WA_NoMousePropagation);
9334 setAttribute(Qt::WA_OpaquePaintEvent);
9335 setMouseTracking(
true);
9336 QLocale currentLocale = locale();
9337 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
9338 setLocale(currentLocale);
9341 mLayers.append(
new QCPLayer(
this, QLatin1String(
"background")));
9342 mLayers.append(
new QCPLayer(
this, QLatin1String(
"grid")));
9343 mLayers.append(
new QCPLayer(
this, QLatin1String(
"main")));
9344 mLayers.append(
new QCPLayer(
this, QLatin1String(
"axes")));
9345 mLayers.append(
new QCPLayer(
this, QLatin1String(
"legend")));
9346 updateLayerIndices();
9347 setCurrentLayer(QLatin1String(
"main"));
9352 mPlotLayout->setParent(
this);
9355 mPlotLayout->setLayer(QLatin1String(
"main"));
9357 mPlotLayout->addElement(0, 0, defaultAxisRect);
9365 Qt::AlignRight | Qt::AlignTop);
9368 defaultAxisRect->
setLayer(QLatin1String(
"background"));
9369 xAxis->setLayer(QLatin1String(
"axes"));
9370 yAxis->setLayer(QLatin1String(
"axes"));
9371 xAxis2->setLayer(QLatin1String(
"axes"));
9372 yAxis2->setLayer(QLatin1String(
"axes"));
9373 xAxis->grid()->setLayer(QLatin1String(
"grid"));
9374 yAxis->grid()->setLayer(QLatin1String(
"grid"));
9375 xAxis2->grid()->setLayer(QLatin1String(
"grid"));
9376 yAxis2->grid()->setLayer(QLatin1String(
"grid"));
9377 legend->setLayer(QLatin1String(
"legend"));
9420 const QCP::AntialiasedElements &antialiasedElements) {
9470 const QCP::AntialiasedElements ¬AntialiasedElements) {
9728 Qt::AspectRatioMode mode) {
9773 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9805 qDebug() << Q_FUNC_INFO
9806 <<
"plottable already added to this QCustomPlot:"
9807 <<
reinterpret_cast<quintptr
>(
plottable);
9811 qDebug() << Q_FUNC_INFO
9812 <<
"plottable not created with this QCustomPlot as parent:"
9813 <<
reinterpret_cast<quintptr
>(
plottable);
9840 qDebug() << Q_FUNC_INFO <<
"plottable not in list:"
9841 <<
reinterpret_cast<quintptr
>(
plottable);
9864 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9901 QList<QCPAbstractPlottable *>
result;
9922 bool onlySelectable)
const {
9924 double resultDistance =
9930 if (onlySelectable &&
9939 .contains(pos.toPoint()))
9944 if (currentDistance >= 0 && currentDistance < resultDistance) {
9946 resultDistance = currentDistance;
9951 return resultPlottable;
9972 if (index >= 0 && index <
mGraphs.size()) {
9975 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
10008 if (!keyAxis) keyAxis =
xAxis;
10009 if (!valueAxis) valueAxis =
yAxis;
10010 if (!keyAxis || !valueAxis) {
10011 qDebug() << Q_FUNC_INFO
10012 <<
"can't use default QCustomPlot xAxis or yAxis, because at "
10013 "least one is invalid (has been deleted)";
10017 qDebug() << Q_FUNC_INFO
10018 <<
"passed keyAxis or valueAxis doesn't have this QCustomPlot "
10025 newGraph->
setName(QLatin1String(
"Graph ") +
10026 QString::number(
mGraphs.size()));
10053 if (index >= 0 && index <
mGraphs.size())
10090 QList<QCPGraph *>
result;
10106 if (index >= 0 && index <
mItems.size()) {
10107 return mItems.at(index);
10109 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
10122 if (!
mItems.isEmpty()) {
10141 qDebug() << Q_FUNC_INFO
10142 <<
"item either already in list or not created with this "
10143 "QCustomPlot as parent:"
10144 <<
reinterpret_cast<quintptr
>(
item);
10162 qDebug() << Q_FUNC_INFO
10163 <<
"item not in list:" <<
reinterpret_cast<quintptr
>(
item);
10173 if (index >= 0 && index <
mItems.size())
10176 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
10209 QList<QCPAbstractItem *>
result;
10230 bool onlySelectable)
const {
10232 double resultDistance =
10238 if (onlySelectable &&
10251 if (currentDistance >= 0 && currentDistance < resultDistance) {
10253 resultDistance = currentDistance;
10292 if (index >= 0 && index <
mLayers.size()) {
10295 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
10321 qDebug() << Q_FUNC_INFO <<
"layer with name doesn't exist:" <<
name;
10337 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:"
10338 <<
reinterpret_cast<quintptr
>(
layer);
10371 if (!otherLayer) otherLayer =
mLayers.last();
10372 if (!
mLayers.contains(otherLayer)) {
10373 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:"
10374 <<
reinterpret_cast<quintptr
>(otherLayer);
10378 qDebug() << Q_FUNC_INFO <<
"A layer exists already with the name"
10407 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:"
10408 <<
reinterpret_cast<quintptr
>(
layer);
10412 qDebug() << Q_FUNC_INFO <<
"can't remove last layer";
10419 bool isFirstLayer = removedIndex == 0;
10421 :
mLayers.at(removedIndex - 1);
10426 for (
int i = children.size() - 1; i >= 0; --i)
10427 children.at(i)->moveToLayer(targetLayer,
true);
10430 for (
int i = 0; i < children.size(); ++i)
10431 children.at(i)->moveToLayer(targetLayer,
false);
10456 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:"
10457 <<
reinterpret_cast<quintptr
>(
layer);
10460 if (!
mLayers.contains(otherLayer)) {
10461 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:"
10462 <<
reinterpret_cast<quintptr
>(otherLayer);
10494 const QList<QCPAxisRect *> rectList =
axisRects();
10495 if (index >= 0 && index < rectList.size()) {
10496 return rectList.at(index);
10498 qDebug() << Q_FUNC_INFO <<
"invalid axis rect index" << index;
10509 QList<QCPAxisRect *>
result;
10510 QStack<QCPLayoutElement *> elementStack;
10513 while (!elementStack.isEmpty()) {
10515 elementStack.pop()->
elements(
false)) {
10517 elementStack.push(element);
10518 if (
QCPAxisRect *ar = qobject_cast<QCPAxisRect *>(element))
10539 bool searchSubElements =
true;
10540 while (searchSubElements && currentElement) {
10541 searchSubElements =
false;
10543 currentElement->
elements(
false)) {
10546 currentElement = subElement;
10547 searchSubElements =
true;
10552 return currentElement;
10563 QList<QCPAxis *>
result, allAxes;
10566 foreach (
QCPAxis *axis, allAxes) {
10582 QList<QCPLegend *>
result;
10584 QStack<QCPLayoutElement *> elementStack;
10587 while (!elementStack.isEmpty()) {
10589 elementStack.pop()->
elements(
false)) {
10591 elementStack.push(subElement);
10592 if (
QCPLegend *leg = qobject_cast<QCPLegend *>(subElement)) {
10644 : Qt::transparent);
10647 if (painter.isActive()) {
10648 painter.setRenderHint(
10649 QPainter::Antialiasing);
10656 if ((refreshPriority ==
rpHint &&
10663 qDebug() << Q_FUNC_INFO
10664 <<
"Couldn't activate painter on buffer. This usually happens "
10665 "because QCustomPlot has width or height zero.";
10671 void QCustomPlot::showPointToolTip(QMouseEvent *
event) {
10674 int evtX =
event->pos().x();
10675 int evtY =
event->pos().y();
10694 double valueY = (evtY - ptop) / (
double)(pbottom - ptop) *
10695 (
double)(dbottom - dtop) +
10712 QPoint gPos = mapToGlobal(QPoint(evtX, evtY));
10713 QToolTip::showText(gPos, QString(
"%1 , %2").arg(valueX).arg(valueY));
10727 QList<QCPAxis *> allAxes;
10730 foreach (
QCPAxis *axis, allAxes) axis->
rescale(onlyVisiblePlottables);
10775 bool noCosmeticPen,
10778 const QString &pdfCreator,
10779 const QString &pdfTitle) {
10780 bool success =
false;
10781 #ifdef QT_NO_PRINTER
10783 Q_UNUSED(noCosmeticPen)
10786 Q_UNUSED(pdfCreator)
10788 qDebug() << Q_FUNC_INFO
10789 <<
"Qt was built without printer support (QT_NO_PRINTER). PDF not "
10792 int newWidth, newHeight;
10794 newWidth = this->
width();
10795 newHeight = this->
height();
10801 QPrinter printer(QPrinter::ScreenResolution);
10802 printer.setOutputFileName(fileName);
10803 printer.setOutputFormat(QPrinter::PdfFormat);
10804 printer.setColorMode(QPrinter::Color);
10805 printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator);
10806 printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName,
10810 #if QT_VERSION < QT_VERSION_CHECK(5, 3, 0)
10811 printer.setFullPage(
true);
10812 printer.setPaperSize(
viewport().
size(), QPrinter::DevicePixel);
10814 QPageLayout pageLayout;
10815 pageLayout.setMode(QPageLayout::FullPageMode);
10816 pageLayout.setOrientation(QPageLayout::Portrait);
10817 pageLayout.setMargins(QMarginsF(0, 0, 0, 0));
10818 pageLayout.setPageSize(QPageSize(
viewport().
size(), QPageSize::Point,
10819 QString(), QPageSize::ExactMatch));
10820 printer.setPageLayout(pageLayout);
10823 if (printpainter.
begin(&printer)) {
10834 draw(&printpainter);
10835 printpainter.end();
11006 return QSize(200, 200);
11017 QPainter painter(
this);
11053 qobject_cast<QCPAbstractPlottable *>(clickedLayerable))
11055 else if (
QCPAxis *ax = qobject_cast<QCPAxis *>(clickedLayerable))
11059 qobject_cast<QCPAbstractItem *>(clickedLayerable))
11061 else if (
QCPLegend *lg = qobject_cast<QCPLegend *>(clickedLayerable))
11064 qobject_cast<QCPAbstractLegendItem *>(clickedLayerable))
11066 else if (
QCPPlotTitle *pt = qobject_cast<QCPPlotTitle *>(clickedLayerable))
11103 QWidget::mousePressEvent(
event);
11119 showPointToolTip(
event);
11124 QWidget::mouseMoveEvent(
event);
11146 bool doReplot =
false;
11151 if (
event->button() == Qt::LeftButton) {
11156 bool selectionStateChanged =
false;
11163 if (layerable != clickedLayerable &&
11166 bool selChanged =
false;
11168 selectionStateChanged |= selChanged;
11173 if (clickedLayerable &&
11176 bool selChanged =
false;
11179 selectionStateChanged |= selChanged;
11181 if (selectionStateChanged) {
11190 event->pos(),
false,
11195 qobject_cast<QCPAbstractPlottable *>(clickedLayerable))
11197 else if (
QCPAxis *ax = qobject_cast<QCPAxis *>(clickedLayerable))
11200 qobject_cast<QCPAbstractItem *>(clickedLayerable))
11202 else if (
QCPLegend *lg = qobject_cast<QCPLegend *>(clickedLayerable))
11205 qobject_cast<QCPAbstractLegendItem *>(
11209 qobject_cast<QCPPlotTitle *>(clickedLayerable))
11221 QWidget::mouseReleaseEvent(
event);
11238 QWidget::wheelEvent(
event);
11263 painter->setClipRect(child->
clipRect().translated(0, -1));
11265 child->
draw(painter);
11313 Qt::SmoothTransformation);
11314 painter->drawPixmap(
11319 painter->drawPixmap(
11348 if (this->legend ==
legend) this->legend = 0;
11358 for (
int i = 0; i <
mLayers.size(); ++i)
mLayers.at(i)->mIndex = i;
11375 bool onlySelectable,
11376 QVariant *selectionDetails)
const {
11377 for (
int layerIndex =
mLayers.size() - 1; layerIndex >= 0; --layerIndex) {
11378 const QList<QCPLayerable *> layerables =
11379 mLayers.at(layerIndex)->children();
11382 for (
int i = layerables.size() - 1; i >= 0; --i) {
11383 if (!layerables.at(i)->realVisibility())
continue;
11386 layerables.at(i)->
selectTest(pos, onlySelectable, &details);
11387 if (dist >= 0 && dist < minimumDistance) {
11388 minimumDistance = dist;
11389 minimumDistanceLayerable = layerables.at(i);
11390 if (selectionDetails) *selectionDetails = details;
11394 return minimumDistanceLayerable;
11419 if (!buffer.isNull())
11420 return buffer.save(fileName,
format, quality);
11437 int newWidth, newHeight;
11439 newWidth = this->
width();
11440 newHeight = this->
height();
11445 int scaledWidth = qRound(scale * newWidth);
11446 int scaledHeight = qRound(scale * newHeight);
11448 QPixmap
result(scaledWidth, scaledHeight);
11451 : Qt::transparent);
11456 if (painter.isActive()) {
11460 if (!qFuzzyCompare(scale, 1.0)) {
11465 painter.scale(scale, scale);
11477 qDebug() << Q_FUNC_INFO <<
"Couldn't activate painter on pixmap";
11500 int newWidth, newHeight;
11502 newWidth = this->
width();
11503 newHeight = this->
height();
11509 if (painter->isActive()) {
11521 qDebug() << Q_FUNC_INFO <<
"Passed painter is not active";
11564 : mLevelCount(350),
11565 mColorInterpolation(ciRGB),
11567 mColorBufferInvalidated(true) {
11568 mColorBuffer.fill(qRgb(0, 0, 0), mLevelCount);
11569 loadPreset(preset);
11574 return ((other.
mLevelCount == this->mLevelCount) &&
11576 (other.
mPeriodic == this->mPeriodic) &&
11588 qDebug() << Q_FUNC_INFO <<
"n must be greater or equal 2 but was" << n;
11679 int dataIndexFactor,
11680 bool logarithmic) {
11683 qDebug() << Q_FUNC_INFO <<
"null pointer given as data";
11687 qDebug() << Q_FUNC_INFO <<
"null pointer given as scanLine";
11692 if (!logarithmic) {
11695 for (
int i = 0; i < n; ++i) {
11696 int index = (int)((
data[dataIndexFactor * i] - range.
lower) *
11697 posToIndexFactor) %
11703 for (
int i = 0; i < n; ++i) {
11704 int index = (
data[dataIndexFactor * i] - range.
lower) *
11716 for (
int i = 0; i < n; ++i) {
11717 int index = (int)(qLn(
data[dataIndexFactor * i] / range.
lower) /
11725 for (
int i = 0; i < n; ++i) {
11726 int index = qLn(
data[dataIndexFactor * i] / range.
lower) /
11750 bool logarithmic) {
11899 result.clearColorStops();
11900 for (QMap<double, QColor>::const_iterator it =
mColorStops.constBegin();
11902 result.setColorStopAt(1.0 - it.key(), it.value());
11915 double indexToPosFactor = 1.0 / (double)(
mLevelCount - 1);
11917 double position = i * indexToPosFactor;
11918 QMap<double, QColor>::const_iterator it =
11933 QMap<double, QColor>::const_iterator high = it;
11934 QMap<double, QColor>::const_iterator low = it - 1;
11937 (high.key() - low.key());
11941 t * high.value().red(),
11942 (1 - t) * low.value().green() +
11943 t * high.value().green(),
11944 (1 - t) * low.value().blue() +
11945 t * high.value().blue());
11949 QColor lowHsv = low.value().toHsv();
11950 QColor highHsv = high.value().toHsv();
11952 double hueDiff = highHsv.hueF() - lowHsv.hueF();
11954 hue = lowHsv.hueF() - t * (1.0 - hueDiff);
11955 else if (hueDiff < -0.5)
11956 hue = lowHsv.hueF() + t * (1.0 + hueDiff);
11958 hue = lowHsv.hueF() + t * hueDiff;
11961 else if (hue >= 1.0)
11966 (1 - t) * lowHsv.saturationF() +
11967 t * highHsv.saturationF(),
11968 (1 - t) * lowHsv.valueF() +
11969 t * highHsv.valueF())
12129 mBackgroundBrush(Qt::NoBrush),
12130 mBackgroundScaled(true),
12131 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
12133 mRangeDrag(Qt::Horizontal | Qt::Vertical),
12134 mRangeZoom(Qt::Horizontal | Qt::Vertical),
12135 mRangeZoomFactorHorz(0.85),
12136 mRangeZoomFactorVert(0.85),
12139 mInsetLayout->setParentLayerable(
this);
12140 mInsetLayout->setParent(
this);
12142 setMinimumSize(50, 50);
12143 setMinimumMargins(QMargins(15, 15, 15, 15));
12149 if (setupDefaultAxes) {
12173 QList<QCPAxis *> axesList =
axes();
12174 for (
int i = 0; i < axesList.size(); ++i)
removeAxis(axesList.at(i));
12193 QList<QCPAxis *> ax(
mAxes.value(
type));
12194 if (index >= 0 && index < ax.size()) {
12195 return ax.at(index);
12197 qDebug() << Q_FUNC_INFO <<
"Axis index out of bounds:" << index;
12211 QList<QCPAxis *>
result;
12226 QList<QCPAxis *>
result;
12227 QHashIterator<QCPAxis::AxisType, QList<QCPAxis *>> it(
mAxes);
12228 while (it.hasNext()) {
12264 qDebug() << Q_FUNC_INFO
12265 <<
"passed axis has different axis type than specified in "
12269 if (newAxis->
axisRect() !=
this) {
12270 qDebug() << Q_FUNC_INFO
12271 <<
"passed axis doesn't have this axis rect as parent "
12275 if (
axes().contains(newAxis)) {
12276 qDebug() << Q_FUNC_INFO
12277 <<
"passed axis is already owned by this axis rect";
12304 QList<QCPAxis *>
result;
12322 QHashIterator<QCPAxis::AxisType, QList<QCPAxis *>> it(
mAxes);
12323 while (it.hasNext()) {
12325 if (it.value().contains(
axis)) {
12327 if (qobject_cast<QCustomPlot *>(
12338 qDebug() << Q_FUNC_INFO
12339 <<
"Axis isn't in axis rect:" <<
reinterpret_cast<quintptr
>(
axis);
12372 QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
12432 if (connectRanges) {
12433 connect(xAxis, SIGNAL(rangeChanged(
QCPRange)), xAxis2,
12435 connect(yAxis, SIGNAL(rangeChanged(
QCPRange)), yAxis2,
12451 QList<QCPAbstractPlottable *>
result;
12471 QList<QCPGraph *>
result;
12495 QList<QCPAbstractItem *>
result;
12501 QList<QCPItemPosition *> positions =
12503 for (
int posId = 0; posId < positions.size(); ++posId) {
12504 if (positions.at(posId)->axisRect() ==
this ||
12505 positions.at(posId)->keyAxis()->axisRect() ==
this ||
12506 positions.at(posId)->valueAxis()->axisRect() ==
this) {
12528 QList<QCPAxis *> allAxes =
axes();
12529 for (
int i = 0; i < allAxes.size(); ++i)
12530 allAxes.at(i)->setupTickVectors();
12548 QList<QCPLayoutElement *>
result;
12614 Qt::AspectRatioMode mode) {
12757 double verticalFactor) {
12805 Qt::SmoothTransformation);
12806 painter->drawPixmap(
mRect.topLeft() + QPoint(0, -1),
12808 QRect(0, 0,
mRect.width(),
mRect.height()) &
12811 painter->drawPixmap(
mRect.topLeft() + QPoint(0, -1),
12813 QRect(0, 0,
mRect.width(),
mRect.height()));
12830 const QList<QCPAxis *> axesList =
mAxes.value(
type);
12831 if (axesList.isEmpty())
return;
12833 bool isFirstVisible =
12839 for (
int i = 1; i < axesList.size(); ++i) {
12840 int offset = axesList.at(i - 1)->offset() +
12841 axesList.at(i - 1)->calculateMargin();
12842 if (axesList.at(i)->visible())
12847 if (!isFirstVisible)
offset += axesList.at(i)->tickLengthIn();
12848 isFirstVisible =
false;
12850 axesList.at(i)->setOffset(
offset);
12857 qDebug() << Q_FUNC_INFO
12858 <<
"Called with side that isn't specified as auto margin";
12864 const QList<QCPAxis *> axesList =
12866 if (axesList.size() > 0)
12867 return axesList.last()->offset() + axesList.last()->calculateMargin();
12889 if (
event->buttons() & Qt::LeftButton) {
12921 rangeDragHorzAxis->pixelToCoord(
mDragStart.x()) -
12922 rangeDragHorzAxis->pixelToCoord(
event->pos().x());
12923 rangeDragHorzAxis->setRange(
12926 }
else if (rangeDragHorzAxis->mScaleType ==
12929 rangeDragHorzAxis->pixelToCoord(
mDragStart.x()) /
12930 rangeDragHorzAxis->pixelToCoord(
event->pos().x());
12931 rangeDragHorzAxis->setRange(
12941 rangeDragVertAxis->pixelToCoord(
mDragStart.y()) -
12942 rangeDragVertAxis->pixelToCoord(
event->pos().y());
12943 rangeDragVertAxis->setRange(
12946 }
else if (rangeDragVertAxis->mScaleType ==
12949 rangeDragVertAxis->pixelToCoord(
mDragStart.y()) /
12950 rangeDragVertAxis->pixelToCoord(
event->pos().y());
12951 rangeDragVertAxis->setRange(
13068 mParentLegend(parent),
13069 mFont(parent->font()),
13070 mTextColor(parent->textColor()),
13071 mSelectedFont(parent->selectedFont()),
13072 mSelectedTextColor(parent->selectedTextColor()),
13075 setLayer(QLatin1String(
"legend"));
13144 bool onlySelectable,
13145 QVariant *details)
const {
13148 if (onlySelectable &&
13153 if (
mRect.contains(pos.toPoint()))
13171 const QVariant &details,
13172 bool *selectionStateChanged) {
13179 if (selectionStateChanged)
13180 *selectionStateChanged =
mSelected != selBefore;
13190 if (selectionStateChanged)
13191 *selectionStateChanged =
mSelected != selBefore;
13280 QRectF textRect = painter->fontMetrics().boundingRect(
13281 0, 0, 0, iconSize.height(), Qt::TextDontClip,
mPlottable->
name());
13282 QRectF iconRect(
mRect.topLeft(), iconSize);
13284 qMax(textRect.height(),
13285 iconSize.height());
13290 mRect.y(), textRect.width(), textHeight, Qt::TextDontClip,
13294 painter->setClipRect(iconRect, Qt::IntersectClip);
13300 painter->setBrush(Qt::NoBrush);
13301 painter->drawRect(iconRect);
13314 QFontMetrics fontMetrics(
getFont());
13316 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(),
13320 result.setHeight(qMax(textRect.height(), iconSize.height()) +
13401 if (qobject_cast<QCustomPlot *>(
13413 bool hasSelectedItems =
false;
13414 for (
int i = 0; i <
itemCount(); ++i) {
13416 hasSelectedItems =
true;
13420 if (hasSelectedItems)
13447 for (
int i = 0; i <
itemCount(); ++i) {
13463 for (
int i = 0; i <
itemCount(); ++i) {
13540 SelectableParts newSelected = selected;
13546 newSelected.testFlag(
13549 qDebug() << Q_FUNC_INFO
13550 <<
"spItems flag can not be set, it can only be unset "
13551 "with this function";
13555 !newSelected.testFlag(
spItems))
13558 for (
int i = 0; i <
itemCount(); ++i) {
13606 for (
int i = 0; i <
itemCount(); ++i) {
13621 for (
int i = 0; i <
itemCount(); ++i) {
13632 return qobject_cast<QCPAbstractLegendItem *>(
elementAt(index));
13643 for (
int i = 0; i <
itemCount(); ++i) {
13645 qobject_cast<QCPPlottableLegendItem *>(
item(i))) {
13646 if (pli->plottable() == plottable)
return pli;
13662 for (
int i = 0; i <
itemCount(); ++i) {
13663 if (
item == this->
item(i))
return true;
13704 bool success =
remove(ali);
13739 QList<QCPAbstractLegendItem *>
result;
13740 for (
int i = 0; i <
itemCount(); ++i) {
13742 if (ali->selected())
result.append(ali);
13799 bool onlySelectable,
13800 QVariant *details)
const {
13814 const QVariant &details,
13815 bool *selectionStateChanged) {
13830 if (selectionStateChanged)
13841 if (selectionStateChanged)
13901 mFont(QFont(QLatin1String(
"sans serif"), 13 * 1.5, QFont::Bold)),
13902 mTextColor(Qt::
black),
13903 mSelectedFont(QFont(QLatin1String(
"sans serif"), 13 * 1.6, QFont::Bold)),
13904 mSelectedTextColor(Qt::
blue),
13905 mSelectable(false),
13910 parentPlot->font().pointSize() * 1.5, QFont::Bold);
13913 parentPlot->font().pointSize() * 1.6, QFont::Bold);
13926 mFont(QFont(parentPlot->font().family(),
13927 parentPlot->font().pointSize() * 1.5,
13929 mTextColor(Qt::
black),
13930 mSelectedFont(QFont(parentPlot->font().family(),
13931 parentPlot->font().pointSize() * 1.6,
13933 mSelectedTextColor(Qt::
blue),
13934 mSelectable(false),
14021 QFontMetrics metrics(
mFont);
14023 metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size();
14031 QFontMetrics metrics(
mFont);
14033 metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size();
14035 result.setWidth(QWIDGETSIZE_MAX);
14042 const QVariant &details,
14043 bool *selectionStateChanged) {
14049 if (selectionStateChanged)
14050 *selectionStateChanged =
mSelected != selBefore;
14059 if (selectionStateChanged)
14060 *selectionStateChanged =
mSelected != selBefore;
14066 bool onlySelectable,
14067 QVariant *details)
const {
14196 mDataScaleType(
QCPAxis::stLinear),
14198 mAxisRect(new QCPColorScaleAxisRectPrivate(this)) {
14212 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
14222 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14226 return mAxisRect.data()->rangeDrag().testFlag(
14236 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14240 return mAxisRect.data()->rangeZoom().testFlag(
14257 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14263 double logBaseTransfer = 10;
14264 QString labelTransfer;
14269 logBaseTransfer =
mColorAxis.data()->scaleLogBase();
14277 QList<QCPAxis::AxisType> allAxisTypes =
14278 QList<QCPAxis::AxisType>()
14372 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
14393 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14400 mAxisRect.data()->setRangeDrag(Qt::Orientation());
14412 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14419 mAxisRect.data()->setRangeZoom(Qt::Orientation());
14426 QList<QCPColorMap *>
result;
14430 if (cm->colorScale() ==
this)
result.append(cm);
14442 QList<QCPColorMap *> maps =
colorMaps();
14444 bool haveRange =
false;
14450 for (
int i = 0; i < maps.size(); ++i) {
14451 if (!maps.at(i)->realVisibility() && onlyVisibleMaps)
continue;
14453 if (maps.at(i)->colorScale() ==
this) {
14454 bool currentFoundRange =
true;
14455 mapRange = maps.at(i)->data()->dataBounds();
14457 if (mapRange.
lower <= 0 && mapRange.
upper > 0)
14459 else if (mapRange.
lower <= 0 && mapRange.
upper <= 0)
14460 currentFoundRange =
false;
14461 }
else if (sign == -1) {
14462 if (mapRange.
upper >= 0 && mapRange.
lower < 0)
14464 else if (mapRange.
upper >= 0 && mapRange.
lower >= 0)
14465 currentFoundRange =
false;
14467 if (currentFoundRange) {
14469 newRange = mapRange;
14471 newRange.
expand(mapRange);
14482 double center = (newRange.
lower + newRange.
upper) *
14505 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14551 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14560 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14569 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14578 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14601 QCPColorScaleAxisRectPrivate::QCPColorScaleAxisRectPrivate(
14603 :
QCPAxisRect(parentColorScale->parentPlot(), true),
14604 mParentColorScale(parentColorScale),
14605 mGradientImageInvalidated(true) {
14608 QList<QCPAxis::AxisType> allAxisTypes =
14615 connect(
axis(
type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)),
14616 this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts)));
14617 connect(
axis(
type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)),
14618 this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts)));
14656 if (mGradientImageInvalidated) updateGradientImage();
14658 bool mirrorHorz =
false;
14659 bool mirrorVert =
false;
14660 if (mParentColorScale->mColorAxis) {
14661 mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() &&
14664 mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() &&
14669 painter->drawImage(rect().adjusted(0, -1, 0, -1),
14670 mGradientImage.mirrored(mirrorHorz, mirrorVert));
14680 void QCPColorScaleAxisRectPrivate::updateGradientImage() {
14681 if (rect().isEmpty())
return;
14683 int n = mParentColorScale->mGradient.levelCount();
14685 QVector<double>
data(n);
14686 for (
int i = 0; i < n; ++i)
data[i] = i;
14691 mGradientImage = QImage(w, h, QImage::Format_RGB32);
14692 QVector<QRgb *> pixels;
14693 for (
int y = 0;
y < h; ++
y)
14694 pixels.append(
reinterpret_cast<QRgb *
>(mGradientImage.scanLine(
y)));
14695 mParentColorScale->mGradient.colorize(
14696 data.constData(),
QCPRange(0, n - 1), pixels.first(), n);
14697 for (
int y = 1;
y < h; ++
y)
14698 memcpy(pixels.at(
y), pixels.first(), n *
sizeof(QRgb));
14700 w = rect().
width();
14702 mGradientImage = QImage(w, h, QImage::Format_RGB32);
14703 for (
int y = 0;
y < h; ++
y) {
14704 QRgb *pixels =
reinterpret_cast<QRgb *
>(mGradientImage.scanLine(
y));
14705 const QRgb lineColor = mParentColorScale->mGradient.color(
14707 for (
int x = 0;
x < w; ++
x) pixels[
x] = lineColor;
14710 mGradientImageInvalidated =
false;
14718 void QCPColorScaleAxisRectPrivate::axisSelectionChanged(
14719 QCPAxis::SelectableParts selectedParts) {
14721 QList<QCPAxis::AxisType> allAxisTypes =
14725 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis *>(sender()))
14726 if (senderAxis->axisType() ==
type)
continue;
14744 void QCPColorScaleAxisRectPrivate::axisSelectableChanged(
14745 QCPAxis::SelectableParts selectableParts) {
14747 QList<QCPAxis::AxisType> allAxisTypes =
14751 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis *>(sender()))
14752 if (senderAxis->axisType() ==
type)
continue;
14794 valueErrorMinus(0) {}
14806 valueErrorMinus(0) {}
14884 setBrush(Qt::NoBrush);
14885 setSelectedPen(QPen(QColor(80, 80, 255), 2.5));
14886 setSelectedBrush(Qt::NoBrush);
14888 setLineStyle(lsLine);
14889 setErrorType(etNone);
14890 setErrorBarSize(6);
14891 setErrorBarSkipSymbol(
true);
14892 setChannelFillGraph(0);
14893 setAdaptiveSampling(
true);
14911 qDebug() << Q_FUNC_INFO
14912 <<
"The data pointer is already in (and owned by) this "
14914 <<
reinterpret_cast<quintptr
>(
data);
14932 const QVector<double> &value) {
14934 int n = key.size();
14935 n = qMin(n, value.size());
14937 for (
int i = 0; i < n; ++i) {
14938 newData.
key = key[i];
14939 newData.
value = value[i];
14955 const QVector<double> &value,
14956 const QVector<double> &valueError) {
14958 int n = key.size();
14959 n = qMin(n, value.size());
14960 n = qMin(n, valueError.size());
14962 for (
int i = 0; i < n; ++i) {
14963 newData.
key = key[i];
14964 newData.
value = value[i];
14981 const QVector<double> &value,
14982 const QVector<double> &valueErrorMinus,
14983 const QVector<double> &valueErrorPlus) {
14985 int n = key.size();
14986 n = qMin(n, value.size());
14987 n = qMin(n, valueErrorMinus.size());
14988 n = qMin(n, valueErrorPlus.size());
14990 for (
int i = 0; i < n; ++i) {
14991 newData.
key = key[i];
14992 newData.
value = value[i];
15010 const QVector<double> &value,
15011 const QVector<double> &keyError) {
15013 int n = key.size();
15014 n = qMin(n, value.size());
15015 n = qMin(n, keyError.size());
15017 for (
int i = 0; i < n; ++i) {
15018 newData.
key = key[i];
15019 newData.
value = value[i];
15036 const QVector<double> &value,
15037 const QVector<double> &keyErrorMinus,
15038 const QVector<double> &keyErrorPlus) {
15040 int n = key.size();
15041 n = qMin(n, value.size());
15042 n = qMin(n, keyErrorMinus.size());
15043 n = qMin(n, keyErrorPlus.size());
15045 for (
int i = 0; i < n; ++i) {
15046 newData.
key = key[i];
15047 newData.
value = value[i];
15066 const QVector<double> &value,
15067 const QVector<double> &keyError,
15068 const QVector<double> &valueError) {
15070 int n = key.size();
15071 n = qMin(n, value.size());
15072 n = qMin(n, valueError.size());
15073 n = qMin(n, keyError.size());
15075 for (
int i = 0; i < n; ++i) {
15076 newData.
key = key[i];
15077 newData.
value = value[i];
15097 const QVector<double> &value,
15098 const QVector<double> &keyErrorMinus,
15099 const QVector<double> &keyErrorPlus,
15100 const QVector<double> &valueErrorMinus,
15101 const QVector<double> &valueErrorPlus) {
15103 int n = key.size();
15104 n = qMin(n, value.size());
15105 n = qMin(n, valueErrorMinus.size());
15106 n = qMin(n, valueErrorPlus.size());
15107 n = qMin(n, keyErrorMinus.size());
15108 n = qMin(n, keyErrorPlus.size());
15110 for (
int i = 0; i < n; ++i) {
15111 newData.
key = key[i];
15112 newData.
value = value[i];
15190 if (targetGraph ==
this) {
15191 qDebug() << Q_FUNC_INFO <<
"targetGraph is this graph itself";
15197 qDebug() << Q_FUNC_INFO <<
"targetGraph not in same plot";
15282 newData.
value = value;
15296 const QVector<double> &values) {
15297 int n = qMin(keys.size(), values.size());
15299 for (
int i = 0; i < n; ++i) {
15300 newData.
key = keys[i];
15301 newData.
value = values[i];
15311 QCPDataMap::iterator it =
mData->begin();
15312 while (it !=
mData->end() && it.key() < key) it =
mData->erase(it);
15320 if (
mData->isEmpty())
return;
15321 QCPDataMap::iterator it =
mData->upperBound(key);
15322 while (it !=
mData->end()) it =
mData->erase(it);
15333 if (fromKey >= toKey ||
mData->isEmpty())
return;
15334 QCPDataMap::iterator it =
mData->upperBound(fromKey);
15335 QCPDataMap::iterator itEnd =
mData->upperBound(toKey);
15336 while (it != itEnd) it =
mData->erase(it);
15358 bool onlySelectable,
15359 QVariant *details)
const {
15363 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15367 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
15396 if (
mData->isEmpty())
return;
15400 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
15432 if (
mData->isEmpty())
return;
15436 qDebug() << Q_FUNC_INFO <<
"invalid value axis";
15461 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15464 if (
mKeyAxis.data()->range().size() <= 0 ||
mData->isEmpty())
return;
15468 QVector<QPointF> *lineData =
new QVector<QPointF>;
15469 QVector<QCPData> *scatterData = 0;
15476 #ifdef QCUSTOMPLOT_CHECK_DATA
15477 QCPDataMap::const_iterator it;
15478 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it) {
15481 it.value().keyErrorMinus) ||
15483 it.value().valueErrorPlus))
15484 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"invalid."
15485 <<
"Plottable name:" <<
name();
15504 if (scatterData)
delete scatterData;
15510 if (
mBrush.style() != Qt::NoBrush) {
15512 painter->fillRect(QRectF(rect.left(), rect.top() + rect.height() / 2.0,
15513 rect.width(), rect.height() / 3.0),
15521 rect.left(), rect.top() + rect.height() / 2.0, rect.right() + 5,
15522 rect.top() + rect.height() /
15534 scaledStyle.setPixmap(scaledStyle.pixmap().scaled(
15535 rect.size().toSize(), Qt::KeepAspectRatio,
15536 Qt::SmoothTransformation));
15537 scaledStyle.applyTo(painter,
mPen);
15538 scaledStyle.drawShape(painter, QRectF(rect).center());
15567 QVector<QCPData> *scatterData)
const {
15621 QVector<QCPData> *scatterData)
const {
15625 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15628 if (!linePixelData) {
15629 qDebug() << Q_FUNC_INFO <<
"null pointer passed as linePixelData";
15633 QVector<QCPData> lineData;
15635 linePixelData->reserve(
15639 linePixelData->resize(lineData.size());
15643 for (
int i = 0; i < lineData.size(); ++i) {
15644 (*linePixelData)[i].setX(
15650 for (
int i = 0; i < lineData.size(); ++i) {
15652 (*linePixelData)[i].setY(
15672 QVector<QCPData> *scatterData)
const {
15676 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15679 if (!linePixelData) {
15680 qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
15684 QVector<QCPData> lineData;
15686 linePixelData->reserve(
15687 lineData.size() * 2 +
15690 linePixelData->resize(lineData.size() * 2);
15696 for (
int i = 0; i < lineData.size(); ++i) {
15698 (*linePixelData)[i * 2 + 0].setX(lastValue);
15699 (*linePixelData)[i * 2 + 0].setY(key);
15701 (*linePixelData)[i * 2 + 1].setX(lastValue);
15702 (*linePixelData)[i * 2 + 1].setY(key);
15708 for (
int i = 0; i < lineData.size(); ++i) {
15710 (*linePixelData)[i * 2 + 0].setX(key);
15711 (*linePixelData)[i * 2 + 0].setY(lastValue);
15713 (*linePixelData)[i * 2 + 1].setX(key);
15714 (*linePixelData)[i * 2 + 1].setY(lastValue);
15733 QVector<QCPData> *scatterData)
const {
15737 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15740 if (!linePixelData) {
15741 qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
15745 QVector<QCPData> lineData;
15747 linePixelData->reserve(
15748 lineData.size() * 2 +
15751 linePixelData->resize(lineData.size() * 2);
15757 for (
int i = 0; i < lineData.size(); ++i) {
15759 (*linePixelData)[i * 2 + 0].setX(value);
15760 (*linePixelData)[i * 2 + 0].setY(lastKey);
15762 (*linePixelData)[i * 2 + 1].setX(value);
15763 (*linePixelData)[i * 2 + 1].setY(lastKey);
15769 for (
int i = 0; i < lineData.size(); ++i) {
15771 (*linePixelData)[i * 2 + 0].setX(lastKey);
15772 (*linePixelData)[i * 2 + 0].setY(value);
15774 (*linePixelData)[i * 2 + 1].setX(lastKey);
15775 (*linePixelData)[i * 2 + 1].setY(value);
15794 QVector<QCPData> *scatterData)
const {
15798 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15801 if (!linePixelData) {
15802 qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
15806 QVector<QCPData> lineData;
15808 linePixelData->reserve(
15809 lineData.size() * 2 +
15812 linePixelData->resize(lineData.size() * 2);
15818 (*linePixelData)[0].setX(lastValue);
15819 (*linePixelData)[0].setY(lastKey);
15820 for (
int i = 1; i < lineData.size(); ++i) {
15822 (*linePixelData)[i * 2 - 1].setX(lastValue);
15823 (*linePixelData)[i * 2 - 1].setY(key);
15826 (*linePixelData)[i * 2 + 0].setX(lastValue);
15827 (*linePixelData)[i * 2 + 0].setY(key);
15829 (*linePixelData)[lineData.size() * 2 - 1].setX(lastValue);
15830 (*linePixelData)[lineData.size() * 2 - 1].setY(lastKey);
15836 (*linePixelData)[0].setX(lastKey);
15837 (*linePixelData)[0].setY(lastValue);
15838 for (
int i = 1; i < lineData.size(); ++i) {
15840 (*linePixelData)[i * 2 - 1].setX(key);
15841 (*linePixelData)[i * 2 - 1].setY(lastValue);
15844 (*linePixelData)[i * 2 + 0].setX(key);
15845 (*linePixelData)[i * 2 + 0].setY(lastValue);
15847 (*linePixelData)[lineData.size() * 2 - 1].setX(lastKey);
15848 (*linePixelData)[lineData.size() * 2 - 1].setY(lastValue);
15865 QVector<QCPData> *scatterData)
const {
15869 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15872 if (!linePixelData) {
15873 qDebug() << Q_FUNC_INFO <<
"null pointer passed as linePixelData";
15877 QVector<QCPData> lineData;
15879 linePixelData->resize(lineData.size() *
15887 for (
int i = 0; i < lineData.size(); ++i) {
15889 (*linePixelData)[i * 2 + 0].setX(zeroPointX);
15890 (*linePixelData)[i * 2 + 0].setY(key);
15891 (*linePixelData)[i * 2 + 1].setX(
15893 (*linePixelData)[i * 2 + 1].setY(key);
15899 for (
int i = 0; i < lineData.size(); ++i) {
15901 (*linePixelData)[i * 2 + 0].setX(key);
15902 (*linePixelData)[i * 2 + 0].setY(zeroPointY);
15903 (*linePixelData)[i * 2 + 1].setX(key);
15904 (*linePixelData)[i * 2 + 1].setY(
15936 painter->
setPen(Qt::NoPen);
15938 painter->drawPolygon(QPolygonF(*lineData));
15942 painter->
setPen(Qt::NoPen);
15959 QVector<QCPData> *scatterData)
const {
15963 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
15972 for (
int i = 0; i < scatterData->size(); ++i)
15976 scatterData->at(i));
15978 for (
int i = 0; i < scatterData->size(); ++i)
15982 scatterData->at(i));
15990 for (
int i = 0; i < scatterData->size(); ++i)
15991 if (!qIsNaN(scatterData->at(i).value))
15997 for (
int i = 0; i < scatterData->size(); ++i)
15998 if (!qIsNaN(scatterData->at(i).value))
16016 QVector<QPointF> *lineData)
const {
16021 painter->setBrush(Qt::NoBrush);
16041 painter->pen().style() == Qt::SolidLine &&
16045 bool lastIsNan =
false;
16046 const int lineDataSize = lineData->size();
16047 while (i < lineDataSize &&
16048 (qIsNaN(lineData->at(i).y()) ||
16049 qIsNaN(lineData->at(i)
16053 while (i < lineDataSize) {
16054 if (!qIsNaN(lineData->at(i).y()) &&
16055 !qIsNaN(lineData->at(i)
16059 painter->
drawLine(lineData->at(i - 1), lineData->at(i));
16067 int segmentStart = 0;
16069 const int lineDataSize = lineData->size();
16070 while (i < lineDataSize) {
16071 if (qIsNaN(lineData->at(i).y()) ||
16072 qIsNaN(lineData->at(i)
16075 painter->drawPolyline(
16076 lineData->constData() + segmentStart,
16079 segmentStart = i + 1;
16084 painter->drawPolyline(lineData->constData() + segmentStart,
16085 lineDataSize - segmentStart);
16098 QVector<QPointF> *lineData)
const {
16106 painter->setBrush(Qt::NoBrush);
16107 painter->drawLines(*lineData);
16126 QVector<QCPData> *scatterData)
const {
16130 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
16134 QCPDataMap::const_iterator lower,
16138 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
return;
16142 int maxCount = std::numeric_limits<int>::max();
16146 maxCount = 2 * keyPixelSpan + 2;
16155 QCPDataMap::const_iterator it = lower;
16156 QCPDataMap::const_iterator upperEnd = upper + 1;
16157 double minValue = it.value().value;
16158 double maxValue = it.value().value;
16159 QCPDataMap::const_iterator currentIntervalFirstPoint = it;
16160 int reversedFactor =
16166 int reversedRound =
16175 double lastIntervalEndKey = currentIntervalStartKey;
16176 double keyEpsilon = qAbs(
16177 currentIntervalStartKey -
16180 1.0 * reversedFactor));
16183 bool keyEpsilonVariable =
16188 int intervalDataCount = 1;
16191 while (it != upperEnd) {
16193 currentIntervalStartKey +
16198 if (it.value().value < minValue)
16199 minValue = it.value().value;
16200 else if (it.value().value > maxValue)
16201 maxValue = it.value().value;
16202 ++intervalDataCount;
16205 if (intervalDataCount >=
16209 if (lastIntervalEndKey <
16210 currentIntervalStartKey -
16216 currentIntervalStartKey + keyEpsilon * 0.2,
16217 currentIntervalFirstPoint.value().value));
16219 currentIntervalStartKey + keyEpsilon * 0.25,
16222 currentIntervalStartKey + keyEpsilon * 0.75,
16225 currentIntervalStartKey +
16233 currentIntervalStartKey + keyEpsilon * 0.8,
16234 (it - 1).value().value));
16237 currentIntervalFirstPoint.key(),
16238 currentIntervalFirstPoint.value().value));
16239 lastIntervalEndKey = (it - 1).value().key;
16240 minValue = it.value().value;
16241 maxValue = it.value().value;
16242 currentIntervalFirstPoint = it;
16246 if (keyEpsilonVariable)
16248 qAbs(currentIntervalStartKey -
16251 currentIntervalStartKey) +
16252 1.0 * reversedFactor));
16253 intervalDataCount = 1;
16258 if (intervalDataCount >= 2)
16261 if (lastIntervalEndKey <
16262 currentIntervalStartKey -
16267 QCPData(currentIntervalStartKey + keyEpsilon * 0.2,
16268 currentIntervalFirstPoint.value().value));
16270 currentIntervalStartKey + keyEpsilon * 0.25, minValue));
16272 currentIntervalStartKey + keyEpsilon * 0.75, maxValue));
16275 QCPData(currentIntervalFirstPoint.key(),
16276 currentIntervalFirstPoint.value().value));
16282 QCPDataMap::const_iterator it = lower;
16283 QCPDataMap::const_iterator upperEnd = upper + 1;
16284 double minValue = it.value().value;
16285 double maxValue = it.value().value;
16286 QCPDataMap::const_iterator minValueIt = it;
16287 QCPDataMap::const_iterator maxValueIt = it;
16288 QCPDataMap::const_iterator currentIntervalStart = it;
16289 int reversedFactor =
16294 int reversedRound =
16302 double keyEpsilon = qAbs(
16303 currentIntervalStartKey -
16306 1.0 * reversedFactor));
16309 bool keyEpsilonVariable =
16314 int intervalDataCount = 1;
16317 while (it != upperEnd) {
16319 currentIntervalStartKey +
16324 if (it.value().value < minValue &&
16325 it.value().value > valueMinRange &&
16326 it.value().value < valueMaxRange) {
16327 minValue = it.value().value;
16329 }
else if (it.value().value > maxValue &&
16330 it.value().value > valueMinRange &&
16331 it.value().value < valueMaxRange) {
16332 maxValue = it.value().value;
16335 ++intervalDataCount;
16338 if (intervalDataCount >= 2)
16344 double valuePixelSpan =
16347 int dataModulo = qMax(
16348 1, qRound(intervalDataCount /
16353 QCPDataMap::const_iterator intervalIt =
16354 currentIntervalStart;
16356 while (intervalIt != it) {
16357 if ((c % dataModulo == 0 ||
16358 intervalIt == minValueIt ||
16359 intervalIt == maxValueIt) &&
16360 intervalIt.value().value > valueMinRange &&
16361 intervalIt.value().value < valueMaxRange)
16362 scatterData->append(intervalIt.value());
16366 }
else if (currentIntervalStart.value().value >
16368 currentIntervalStart.value().value <
16370 scatterData->append(currentIntervalStart.value());
16371 minValue = it.value().value;
16372 maxValue = it.value().value;
16373 currentIntervalStart = it;
16377 if (keyEpsilonVariable)
16379 qAbs(currentIntervalStartKey -
16382 currentIntervalStartKey) +
16383 1.0 * reversedFactor));
16384 intervalDataCount = 1;
16389 if (intervalDataCount >=
16397 int dataModulo = qMax(
16398 1, qRound(intervalDataCount /
16402 QCPDataMap::const_iterator intervalIt = currentIntervalStart;
16404 while (intervalIt != it) {
16405 if ((c % dataModulo == 0 || intervalIt == minValueIt ||
16406 intervalIt == maxValueIt) &&
16407 intervalIt.value().value > valueMinRange &&
16408 intervalIt.value().value < valueMaxRange)
16409 scatterData->append(intervalIt.value());
16413 }
else if (currentIntervalStart.value().value > valueMinRange &&
16414 currentIntervalStart.value().value < valueMaxRange)
16415 scatterData->append(currentIntervalStart.value());
16420 QVector<QCPData> *dataVector = 0;
16422 dataVector = lineData;
16423 else if (scatterData)
16424 dataVector = scatterData;
16426 QCPDataMap::const_iterator it = lower;
16427 QCPDataMap::const_iterator upperEnd = upper + 1;
16430 while (it != upperEnd) {
16431 dataVector->append(it.value());
16435 if (lineData && scatterData) *scatterData = *dataVector;
16451 if (qIsNaN(
data.value))
return;
16455 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
16461 double skipSymbolMargin =
16476 painter->
drawLine(QLineF(
x,
a,
x,
y + skipSymbolMargin));
16477 if (
y - b > skipSymbolMargin)
16478 painter->
drawLine(QLineF(
x,
y - skipSymbolMargin,
x, b));
16482 painter->
drawLine(QLineF(
x - barWidthHalf,
a,
x + barWidthHalf,
a));
16483 painter->
drawLine(QLineF(
x - barWidthHalf, b,
x + barWidthHalf, b));
16494 painter->
drawLine(QLineF(
a,
y,
x - skipSymbolMargin,
y));
16495 if (b -
x > skipSymbolMargin)
16496 painter->
drawLine(QLineF(
x + skipSymbolMargin,
y, b,
y));
16500 painter->
drawLine(QLineF(
a,
y - barWidthHalf,
a,
y + barWidthHalf));
16501 painter->
drawLine(QLineF(b,
y - barWidthHalf, b,
y + barWidthHalf));
16515 painter->
drawLine(QLineF(
a,
y,
x - skipSymbolMargin,
y));
16516 if (b -
x > skipSymbolMargin)
16517 painter->
drawLine(QLineF(
x + skipSymbolMargin,
y, b,
y));
16521 painter->
drawLine(QLineF(
a,
y - barWidthHalf,
a,
y + barWidthHalf));
16522 painter->
drawLine(QLineF(b,
y - barWidthHalf, b,
y + barWidthHalf));
16533 painter->
drawLine(QLineF(
x,
a,
x,
y + skipSymbolMargin));
16534 if (
y - b > skipSymbolMargin)
16535 painter->
drawLine(QLineF(
x,
y - skipSymbolMargin,
x, b));
16539 painter->
drawLine(QLineF(
x - barWidthHalf,
a,
x + barWidthHalf,
a));
16540 painter->
drawLine(QLineF(
x - barWidthHalf, b,
x + barWidthHalf, b));
16561 QCPDataMap::const_iterator &upper)
const {
16563 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
16566 if (
mData->isEmpty()) {
16567 lower =
mData->constEnd();
16568 upper =
mData->constEnd();
16573 QCPDataMap::const_iterator lbound =
16575 QCPDataMap::const_iterator ubound =
16578 lbound !=
mData->constBegin();
16581 ubound !=
mData->constEnd();
16584 lower = (lowoutlier
16587 upper = (highoutlier ? ubound : ubound - 1);
16603 const QCPDataMap::const_iterator &upper,
16604 int maxCount)
const {
16605 if (upper ==
mData->constEnd() && lower ==
mData->constEnd())
return 0;
16606 QCPDataMap::const_iterator it = lower;
16608 while (it != upper &&
count < maxCount) {
16633 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
16638 if (
mKeyAxis.data()->orientation() == Qt::Vertical) {
16655 lineData->remove(lineData->size() - 2, 2);
16677 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
16685 point.setY(lowerKey);
16688 point.setY(lowerKey);
16690 point.setX(lowerKey);
16693 point.setX(lowerKey);
16708 point.setY(lowerKey);
16711 point.setX(lowerKey);
16743 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
16751 point.setY(upperKey);
16754 point.setY(upperKey);
16756 point.setX(upperKey);
16759 point.setX(upperKey);
16774 point.setY(upperKey);
16777 point.setX(upperKey);
16801 const QVector<QPointF> *lineData)
const {
16807 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
16808 return QPolygonF();
16811 qDebug() << Q_FUNC_INFO <<
"channel fill target key axis invalid";
16812 return QPolygonF();
16817 return QPolygonF();
16821 if (lineData->isEmpty())
return QPolygonF();
16822 QVector<QPointF> otherData;
16824 if (otherData.isEmpty())
return QPolygonF();
16825 QVector<QPointF> thisData;
16826 thisData.reserve(lineData->size() +
16829 for (
int i = 0; i < lineData->size();
16832 thisData << lineData->at(i);
16836 QVector<QPointF> *staticData = &thisData;
16837 QVector<QPointF> *croppedData = &otherData;
16845 if (staticData->first().x() > staticData->last().x()) {
16846 int size = staticData->size();
16847 for (
int i = 0; i <
size / 2; ++i)
16848 qSwap((*staticData)[i], (*staticData)[
size - 1 - i]);
16850 if (croppedData->first().x() > croppedData->last().x()) {
16851 int size = croppedData->size();
16852 for (
int i = 0; i <
size / 2; ++i)
16853 qSwap((*croppedData)[i], (*croppedData)[
size - 1 - i]);
16856 if (staticData->first().x() <
16857 croppedData->first().x())
16858 qSwap(staticData, croppedData);
16859 int lowBound =
findIndexBelowX(croppedData, staticData->first().x());
16860 if (lowBound == -1)
return QPolygonF();
16861 croppedData->remove(0, lowBound);
16864 if (croppedData->size() < 2)
16865 return QPolygonF();
16867 if (croppedData->at(1).x() - croppedData->at(0).x() != 0)
16868 slope = (croppedData->at(1).y() - croppedData->at(0).y()) /
16869 (croppedData->at(1).x() - croppedData->at(0).x());
16872 (*croppedData)[0].setY(
16873 croppedData->at(0).y() +
16874 slope * (staticData->first().x() - croppedData->at(0).x()));
16875 (*croppedData)[0].setX(staticData->first().x());
16878 if (staticData->last().x() >
16879 croppedData->last().x())
16880 qSwap(staticData, croppedData);
16881 int highBound =
findIndexAboveX(croppedData, staticData->last().x());
16882 if (highBound == -1)
return QPolygonF();
16883 croppedData->remove(highBound + 1,
16884 croppedData->size() - (highBound + 1));
16887 if (croppedData->size() < 2)
16888 return QPolygonF();
16889 int li = croppedData->size() - 1;
16890 if (croppedData->at(li).x() - croppedData->at(li - 1).x() != 0)
16891 slope = (croppedData->at(li).y() - croppedData->at(li - 1).y()) /
16892 (croppedData->at(li).x() - croppedData->at(li - 1).x());
16895 (*croppedData)[li].setY(
16896 croppedData->at(li - 1).y() +
16897 slope * (staticData->last().x() - croppedData->at(li - 1).x()));
16898 (*croppedData)[li].setX(staticData->last().x());
16907 if (staticData->first().y() < staticData->last().y()) {
16908 int size = staticData->size();
16909 for (
int i = 0; i <
size / 2; ++i)
16910 qSwap((*staticData)[i], (*staticData)[
size - 1 - i]);
16912 if (croppedData->first().y() < croppedData->last().y()) {
16913 int size = croppedData->size();
16914 for (
int i = 0; i <
size / 2; ++i)
16915 qSwap((*croppedData)[i], (*croppedData)[
size - 1 - i]);
16918 if (staticData->first().y() >
16919 croppedData->first().y())
16920 qSwap(staticData, croppedData);
16921 int lowBound =
findIndexAboveY(croppedData, staticData->first().y());
16922 if (lowBound == -1)
return QPolygonF();
16923 croppedData->remove(0, lowBound);
16926 if (croppedData->size() < 2)
16927 return QPolygonF();
16929 if (croppedData->at(1).y() - croppedData->at(0).y() !=
16931 slope = (croppedData->at(1).x() - croppedData->at(0).x()) /
16932 (croppedData->at(1).y() - croppedData->at(0).y());
16935 (*croppedData)[0].setX(
16936 croppedData->at(0).x() +
16937 slope * (staticData->first().y() - croppedData->at(0).y()));
16938 (*croppedData)[0].setY(staticData->first().y());
16941 if (staticData->last().y() <
16942 croppedData->last().y())
16943 qSwap(staticData, croppedData);
16944 int highBound =
findIndexBelowY(croppedData, staticData->last().y());
16945 if (highBound == -1)
return QPolygonF();
16946 croppedData->remove(highBound + 1,
16947 croppedData->size() - (highBound + 1));
16950 if (croppedData->size() < 2)
16951 return QPolygonF();
16952 int li = croppedData->size() - 1;
16953 if (croppedData->at(li).y() - croppedData->at(li - 1).y() !=
16955 slope = (croppedData->at(li).x() - croppedData->at(li - 1).x()) /
16956 (croppedData->at(li).y() - croppedData->at(li - 1).y());
16959 (*croppedData)[li].setX(
16960 croppedData->at(li - 1).x() +
16961 slope * (staticData->last().y() - croppedData->at(li - 1).y()));
16962 (*croppedData)[li].setY(staticData->last().y());
16966 for (
int i = otherData.size() - 1; i >= 0;
16968 thisData << otherData.at(i);
16969 return QPolygonF(thisData);
16981 for (
int i =
data->size() - 1; i >= 0; --i) {
16982 if (
data->at(i).x() <
x) {
16983 if (i < data->
size() - 1)
16986 return data->size() - 1;
17001 for (
int i = 0; i <
data->size(); ++i) {
17002 if (
data->at(i).x() >
x) {
17021 for (
int i = 0; i <
data->size(); ++i) {
17022 if (
data->at(i).y() <
y) {
17043 if (
mData->isEmpty())
return -1.0;
17049 QVector<QCPData> scatterData;
17051 if (scatterData.size() > 0) {
17052 double minDistSqr = std::numeric_limits<double>::max();
17053 for (
int i = 0; i < scatterData.size(); ++i) {
17054 double currentDistSqr =
17056 scatterData.at(i).value) -
17059 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
17061 return qSqrt(minDistSqr);
17066 QVector<QPointF> lineData;
17069 if (lineData.size() >
17072 double minDistSqr = std::numeric_limits<double>::max();
17076 for (
int i = 0; i < lineData.size() - 1;
17080 lineData.at(i), lineData.at(i + 1), pixelPoint);
17081 if (currentDistSqr < minDistSqr)
17082 minDistSqr = currentDistSqr;
17086 for (
int i = 0; i < lineData.size() - 1; ++i) {
17088 lineData.at(i), lineData.at(i + 1), pixelPoint);
17089 if (currentDistSqr < minDistSqr)
17090 minDistSqr = currentDistSqr;
17093 return qSqrt(minDistSqr);
17094 }
else if (lineData.size() > 0)
17097 return QVector2D(lineData.at(0) - pixelPoint).length();
17112 for (
int i =
data->size() - 1; i >= 0; --i) {
17113 if (
data->at(i).y() >
y) {
17114 if (i < data->
size() - 1)
17117 return data->size() - 1;
17129 return getKeyRange(foundRange, inSignDomain,
true);
17150 bool includeErrors)
const {
17152 bool haveLower =
false;
17153 bool haveUpper =
false;
17155 double current, currentErrorMinus, currentErrorPlus;
17157 if (inSignDomain ==
sdBoth)
17159 QCPDataMap::const_iterator it =
mData->constBegin();
17160 while (it !=
mData->constEnd()) {
17161 if (!qIsNaN(it.value().value)) {
17162 current = it.value().key;
17163 currentErrorMinus =
17164 (includeErrors ? it.value().keyErrorMinus : 0);
17166 (includeErrors ? it.value().keyErrorPlus : 0);
17167 if (current - currentErrorMinus < range.
lower || !haveLower) {
17168 range.
lower = current - currentErrorMinus;
17171 if (current + currentErrorPlus > range.
upper || !haveUpper) {
17172 range.
upper = current + currentErrorPlus;
17178 }
else if (inSignDomain ==
17181 QCPDataMap::const_iterator it =
mData->constBegin();
17182 while (it !=
mData->constEnd()) {
17183 if (!qIsNaN(it.value().value)) {
17184 current = it.value().key;
17185 currentErrorMinus =
17186 (includeErrors ? it.value().keyErrorMinus : 0);
17188 (includeErrors ? it.value().keyErrorPlus : 0);
17189 if ((current - currentErrorMinus < range.
lower || !haveLower) &&
17190 current - currentErrorMinus < 0) {
17191 range.
lower = current - currentErrorMinus;
17194 if ((current + currentErrorPlus > range.
upper || !haveUpper) &&
17195 current + currentErrorPlus < 0) {
17196 range.
upper = current + currentErrorPlus;
17203 if ((current < range.
lower || !haveLower) && current < 0) {
17204 range.
lower = current;
17207 if ((current > range.
upper || !haveUpper) && current < 0) {
17208 range.
upper = current;
17215 }
else if (inSignDomain ==
17218 QCPDataMap::const_iterator it =
mData->constBegin();
17219 while (it !=
mData->constEnd()) {
17220 if (!qIsNaN(it.value().value)) {
17221 current = it.value().key;
17222 currentErrorMinus =
17223 (includeErrors ? it.value().keyErrorMinus : 0);
17225 (includeErrors ? it.value().keyErrorPlus : 0);
17226 if ((current - currentErrorMinus < range.
lower || !haveLower) &&
17227 current - currentErrorMinus > 0) {
17228 range.
lower = current - currentErrorMinus;
17231 if ((current + currentErrorPlus > range.
upper || !haveUpper) &&
17232 current + currentErrorPlus > 0) {
17233 range.
upper = current + currentErrorPlus;
17240 if ((current < range.
lower || !haveLower) && current > 0) {
17241 range.
lower = current;
17244 if ((current > range.
upper || !haveUpper) && current > 0) {
17245 range.
upper = current;
17254 foundRange = haveLower && haveUpper;
17267 bool includeErrors)
const {
17269 bool haveLower =
false;
17270 bool haveUpper =
false;
17272 double current, currentErrorMinus, currentErrorPlus;
17274 if (inSignDomain ==
sdBoth)
17276 QCPDataMap::const_iterator it =
mData->constBegin();
17277 while (it !=
mData->constEnd()) {
17278 current = it.value().value;
17279 if (!qIsNaN(current)) {
17280 currentErrorMinus =
17281 (includeErrors ? it.value().valueErrorMinus : 0);
17283 (includeErrors ? it.value().valueErrorPlus : 0);
17284 if (current - currentErrorMinus < range.
lower || !haveLower) {
17285 range.
lower = current - currentErrorMinus;
17288 if (current + currentErrorPlus > range.
upper || !haveUpper) {
17289 range.
upper = current + currentErrorPlus;
17295 }
else if (inSignDomain ==
17298 QCPDataMap::const_iterator it =
mData->constBegin();
17299 while (it !=
mData->constEnd()) {
17300 current = it.value().value;
17301 if (!qIsNaN(current)) {
17302 currentErrorMinus =
17303 (includeErrors ? it.value().valueErrorMinus : 0);
17305 (includeErrors ? it.value().valueErrorPlus : 0);
17306 if ((current - currentErrorMinus < range.
lower || !haveLower) &&
17307 current - currentErrorMinus < 0) {
17308 range.
lower = current - currentErrorMinus;
17311 if ((current + currentErrorPlus > range.
upper || !haveUpper) &&
17312 current + currentErrorPlus < 0) {
17313 range.
upper = current + currentErrorPlus;
17320 if ((current < range.
lower || !haveLower) && current < 0) {
17321 range.
lower = current;
17324 if ((current > range.
upper || !haveUpper) && current < 0) {
17325 range.
upper = current;
17332 }
else if (inSignDomain ==
17335 QCPDataMap::const_iterator it =
mData->constBegin();
17336 while (it !=
mData->constEnd()) {
17337 current = it.value().value;
17338 if (!qIsNaN(current)) {
17339 currentErrorMinus =
17340 (includeErrors ? it.value().valueErrorMinus : 0);
17342 (includeErrors ? it.value().valueErrorPlus : 0);
17343 if ((current - currentErrorMinus < range.
lower || !haveLower) &&
17344 current - currentErrorMinus > 0) {
17345 range.
lower = current - currentErrorMinus;
17348 if ((current + currentErrorPlus > range.
upper || !haveUpper) &&
17349 current + currentErrorPlus > 0) {
17350 range.
upper = current + currentErrorPlus;
17357 if ((current < range.
lower || !haveLower) && current > 0) {
17358 range.
lower = current;
17361 if ((current > range.
upper || !haveUpper) && current > 0) {
17362 range.
upper = current;
17371 foundRange = haveLower && haveUpper;
17402 : t(t), key(key), value(value) {}
17455 mPen.setStyle(Qt::SolidLine);
17457 mBrush.setStyle(Qt::NoBrush);
17461 QColor(80, 80, 255));
17480 qDebug() << Q_FUNC_INFO
17481 <<
"The data pointer is already in (and owned by) this "
17483 <<
reinterpret_cast<quintptr
>(
data);
17501 const QVector<double> &key,
17502 const QVector<double> &value) {
17505 n = qMin(n, key.size());
17506 n = qMin(n, value.size());
17508 for (
int i = 0; i < n; ++i) {
17510 newData.
key = key[i];
17511 newData.
value = value[i];
17523 const QVector<double> &value) {
17525 int n = key.size();
17526 n = qMin(n, value.size());
17528 for (
int i = 0; i < n; ++i) {
17531 newData.
key = key[i];
17532 newData.
value = value[i];
17582 newData.
value = value;
17596 if (!
mData->isEmpty())
17597 newData.
t = (
mData->constEnd() - 1).key() + 1;
17601 newData.
value = value;
17610 const QVector<double> &keys,
17611 const QVector<double> &values) {
17613 n = qMin(n, keys.size());
17614 n = qMin(n, values.size());
17616 for (
int i = 0; i < n; ++i) {
17618 newData.
key = keys[i];
17619 newData.
value = values[i];
17629 QCPCurveDataMap::iterator it =
mData->begin();
17630 while (it !=
mData->end() && it.key() < t) it =
mData->erase(it);
17638 if (
mData->isEmpty())
return;
17639 QCPCurveDataMap::iterator it =
mData->upperBound(t);
17640 while (it !=
mData->end()) it =
mData->erase(it);
17651 if (fromt >= tot ||
mData->isEmpty())
return;
17652 QCPCurveDataMap::iterator it =
mData->upperBound(fromt);
17653 QCPCurveDataMap::iterator itEnd =
mData->upperBound(tot);
17654 while (it != itEnd) it =
mData->erase(it);
17676 bool onlySelectable,
17677 QVariant *details)
const {
17681 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
17685 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
17693 if (
mData->isEmpty())
return;
17696 QVector<QPointF> *lineData =
new QVector<QPointF>;
17702 #ifdef QCUSTOMPLOT_CHECK_DATA
17703 QCPCurveDataMap::const_iterator it;
17704 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it) {
17707 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"invalid."
17708 <<
"Plottable name:" <<
name();
17713 if (
mainBrush().style() != Qt::NoBrush &&
17716 painter->
setPen(Qt::NoPen);
17718 painter->drawPolygon(QPolygonF(*lineData));
17726 painter->setBrush(Qt::NoBrush);
17730 painter->pen().style() == Qt::SolidLine &&
17734 bool lastIsNan =
false;
17735 const int lineDataSize = lineData->size();
17736 while (i < lineDataSize &&
17737 (qIsNaN(lineData->at(i).y()) ||
17738 qIsNaN(lineData->at(i)
17742 while (i < lineDataSize) {
17743 if (!qIsNaN(lineData->at(i).y()) &&
17744 !qIsNaN(lineData->at(i)
17748 painter->
drawLine(lineData->at(i - 1), lineData->at(i));
17756 int segmentStart = 0;
17758 const int lineDataSize = lineData->size();
17759 while (i < lineDataSize) {
17760 if (qIsNaN(lineData->at(i).y()) ||
17761 qIsNaN(lineData->at(i)
17764 painter->drawPolyline(
17765 lineData->constData() + segmentStart,
17768 segmentStart = i + 1;
17773 painter->drawPolyline(lineData->constData() + segmentStart,
17774 lineDataSize - segmentStart);
17788 if (
mBrush.style() != Qt::NoBrush) {
17790 painter->fillRect(QRectF(rect.left(), rect.top() + rect.height() / 2.0,
17791 rect.width(), rect.height() / 3.0),
17799 rect.left(), rect.top() + rect.height() / 2.0, rect.right() + 5,
17800 rect.top() + rect.height() /
17812 scaledStyle.setPixmap(scaledStyle.pixmap().scaled(
17813 rect.size().toSize(), Qt::KeepAspectRatio,
17814 Qt::SmoothTransformation));
17815 scaledStyle.applyTo(painter,
mPen);
17816 scaledStyle.drawShape(painter, QRectF(rect).center());
17831 const QVector<QPointF> *pointData)
const {
17835 for (
int i = 0; i < pointData->size(); ++i)
17836 if (!qIsNaN(pointData->at(i).x()) && !qIsNaN(pointData->at(i).y()))
17859 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
17864 double strokeMargin = qMax(
17866 qreal(
mainPen().widthF() * 0.75));
17894 QCPCurveDataMap::const_iterator it =
mData->constBegin();
17895 QCPCurveDataMap::const_iterator prevIt =
mData->constEnd() - 1;
17896 int prevRegion =
getRegion(prevIt.value().key, prevIt.value().value,
17897 rectLeft, rectTop, rectRight, rectBottom);
17903 while (it !=
mData->constEnd()) {
17904 currentRegion =
getRegion(it.value().key, it.value().value, rectLeft,
17905 rectTop, rectRight, rectBottom);
17906 if (currentRegion !=
17910 if (currentRegion !=
17913 QPointF crossA, crossB;
17918 currentRegion, it.value().key, it.value().value,
17919 prevIt.value().key, prevIt.value().value, rectLeft,
17920 rectTop, rectRight, rectBottom));
17925 prevRegion, currentRegion, prevIt.value().key,
17926 prevIt.value().value, it.value().key,
17927 it.value().value, rectLeft, rectTop, rectRight,
17929 }
else if (
mayTraverse(prevRegion, currentRegion) &&
17930 getTraverse(prevIt.value().key, prevIt.value().value,
17931 it.value().key, it.value().value,
17932 rectLeft, rectTop, rectRight, rectBottom,
17937 QVector<QPointF> beforeTraverseCornerPoints,
17938 afterTraverseCornerPoints;
17940 rectTop, rectRight, rectBottom,
17941 beforeTraverseCornerPoints,
17942 afterTraverseCornerPoints);
17943 if (it !=
mData->constBegin()) {
17944 *lineData << beforeTraverseCornerPoints;
17945 lineData->append(crossA);
17946 lineData->append(crossB);
17947 *lineData << afterTraverseCornerPoints;
17949 lineData->append(crossB);
17950 *lineData << afterTraverseCornerPoints;
17951 trailingPoints << beforeTraverseCornerPoints << crossA;
17958 prevRegion, currentRegion, prevIt.value().key,
17959 prevIt.value().value, it.value().key,
17960 it.value().value, rectLeft, rectTop, rectRight,
17967 mData->constBegin())
17972 prevRegion, prevIt.value().key,
17973 prevIt.value().value, it.value().key,
17974 it.value().value, rectLeft, rectTop, rectRight,
17978 prevRegion, prevIt.value().key,
17979 prevIt.value().value, it.value().key,
17980 it.value().value, rectLeft, rectTop, rectRight,
17987 if (currentRegion == 5)
17998 prevRegion = currentRegion;
18001 *lineData << trailingPoints;
18029 double rectBottom)
const {
18034 else if (
y < rectBottom)
18038 }
else if (
x > rectRight)
18042 else if (
y < rectBottom)
18050 else if (
y < rectBottom)
18082 double rectBottom)
const {
18083 double intersectKey = rectLeft;
18084 double intersectValue = rectTop;
18085 switch (otherRegion) {
18088 intersectValue = rectTop;
18089 intersectKey = otherKey + (key - otherKey) / (value - otherValue) *
18090 (intersectValue - otherValue);
18091 if (intersectKey < rectLeft ||
18092 intersectKey > rectRight)
18095 intersectKey = rectLeft;
18096 intersectValue = otherValue + (value - otherValue) /
18098 (intersectKey - otherKey);
18104 intersectKey = rectLeft;
18105 intersectValue = otherValue + (value - otherValue) /
18107 (intersectKey - otherKey);
18112 intersectValue = rectBottom;
18113 intersectKey = otherKey + (key - otherKey) / (value - otherValue) *
18114 (intersectValue - otherValue);
18115 if (intersectKey < rectLeft ||
18116 intersectKey > rectRight)
18119 intersectKey = rectLeft;
18120 intersectValue = otherValue + (value - otherValue) /
18122 (intersectKey - otherKey);
18128 intersectValue = rectTop;
18129 intersectKey = otherKey + (key - otherKey) / (value - otherValue) *
18130 (intersectValue - otherValue);
18139 intersectValue = rectBottom;
18140 intersectKey = otherKey + (key - otherKey) / (value - otherValue) *
18141 (intersectValue - otherValue);
18146 intersectValue = rectTop;
18147 intersectKey = otherKey + (key - otherKey) / (value - otherValue) *
18148 (intersectValue - otherValue);
18149 if (intersectKey < rectLeft ||
18150 intersectKey > rectRight)
18153 intersectKey = rectRight;
18154 intersectValue = otherValue + (value - otherValue) /
18156 (intersectKey - otherKey);
18162 intersectKey = rectRight;
18163 intersectValue = otherValue + (value - otherValue) /
18165 (intersectKey - otherKey);
18170 intersectValue = rectBottom;
18171 intersectKey = otherKey + (key - otherKey) / (value - otherValue) *
18172 (intersectValue - otherValue);
18173 if (intersectKey < rectLeft ||
18174 intersectKey > rectRight)
18177 intersectKey = rectRight;
18178 intersectValue = otherValue + (value - otherValue) /
18180 (intersectKey - otherKey);
18218 double rectBottom)
const {
18219 QVector<QPointF>
result;
18220 switch (prevRegion) {
18222 switch (currentRegion) {
18256 if ((value - prevValue) / (key - prevKey) *
18277 switch (currentRegion) {
18312 switch (currentRegion) {
18346 if ((value - prevValue) / (key - prevKey) *
18347 (rectRight - key) +
18367 switch (currentRegion) {
18402 switch (currentRegion) {
18423 switch (currentRegion) {
18458 switch (currentRegion) {
18492 if ((value - prevValue) / (key - prevKey) *
18493 (rectRight - key) +
18513 switch (currentRegion) {
18548 switch (currentRegion) {
18582 if ((value - prevValue) / (key - prevKey) *
18620 switch (prevRegion) {
18622 switch (currentRegion) {
18633 switch (currentRegion) {
18642 switch (currentRegion) {
18653 switch (currentRegion) {
18664 switch (currentRegion) {
18673 switch (currentRegion) {
18684 switch (currentRegion) {
18693 switch (currentRegion) {
18733 QPointF &crossB)
const {
18736 if (qFuzzyIsNull(key - prevKey))
18740 intersections.append(
18741 QPointF(key, rectBottom));
18743 intersections.append(QPointF(key, rectTop));
18744 }
else if (qFuzzyIsNull(value - prevValue))
18748 intersections.append(QPointF(
18751 intersections.append(QPointF(rectRight, value));
18755 double keyPerValue = (key - prevKey) / (value - prevValue);
18757 gamma = prevKey + (rectTop - prevValue) * keyPerValue;
18758 if (gamma >= rectLeft && gamma <= rectRight)
18759 intersections.append(QPointF(gamma, rectTop));
18761 gamma = prevKey + (rectBottom - prevValue) * keyPerValue;
18762 if (gamma >= rectLeft && gamma <= rectRight)
18763 intersections.append(QPointF(gamma, rectBottom));
18764 double valuePerKey = 1.0 / keyPerValue;
18766 gamma = prevValue + (rectLeft - prevKey) * valuePerKey;
18767 if (gamma >= rectBottom && gamma <= rectTop)
18768 intersections.append(QPointF(rectLeft, gamma));
18770 gamma = prevValue + (rectRight - prevKey) * valuePerKey;
18771 if (gamma >= rectBottom && gamma <= rectTop)
18772 intersections.append(QPointF(rectRight, gamma));
18776 if (intersections.size() > 2) {
18780 double distSqrMax = 0;
18782 for (
int i = 0; i < intersections.size() - 1; ++i) {
18783 for (
int k = i + 1; k < intersections.size(); ++k) {
18784 QPointF distPoint = intersections.at(i) - intersections.at(k);
18785 double distSqr = distPoint.x() * distPoint.x() + distPoint.y() +
18787 if (distSqr > distSqrMax) {
18788 pv1 = intersections.at(i);
18789 pv2 = intersections.at(k);
18790 distSqrMax = distSqr;
18794 intersections = QList<QPointF>() << pv1 << pv2;
18795 }
else if (intersections.size() != 2) {
18803 if ((key - prevKey) * (intersections.at(1).x() - intersections.at(0).x()) +
18804 (value - prevValue) *
18805 (intersections.at(1).y() - intersections.at(0).y()) <
18807 intersections.move(0, 1);
18808 crossA =
coordsToPixels(intersections.at(0).x(), intersections.at(0).y());
18809 crossB =
coordsToPixels(intersections.at(1).x(), intersections.at(1).y());
18848 QVector<QPointF> &beforeTraverse,
18849 QVector<QPointF> &afterTraverse)
const {
18850 switch (prevRegion) {
18852 switch (currentRegion) {
18870 switch (currentRegion) {
18883 switch (currentRegion) {
18901 switch (currentRegion) {
18917 switch (currentRegion) {
18930 switch (currentRegion) {
18948 switch (currentRegion) {
18961 switch (currentRegion) {
18988 if (
mData->isEmpty()) {
18989 qDebug() << Q_FUNC_INFO <<
"requested point distance on curve" <<
mName
18993 if (
mData->size() == 1) {
18995 mData->constBegin().value().value);
18996 return QVector2D(dataPoint - pixelPoint).length();
19000 QVector<QPointF> *lineData =
new QVector<QPointF>;
19002 double minDistSqr = std::numeric_limits<double>::max();
19003 for (
int i = 0; i < lineData->size() - 1; ++i) {
19004 double currentDistSqr =
19005 distSqrToLine(lineData->at(i), lineData->at(i + 1), pixelPoint);
19006 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
19009 return qSqrt(minDistSqr);
19016 bool haveLower =
false;
19017 bool haveUpper =
false;
19021 QCPCurveDataMap::const_iterator it =
mData->constBegin();
19022 while (it !=
mData->constEnd()) {
19023 current = it.value().key;
19024 if (!qIsNaN(current) && !qIsNaN(it.value().value)) {
19025 if (inSignDomain ==
sdBoth ||
19026 (inSignDomain ==
sdNegative && current < 0) ||
19027 (inSignDomain ==
sdPositive && current > 0)) {
19028 if (current < range.
lower || !haveLower) {
19029 range.
lower = current;
19032 if (current > range.
upper || !haveUpper) {
19033 range.
upper = current;
19041 foundRange = haveLower && haveUpper;
19049 bool haveLower =
false;
19050 bool haveUpper =
false;
19054 QCPCurveDataMap::const_iterator it =
mData->constBegin();
19055 while (it !=
mData->constEnd()) {
19056 current = it.value().value;
19057 if (!qIsNaN(current) && !qIsNaN(it.value().key)) {
19058 if (inSignDomain ==
sdBoth ||
19059 (inSignDomain ==
sdNegative && current < 0) ||
19060 (inSignDomain ==
sdPositive && current > 0)) {
19061 if (current < range.
lower || !haveLower) {
19062 range.
lower = current;
19065 if (current > range.
upper || !haveUpper) {
19066 range.
upper = current;
19074 foundRange = haveLower && haveUpper;
19152 : QObject(parentPlot),
19153 mParentPlot(parentPlot),
19154 mSpacingType(stAbsolute),
19187 if (index >= 0 && index <
mBars.size()) {
19188 return mBars.at(index);
19190 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
19203 bars->setBarsGroup(0);
19214 qDebug() << Q_FUNC_INFO <<
"bars is 0";
19219 bars->setBarsGroup(
this);
19221 qDebug() << Q_FUNC_INFO
19222 <<
"bars plottable is already in this bars group:"
19223 <<
reinterpret_cast<quintptr
>(
bars);
19237 qDebug() << Q_FUNC_INFO <<
"bars is 0";
19254 qDebug() << Q_FUNC_INFO <<
"bars is 0";
19259 bars->setBarsGroup(0);
19261 qDebug() << Q_FUNC_INFO <<
"bars plottable is not in this bars group:"
19262 <<
reinterpret_cast<quintptr
>(
bars);
19293 QList<const QCPBars *> baseBars;
19296 if (!baseBars.contains(b)) baseBars.append(b);
19305 int index = baseBars.indexOf(thisBase);
19308 double lowerPixelWidth, upperPixelWidth;
19309 if (baseBars.size() % 2 == 1 &&
19310 index == (baseBars.size() - 1) /
19315 (baseBars.size() - 1) / 2.0)
19317 if (baseBars.size() % 2 == 0)
19319 startIndex = baseBars.size() / 2 - 1;
19324 startIndex = (baseBars.size() - 1) / 2 - 1;
19325 baseBars.at((baseBars.size() - 1) / 2)
19326 ->getPixelWidth(keyCoord, lowerPixelWidth,
19328 result -= qAbs(upperPixelWidth - lowerPixelWidth) *
19334 for (
int i = startIndex; i > index;
19338 baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth,
19340 result -= qAbs(upperPixelWidth - lowerPixelWidth);
19344 baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth,
19346 result -= qAbs(upperPixelWidth - lowerPixelWidth) * 0.5;
19349 if (baseBars.size() % 2 == 0)
19351 startIndex = baseBars.size() / 2;
19356 startIndex = (baseBars.size() - 1) / 2 + 1;
19357 baseBars.at((baseBars.size() - 1) / 2)
19358 ->getPixelWidth(keyCoord, lowerPixelWidth,
19360 result += qAbs(upperPixelWidth - lowerPixelWidth) *
19366 for (
int i = startIndex; i < index;
19370 baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth,
19372 result += qAbs(upperPixelWidth - lowerPixelWidth);
19376 baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth,
19378 result += qAbs(upperPixelWidth - lowerPixelWidth) * 0.5;
19401 if (
bars->keyAxis()->orientation() == Qt::Horizontal)
19402 return bars->keyAxis()->axisRect()->width() *
mSpacing;
19404 return bars->keyAxis()->axisRect()->height() *
mSpacing;
19407 double keyPixel =
bars->keyAxis()->coordToPixel(keyCoord);
19408 return bars->keyAxis()->coordToPixel(keyCoord +
mSpacing) -
19514 mWidthType(wtPlotCoords),
19519 mPen.setStyle(Qt::SolidLine);
19520 mBrush.setColor(QColor(40, 50, 255, 30));
19521 mBrush.setStyle(Qt::SolidPattern);
19522 mSelectedPen = mPen;
19523 mSelectedPen.setWidthF(2.5);
19524 mSelectedPen.setColor(
19525 QColor(80, 80, 255));
19526 mSelectedBrush = mBrush;
19596 qDebug() << Q_FUNC_INFO
19597 <<
"The data pointer is already in (and owned by) this "
19599 <<
reinterpret_cast<quintptr
>(
data);
19617 const QVector<double> &value) {
19619 int n = key.size();
19620 n = qMin(n, value.size());
19622 for (
int i = 0; i < n; ++i) {
19623 newData.
key = key[i];
19624 newData.
value = value[i];
19645 if (bars ==
this)
return;
19648 qDebug() << Q_FUNC_INFO
19649 <<
"passed QCPBars* doesn't have same key and value axis as "
19679 if (bars ==
this)
return;
19682 qDebug() << Q_FUNC_INFO
19683 <<
"passed QCPBars* doesn't have same key and value axis as "
19720 newData.
value = value;
19729 const QVector<double> &values) {
19730 int n = keys.size();
19731 n = qMin(n, values.size());
19733 for (
int i = 0; i < n; ++i) {
19734 newData.
key = keys[i];
19735 newData.
value = values[i];
19745 QCPBarDataMap::iterator it =
mData->begin();
19746 while (it !=
mData->end() && it.key() < key) it =
mData->erase(it);
19754 if (
mData->isEmpty())
return;
19755 QCPBarDataMap::iterator it =
mData->upperBound(key);
19756 while (it !=
mData->end()) it =
mData->erase(it);
19767 if (fromKey >= toKey ||
mData->isEmpty())
return;
19768 QCPBarDataMap::iterator it =
mData->upperBound(fromKey);
19769 QCPBarDataMap::iterator itEnd =
mData->upperBound(toKey);
19770 while (it != itEnd) it =
mData->erase(it);
19792 bool onlySelectable,
19793 QVariant *details)
const {
19797 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
19801 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
19802 QCPBarDataMap::ConstIterator it;
19803 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it) {
19816 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
19819 if (
mData->isEmpty())
return;
19821 QCPBarDataMap::const_iterator it, lower, upperEnd;
19823 for (it = lower; it != upperEnd; ++it) {
19825 #ifdef QCUSTOMPLOT_CHECK_DATA
19827 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key()
19828 <<
"of drawn range invalid."
19829 <<
"Plottable name:" <<
name();
19831 QPolygonF barPolygon =
getBarPolygon(it.key(), it.value().value);
19833 if (
mainBrush().style() != Qt::NoBrush &&
19836 painter->
setPen(Qt::NoPen);
19838 painter->drawPolygon(barPolygon);
19844 painter->setBrush(Qt::NoBrush);
19845 painter->drawPolyline(barPolygon);
19854 painter->setBrush(
mBrush);
19856 QRectF r = QRectF(0, 0, rect.width() * 0.67, rect.height() * 0.67);
19857 r.moveCenter(rect.center());
19858 painter->drawRect(r);
19880 QCPBarDataMap::const_iterator &lower,
19881 QCPBarDataMap::const_iterator &upperEnd)
const {
19883 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
19886 if (
mData->isEmpty()) {
19887 lower =
mData->constEnd();
19888 upperEnd =
mData->constEnd();
19894 upperEnd =
mData->upperBound(
mKeyAxis.data()->range().upper);
19895 double lowerPixelBound =
19897 double upperPixelBound =
19899 bool isVisible =
false;
19902 QCPBarDataMap::const_iterator it = lower;
19903 while (it !=
mData->constBegin()) {
19906 getBarPolygon(it.value().key, it.value().value).boundingRect();
19907 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
19908 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
19909 barBounds.right() >= lowerPixelBound) ||
19910 (
mKeyAxis.data()->rangeReversed() &&
19911 barBounds.left() <= lowerPixelBound));
19913 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
19914 barBounds.top() <= lowerPixelBound) ||
19915 (
mKeyAxis.data()->rangeReversed() &&
19916 barBounds.bottom() >= lowerPixelBound));
19925 while (it !=
mData->constEnd()) {
19927 getBarPolygon(upperEnd.value().key, upperEnd.value().value)
19929 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
19930 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
19931 barBounds.left() <= upperPixelBound) ||
19932 (
mKeyAxis.data()->rangeReversed() &&
19933 barBounds.right() >= upperPixelBound));
19935 isVisible = ((!
mKeyAxis.data()->rangeReversed() &&
19936 barBounds.bottom() >= upperPixelBound) ||
19937 (
mKeyAxis.data()->rangeReversed() &&
19938 barBounds.top() <= upperPixelBound));
19957 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
19958 return QPolygonF();
19962 double lowerPixelWidth, upperPixelWidth;
19970 result << QPointF(keyPixel + lowerPixelWidth, basePixel);
19971 result << QPointF(keyPixel + lowerPixelWidth, valuePixel);
19972 result << QPointF(keyPixel + upperPixelWidth, valuePixel);
19973 result << QPointF(keyPixel + upperPixelWidth, basePixel);
19975 result << QPointF(basePixel, keyPixel + lowerPixelWidth);
19976 result << QPointF(valuePixel, keyPixel + lowerPixelWidth);
19977 result << QPointF(valuePixel, keyPixel + upperPixelWidth);
19978 result << QPointF(basePixel, keyPixel + upperPixelWidth);
20000 (
mKeyAxis.data()->orientation() == Qt::Vertical)))
20001 qSwap(lower, upper);
20006 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
20013 (
mKeyAxis.data()->rangeReversed() ^
20014 (
mKeyAxis.data()->orientation() == Qt::Vertical)))
20015 qSwap(lower, upper);
20017 qDebug() << Q_FUNC_INFO <<
"No key axis or axis rect defined";
20022 double keyPixel =
mKeyAxis.data()->coordToPixel(key);
20031 qDebug() << Q_FUNC_INFO <<
"No key axis defined";
20054 double epsilon = qAbs(key) * 1
e-6;
20056 if (key == 0) epsilon = 1
e-6;
20057 QCPBarDataMap::const_iterator it =
20058 mBarBelow.data()->mData->lowerBound(key - epsilon);
20059 QCPBarDataMap::const_iterator itEnd =
20060 mBarBelow.data()->mData->upperBound(key + epsilon);
20061 while (it != itEnd) {
20062 if ((positive && it.value().value > max) ||
20063 (!positive && it.value().value < max))
20064 max = it.value().value;
20068 return max +
mBarBelow.data()->getStackedBaseValue(key, positive);
20083 if (!lower && !upper)
return;
20089 upper->
mBarBelow.data()->mBarAbove.data() == upper)
20090 upper->
mBarBelow.data()->mBarAbove = 0;
20096 lower->
mBarAbove.data()->mBarBelow.data() == lower)
20097 lower->
mBarAbove.data()->mBarBelow = 0;
20103 lower->
mBarAbove.data()->mBarBelow.data() == lower)
20104 lower->
mBarAbove.data()->mBarBelow = 0;
20107 upper->
mBarBelow.data()->mBarAbove.data() == upper)
20108 upper->
mBarBelow.data()->mBarAbove = 0;
20117 bool haveLower =
false;
20118 bool haveUpper =
false;
20121 QCPBarDataMap::const_iterator it =
mData->constBegin();
20122 while (it !=
mData->constEnd()) {
20123 current = it.value().key;
20124 if (inSignDomain ==
sdBoth ||
20125 (inSignDomain ==
sdNegative && current < 0) ||
20126 (inSignDomain ==
sdPositive && current > 0)) {
20127 if (current < range.
lower || !haveLower) {
20128 range.
lower = current;
20131 if (current > range.
upper || !haveUpper) {
20132 range.
upper = current;
20141 double lowerPixelWidth, upperPixelWidth, keyPixel;
20143 keyPixel =
mKeyAxis.data()->coordToPixel(range.
lower) + lowerPixelWidth;
20149 double lowerPixelWidth, upperPixelWidth, keyPixel;
20151 keyPixel =
mKeyAxis.data()->coordToPixel(range.
upper) + upperPixelWidth;
20156 foundRange = haveLower && haveUpper;
20166 bool haveLower =
true;
20168 bool haveUpper =
true;
20172 QCPBarDataMap::const_iterator it =
mData->constBegin();
20173 while (it !=
mData->constEnd()) {
20174 current = it.value().value +
20176 if (inSignDomain ==
sdBoth ||
20177 (inSignDomain ==
sdNegative && current < 0) ||
20178 (inSignDomain ==
sdPositive && current > 0)) {
20179 if (current < range.
lower || !haveLower) {
20180 range.
lower = current;
20183 if (current > range.
upper || !haveUpper) {
20184 range.
upper = current;
20262 setWhiskerWidth(0.2);
20267 setMedianPen(QPen(
Qt::black, 3, Qt::SolidLine, Qt::FlatCap));
20268 setWhiskerPen(QPen(
Qt::black, 0, Qt::DashLine, Qt::FlatCap));
20349 double lowerQuartile,
20351 double upperQuartile,
20426 bool onlySelectable,
20427 QVariant *details)
const {
20431 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
20435 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
20436 double posKey, posValue;
20441 if (keyRange.contains(posKey) && valueRange.contains(posValue))
20447 mKeyAxis.data()->coordToPixel(posKey));
20455 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
20460 #ifdef QCUSTOMPLOT_CHECK_DATA
20464 qDebug() << Q_FUNC_INFO <<
"Data point at" <<
mKey
20465 <<
"of drawn range has invalid data."
20466 <<
"Plottable name:" <<
name();
20467 for (
int i = 0; i <
mOutliers.size(); ++i)
20469 qDebug() << Q_FUNC_INFO <<
"Data point outlier at" <<
mKey
20470 <<
"of drawn range invalid."
20471 <<
"Plottable name:" <<
name();
20474 QRectF quartileBox;
20478 painter->setClipRect(quartileBox, Qt::IntersectClip);
20488 const QRectF &rect)
const {
20492 painter->setBrush(
mBrush);
20493 QRectF r = QRectF(0, 0, rect.width() * 0.67, rect.height() * 0.67);
20494 r.moveCenter(rect.center());
20495 painter->drawRect(r);
20506 QRectF *quartileBox)
const {
20513 painter->drawRect(box);
20514 if (quartileBox) *quartileBox = box;
20535 QLineF backboneMin, backboneMax, barMin, barMax;
20560 for (
int i = 0; i <
mOutliers.size(); ++i)
20568 if (inSignDomain ==
sdBoth) {
20576 foundRange =
false;
20585 foundRange =
false;
20589 foundRange =
false;
20596 QVector<double> values;
20603 bool haveUpper =
false;
20604 bool haveLower =
false;
20607 for (
int i = 0; i < values.size(); ++i) {
20608 if ((inSignDomain ==
sdNegative && values.at(i) < 0) ||
20609 (inSignDomain ==
sdPositive && values.at(i) > 0) ||
20610 (inSignDomain ==
sdBoth)) {
20611 if (values.at(i) > upper || !haveUpper) {
20612 upper = values.at(i);
20615 if (values.at(i) < lower || !haveLower) {
20616 lower = values.at(i);
20622 if (haveLower && haveUpper) {
20627 foundRange =
false;
20691 mKeyRange(keyRange),
20692 mValueRange(valueRange),
20695 mDataModified(true) {
20696 setSize(keySize, valueSize);
20713 mDataModified(true) {
20721 if (&other !=
this) {
20743 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 &&
20752 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 &&
20778 #ifdef __EXCEPTIONS
20783 #ifdef __EXCEPTIONS
20791 qDebug() << Q_FUNC_INFO <<
"out of memory for data dimensions "
20897 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 &&
20919 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 &&
20945 double minHeight =
mData[0];
20946 double maxHeight =
mData[0];
20948 for (
int i = 0; i < dataCount; ++i) {
20949 if (
mData[i] > maxHeight) maxHeight =
mData[i];
20950 if (
mData[i] < minHeight) minHeight =
mData[i];
20969 for (
int i = 0; i < dataCount; ++i)
mData[i] =
z;
20996 int *valueIndex)
const {
21028 double *value)
const {
21030 *key = keyIndex / (double)(
mKeySize - 1) *
21034 *value = valueIndex / (double)(
mValueSize - 1) *
21150 mDataScaleType(
QCPAxis::stLinear),
21152 mInterpolate(true),
21153 mTightBoundary(false),
21154 mMapImageInvalidated(true) {}
21168 qDebug() << Q_FUNC_INFO
21169 <<
"The data pointer is already in (and owned by) this "
21171 <<
reinterpret_cast<quintptr
>(
data);
21374 const QSize &thumbSize) {
21390 QPixmap::fromImage(
mMapImage.mirrored(mirrorX, mirrorY))
21391 .scaled(thumbSize, Qt::KeepAspectRatio, transformMode);
21403 bool onlySelectable,
21404 QVariant *details)
const {
21408 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
21412 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
21413 double posKey, posValue;
21444 int keyOversamplingFactor =
21448 100.0 / (
double)keySize);
21453 int valueOversamplingFactor =
21457 100.0 / (
double)valueSize);
21466 (
mMapImage.width() != keySize * keyOversamplingFactor ||
21467 mMapImage.height() != valueSize * valueOversamplingFactor))
21468 mMapImage = QImage(QSize(keySize * keyOversamplingFactor,
21469 valueSize * valueOversamplingFactor),
21470 QImage::Format_RGB32);
21472 (
mMapImage.width() != valueSize * valueOversamplingFactor ||
21473 mMapImage.height() != keySize * keyOversamplingFactor))
21474 mMapImage = QImage(QSize(valueSize * valueOversamplingFactor,
21475 keySize * keyOversamplingFactor),
21476 QImage::Format_RGB32);
21478 QImage *localMapImage =
21482 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
21488 QImage(QSize(keySize, valueSize), QImage::Format_RGB32);
21493 QImage(QSize(valueSize, keySize), QImage::Format_RGB32);
21504 const int lineCount = valueSize;
21505 const int rowCount = keySize;
21506 for (
int line = 0; line < lineCount; ++line) {
21507 QRgb *pixels =
reinterpret_cast<QRgb *
>(localMapImage->scanLine(
21519 const int lineCount = keySize;
21520 const int rowCount = valueSize;
21521 for (
int line = 0; line < lineCount; ++line) {
21522 QRgb *pixels =
reinterpret_cast<QRgb *
>(localMapImage->scanLine(
21534 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) {
21537 keySize * keyOversamplingFactor,
21538 valueSize * valueOversamplingFactor, Qt::IgnoreAspectRatio,
21539 Qt::FastTransformation);
21542 valueSize * valueOversamplingFactor,
21543 keySize * keyOversamplingFactor, Qt::IgnoreAspectRatio,
21544 Qt::FastTransformation);
21562 QRectF mapBufferTarget;
21565 double mapBufferPixelRatio =
21568 mapBufferTarget = painter->clipRegion().boundingRect();
21569 mapBuffer = QPixmap(
21570 (mapBufferTarget.size() * mapBufferPixelRatio).toSize());
21571 mapBuffer.fill(Qt::transparent);
21573 localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio);
21574 localPainter->translate(-mapBufferTarget.topLeft());
21584 double halfCellWidth = 0;
21585 double halfCellHeight = 0;
21586 if (
keyAxis()->orientation() == Qt::Horizontal) {
21591 halfCellHeight = 0.5 * imageRect.height() /
21596 halfCellHeight = 0.5 * imageRect.height() /
21599 halfCellWidth = 0.5 * imageRect.width() /
21602 imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth,
21610 bool smoothBackup = localPainter->renderHints().testFlag(
21611 QPainter::SmoothPixmapTransform);
21612 localPainter->setRenderHint(QPainter::SmoothPixmapTransform,
mInterpolate);
21613 QRegion clipBackup;
21615 clipBackup = localPainter->clipRegion();
21616 QRectF tightClipRect =
21622 localPainter->setClipRect(tightClipRect, Qt::IntersectClip);
21624 localPainter->drawImage(imageRect,
mMapImage.mirrored(mirrorX, mirrorY));
21626 localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup);
21631 delete localPainter;
21632 painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer);
21638 const QRectF &rect)
const {
21642 QPixmap scaledIcon =
21643 mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio,
21644 Qt::FastTransformation);
21645 QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height());
21646 iconRect.moveCenter(rect.center());
21647 painter->drawPixmap(iconRect.topLeft(), scaledIcon);
21667 foundRange =
false;
21672 foundRange =
false;
21687 foundRange =
false;
21692 foundRange =
false;
21720 : key(0), open(0), high(0), low(0), close(0) {}
21726 double key,
double open,
double high,
double low,
double close)
21727 : key(key), open(open), high(high), low(low), close(close) {}
21796 mChartStyle(csOhlc),
21798 mTwoColored(false),
21799 mBrushPositive(QBrush(QColor(210, 210, 255))),
21800 mBrushNegative(QBrush(QColor(255, 210, 210))),
21801 mPenPositive(QPen(QColor(10, 40, 180))),
21802 mPenNegative(QPen(QColor(180, 40, 10))) {
21827 qDebug() << Q_FUNC_INFO
21828 <<
"The data pointer is already in (and owned by) this "
21830 <<
reinterpret_cast<quintptr
>(
data);
21850 const QVector<double> &open,
21851 const QVector<double> &high,
21852 const QVector<double> &low,
21853 const QVector<double> &close) {
21855 int n = key.size();
21856 n = qMin(n, open.size());
21857 n = qMin(n, high.size());
21858 n = qMin(n, low.size());
21859 n = qMin(n, close.size());
21860 for (
int i = 0; i < n; ++i) {
21982 double key,
double open,
double high,
double low,
double close) {
21997 const QVector<double> &open,
21998 const QVector<double> &high,
21999 const QVector<double> &low,
22000 const QVector<double> &close) {
22001 int n = key.size();
22002 n = qMin(n, open.size());
22003 n = qMin(n, high.size());
22004 n = qMin(n, low.size());
22005 n = qMin(n, close.size());
22006 for (
int i = 0; i < n; ++i) {
22019 QCPFinancialDataMap::iterator it =
mData->begin();
22020 while (it !=
mData->end() && it.key() < key) it =
mData->erase(it);
22029 if (
mData->isEmpty())
return;
22030 QCPFinancialDataMap::iterator it =
mData->upperBound(key);
22031 while (it !=
mData->end()) it =
mData->erase(it);
22042 if (fromKey >= toKey ||
mData->isEmpty())
return;
22043 QCPFinancialDataMap::iterator it =
mData->upperBound(fromKey);
22044 QCPFinancialDataMap::iterator itEnd =
mData->upperBound(toKey);
22045 while (it != itEnd) it =
mData->erase(it);
22068 bool onlySelectable,
22069 QVariant *details)
const {
22073 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22077 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint())) {
22079 QCPFinancialDataMap::const_iterator lower,
22083 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
return -1;
22112 const QVector<double> &value,
22113 double timeBinSize,
22114 double timeBinOffset) {
22116 int count = qMin(time.size(), value.size());
22120 value.first(), value.first());
22121 int currentBinIndex =
22122 qFloor((time.first() - timeBinOffset) / timeBinSize + 0.5);
22123 for (
int i = 0; i <
count; ++i) {
22124 int index = qFloor((time.at(i) - timeBinOffset) / timeBinSize + 0.5);
22125 if (currentBinIndex ==
22128 if (value.at(i) < currentBinData.low)
22129 currentBinData.low = value.at(i);
22130 if (value.at(i) > currentBinData.high)
22131 currentBinData.high = value.at(i);
22135 currentBinData.close = value.at(i);
22136 currentBinData.key = timeBinOffset + (index)*timeBinSize;
22137 map.insert(currentBinData.key, currentBinData);
22143 currentBinData.close = value.at(i - 1);
22144 currentBinData.key = timeBinOffset + (index - 1) * timeBinSize;
22145 map.insert(currentBinData.key, currentBinData);
22147 currentBinIndex = index;
22148 currentBinData.open = value.at(i);
22149 currentBinData.high = value.at(i);
22150 currentBinData.low = value.at(i);
22160 QCPFinancialDataMap::const_iterator lower,
22164 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
return;
22179 const QRectF &rect)
const {
22187 painter->setClipRegion(QRegion(QPolygon()
22188 << rect.bottomLeft().toPoint()
22189 << rect.topRight().toPoint()
22190 << rect.topLeft().toPoint()));
22191 painter->
drawLine(QLineF(0, rect.height() * 0.5, rect.width(),
22192 rect.height() * 0.5)
22193 .translated(rect.topLeft()));
22194 painter->
drawLine(QLineF(rect.width() * 0.2, rect.height() * 0.3,
22195 rect.width() * 0.2, rect.height() * 0.5)
22196 .translated(rect.topLeft()));
22197 painter->
drawLine(QLineF(rect.width() * 0.8, rect.height() * 0.5,
22198 rect.width() * 0.8, rect.height() * 0.7)
22199 .translated(rect.topLeft()));
22203 painter->setClipRegion(QRegion(QPolygon()
22204 << rect.bottomLeft().toPoint()
22205 << rect.topRight().toPoint()
22206 << rect.bottomRight().toPoint()));
22207 painter->
drawLine(QLineF(0, rect.height() * 0.5, rect.width(),
22208 rect.height() * 0.5)
22209 .translated(rect.topLeft()));
22210 painter->
drawLine(QLineF(rect.width() * 0.2, rect.height() * 0.3,
22211 rect.width() * 0.2, rect.height() * 0.5)
22212 .translated(rect.topLeft()));
22213 painter->
drawLine(QLineF(rect.width() * 0.8, rect.height() * 0.5,
22214 rect.width() * 0.8, rect.height() * 0.7)
22215 .translated(rect.topLeft()));
22217 painter->setBrush(
mBrush);
22219 painter->
drawLine(QLineF(0, rect.height() * 0.5, rect.width(),
22220 rect.height() * 0.5)
22221 .translated(rect.topLeft()));
22222 painter->
drawLine(QLineF(rect.width() * 0.2, rect.height() * 0.3,
22223 rect.width() * 0.2, rect.height() * 0.5)
22224 .translated(rect.topLeft()));
22225 painter->
drawLine(QLineF(rect.width() * 0.8, rect.height() * 0.5,
22226 rect.width() * 0.8, rect.height() * 0.7)
22227 .translated(rect.topLeft()));
22234 painter->setClipRegion(QRegion(QPolygon()
22235 << rect.bottomLeft().toPoint()
22236 << rect.topRight().toPoint()
22237 << rect.topLeft().toPoint()));
22238 painter->
drawLine(QLineF(0, rect.height() * 0.5,
22239 rect.width() * 0.25, rect.height() * 0.5)
22240 .translated(rect.topLeft()));
22241 painter->
drawLine(QLineF(rect.width() * 0.75, rect.height() * 0.5,
22242 rect.width(), rect.height() * 0.5)
22243 .translated(rect.topLeft()));
22244 painter->drawRect(QRectF(rect.width() * 0.25, rect.height() * 0.25,
22245 rect.width() * 0.5, rect.height() * 0.5)
22246 .translated(rect.topLeft()));
22250 painter->setClipRegion(QRegion(QPolygon()
22251 << rect.bottomLeft().toPoint()
22252 << rect.topRight().toPoint()
22253 << rect.bottomRight().toPoint()));
22254 painter->
drawLine(QLineF(0, rect.height() * 0.5,
22255 rect.width() * 0.25, rect.height() * 0.5)
22256 .translated(rect.topLeft()));
22257 painter->
drawLine(QLineF(rect.width() * 0.75, rect.height() * 0.5,
22258 rect.width(), rect.height() * 0.5)
22259 .translated(rect.topLeft()));
22260 painter->drawRect(QRectF(rect.width() * 0.25, rect.height() * 0.25,
22261 rect.width() * 0.5, rect.height() * 0.5)
22262 .translated(rect.topLeft()));
22264 painter->setBrush(
mBrush);
22266 painter->
drawLine(QLineF(0, rect.height() * 0.5,
22267 rect.width() * 0.25, rect.height() * 0.5)
22268 .translated(rect.topLeft()));
22269 painter->
drawLine(QLineF(rect.width() * 0.75, rect.height() * 0.5,
22270 rect.width(), rect.height() * 0.5)
22271 .translated(rect.topLeft()));
22272 painter->drawRect(QRectF(rect.width() * 0.25, rect.height() * 0.25,
22273 rect.width() * 0.5, rect.height() * 0.5)
22274 .translated(rect.topLeft()));
22283 bool haveLower =
false;
22284 bool haveUpper =
false;
22287 QCPFinancialDataMap::const_iterator it =
mData->constBegin();
22288 while (it !=
mData->constEnd()) {
22289 current = it.value().key;
22290 if (inSignDomain ==
sdBoth ||
22291 (inSignDomain ==
sdNegative && current < 0) ||
22292 (inSignDomain ==
sdPositive && current > 0)) {
22293 if (current < range.
lower || !haveLower) {
22294 range.
lower = current;
22297 if (current > range.
upper || !haveUpper) {
22298 range.
upper = current;
22307 foundRange = haveLower && haveUpper;
22315 bool haveLower =
false;
22316 bool haveUpper =
false;
22318 QCPFinancialDataMap::const_iterator it =
mData->constBegin();
22319 while (it !=
mData->constEnd()) {
22321 if (inSignDomain ==
sdBoth ||
22322 (inSignDomain ==
sdNegative && it.value().high < 0) ||
22323 (inSignDomain ==
sdPositive && it.value().high > 0)) {
22324 if (it.value().high < range.
lower || !haveLower) {
22325 range.
lower = it.value().high;
22328 if (it.value().high > range.
upper || !haveUpper) {
22329 range.
upper = it.value().high;
22334 if (inSignDomain ==
sdBoth ||
22335 (inSignDomain ==
sdNegative && it.value().low < 0) ||
22336 (inSignDomain ==
sdPositive && it.value().low > 0)) {
22337 if (it.value().low < range.
lower || !haveLower) {
22338 range.
lower = it.value().low;
22341 if (it.value().low > range.
upper || !haveUpper) {
22342 range.
upper = it.value().low;
22349 foundRange = haveLower && haveUpper;
22363 const QCPFinancialDataMap::const_iterator &begin,
22364 const QCPFinancialDataMap::const_iterator &end) {
22368 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22375 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) {
22379 linePen = it.value().close >= it.value().open ?
mPenPositive
22383 painter->
setPen(linePen);
22392 double keyWidthPixels =
22398 painter->
drawLine(QPointF(keyPixel - keyWidthPixels, openPixel),
22399 QPointF(keyPixel, openPixel));
22401 painter->
drawLine(QPointF(keyPixel, closePixel),
22402 QPointF(keyPixel + keyWidthPixels, closePixel));
22405 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) {
22409 linePen = it.value().close >= it.value().open ?
mPenPositive
22413 painter->
setPen(linePen);
22422 double keyWidthPixels =
22428 painter->
drawLine(QPointF(openPixel, keyPixel - keyWidthPixels),
22429 QPointF(openPixel, keyPixel));
22431 painter->
drawLine(QPointF(closePixel, keyPixel),
22432 QPointF(closePixel, keyPixel + keyWidthPixels));
22447 const QCPFinancialDataMap::const_iterator &begin,
22448 const QCPFinancialDataMap::const_iterator &end) {
22452 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22460 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) {
22465 if (it.value().close >= it.value().open) {
22476 painter->
setPen(linePen);
22477 painter->setBrush(boxBrush);
22486 qMax(it.value().open, it.value().close))));
22492 qMin(it.value().open, it.value().close))));
22494 double keyWidthPixels =
22498 QRectF(QPointF(keyPixel - keyWidthPixels, closePixel),
22499 QPointF(keyPixel + keyWidthPixels, openPixel)));
22503 for (QCPFinancialDataMap::const_iterator it = begin; it != end; ++it) {
22508 if (it.value().close >= it.value().open) {
22519 painter->
setPen(linePen);
22520 painter->setBrush(boxBrush);
22528 qMax(it.value().open, it.value().close)),
22534 qMin(it.value().open, it.value().close)),
22537 double keyWidthPixels =
22541 QRectF(QPointF(closePixel, keyPixel - keyWidthPixels),
22542 QPointF(openPixel, keyPixel + keyWidthPixels)));
22554 const QPointF &pos,
22555 const QCPFinancialDataMap::const_iterator &begin,
22556 const QCPFinancialDataMap::const_iterator &end)
const {
22560 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22564 double minDistSqr = std::numeric_limits<double>::max();
22565 QCPFinancialDataMap::const_iterator it;
22567 for (it = begin; it != end; ++it) {
22574 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
22578 for (it = begin; it != end; ++it) {
22585 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
22588 return qSqrt(minDistSqr);
22598 const QPointF &pos,
22599 const QCPFinancialDataMap::const_iterator &begin,
22600 const QCPFinancialDataMap::const_iterator &end)
const {
22604 qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
22608 double minDistSqr = std::numeric_limits<double>::max();
22609 QCPFinancialDataMap::const_iterator it;
22611 for (it = begin; it != end; ++it) {
22612 double currentDistSqr;
22615 it.value().key +
mWidth * 0.5);
22616 QCPRange boxValueRange(it.value().close, it.value().open);
22617 double posKey, posValue;
22619 if (boxKeyRange.
contains(posKey) &&
22632 it.value().open, it.value().close))),
22639 it.value().open, it.value().close))),
22641 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
22643 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
22647 for (it = begin; it != end; ++it) {
22648 double currentDistSqr;
22651 it.value().key +
mWidth * 0.5);
22652 QCPRange boxValueRange(it.value().close, it.value().open);
22653 double posKey, posValue;
22655 if (boxKeyRange.
contains(posKey) &&
22667 it.value().close)),
22674 it.value().close)),
22677 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
22679 if (currentDistSqr < minDistSqr) minDistSqr = currentDistSqr;
22682 return qSqrt(minDistSqr);
22704 QCPFinancialDataMap::const_iterator &lower,
22705 QCPFinancialDataMap::const_iterator &upper)
const {
22707 qDebug() << Q_FUNC_INFO <<
"invalid key axis";
22710 if (
mData->isEmpty()) {
22711 lower =
mData->constEnd();
22712 upper =
mData->constEnd();
22717 QCPFinancialDataMap::const_iterator lbound =
22719 QCPFinancialDataMap::const_iterator ubound =
22722 lbound !=
mData->constBegin();
22725 ubound !=
mData->constEnd();
22728 lower = (lowoutlier
22731 upper = (highoutlier ? ubound : ubound - 1);
22755 point1(createPosition(QLatin1String(
"point1"))),
22756 point2(createPosition(QLatin1String(
"point2"))) {
22757 point1->setCoords(0, 0);
22758 point2->setCoords(1, 1);
22784 bool onlySelectable,
22785 QVariant *details)
const {
22800 double clipPad =
mainPen().widthF();
22802 start, end - start,
22803 clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad));
22805 if (!line.isNull()) {
22819 const QVector2D &vec,
22820 const QVector2D &point)
const {
22821 return qAbs((base.y() - point.y()) * vec.x() -
22822 (base.x() - point.x()) * vec.y()) /
22834 const QVector2D &base,
const QVector2D &vec,
const QRect &rect)
const {
22838 if (vec.x() == 0 && vec.y() == 0)
return result;
22839 if (qFuzzyIsNull(vec.x()))
22844 gamma = base.x() - bx + (by - base.y()) * vec.x() / vec.y();
22845 if (gamma >= 0 && gamma <= rect.width())
22846 result.setLine(bx + gamma, rect.top(), bx + gamma,
22849 }
else if (qFuzzyIsNull(vec.y()))
22854 gamma = base.y() - by + (bx - base.x()) * vec.y() / vec.x();
22855 if (gamma >= 0 && gamma <= rect.height())
22856 result.setLine(rect.left(), by + gamma, rect.right(),
22861 QList<QVector2D> pointVectors;
22865 gamma = base.x() - bx + (by - base.y()) * vec.x() / vec.y();
22866 if (gamma >= 0 && gamma <= rect.width())
22867 pointVectors.append(QVector2D(bx + gamma, by));
22870 by = rect.bottom();
22871 gamma = base.x() - bx + (by - base.y()) * vec.x() / vec.y();
22872 if (gamma >= 0 && gamma <= rect.width())
22873 pointVectors.append(QVector2D(bx + gamma, by));
22877 gamma = base.y() - by + (bx - base.x()) * vec.y() / vec.x();
22878 if (gamma >= 0 && gamma <= rect.height())
22879 pointVectors.append(QVector2D(bx, by + gamma));
22883 gamma = base.y() - by + (bx - base.x()) * vec.y() / vec.x();
22884 if (gamma >= 0 && gamma <= rect.height())
22885 pointVectors.append(QVector2D(bx, by + gamma));
22888 if (pointVectors.size() == 2) {
22889 result.setPoints(pointVectors.at(0).toPointF(),
22890 pointVectors.at(1).toPointF());
22891 }
else if (pointVectors.size() > 2) {
22894 double distSqrMax = 0;
22895 QVector2D pv1, pv2;
22896 for (
int i = 0; i < pointVectors.size() - 1; ++i) {
22897 for (
int k = i + 1; k < pointVectors.size(); ++k) {
22898 double distSqr = (pointVectors.at(i) - pointVectors.at(k))
22900 if (distSqr > distSqrMax) {
22901 pv1 = pointVectors.at(i);
22902 pv2 = pointVectors.at(k);
22903 distSqrMax = distSqr;
22907 result.setPoints(pv1.toPointF(), pv2.toPointF());
22946 start(createPosition(QLatin1String(
"start"))),
22947 end(createPosition(QLatin1String(
"end"))) {
22948 start->setCoords(0, 0);
22949 end->setCoords(1, 1);
22997 bool onlySelectable,
22998 QVariant *details)
const {
23009 if (startVec.toPoint() == endVec.toPoint())
return;
23012 clipPad = qMax(clipPad, (
double)
mainPen().widthF());
23015 clipRect().adjusted(-clipPad, -clipPad, clipPad, clipPad));
23017 if (!line.isNull()) {
23020 painter->setBrush(Qt::SolidPattern);
23022 mTail.
draw(painter, startVec, startVec - endVec);
23024 mHead.
draw(painter, endVec, endVec - startVec);
23036 const QVector2D &end,
23037 const QRect &rect)
const {
23038 bool containsStart = rect.contains(
start.x(),
start.y());
23039 bool containsEnd = rect.contains(
end.x(),
end.y());
23040 if (containsStart && containsEnd)
23041 return QLineF(
start.toPointF(),
end.toPointF());
23043 QVector2D base =
start;
23048 QList<QVector2D> pointVectors;
23050 if (!qFuzzyIsNull(vec.y()))
23055 mu = (by - base.y()) / vec.y();
23056 if (mu >= 0 && mu <= 1) {
23057 gamma = base.x() - bx + mu * vec.x();
23058 if (gamma >= 0 && gamma <= rect.width())
23059 pointVectors.append(QVector2D(bx + gamma, by));
23063 by = rect.bottom();
23064 mu = (by - base.y()) / vec.y();
23065 if (mu >= 0 && mu <= 1) {
23066 gamma = base.x() - bx + mu * vec.x();
23067 if (gamma >= 0 && gamma <= rect.width())
23068 pointVectors.append(QVector2D(bx + gamma, by));
23071 if (!qFuzzyIsNull(vec.x()))
23076 mu = (bx - base.x()) / vec.x();
23077 if (mu >= 0 && mu <= 1) {
23078 gamma = base.y() - by + mu * vec.y();
23079 if (gamma >= 0 && gamma <= rect.height())
23080 pointVectors.append(QVector2D(bx, by + gamma));
23085 mu = (bx - base.x()) / vec.x();
23086 if (mu >= 0 && mu <= 1) {
23087 gamma = base.y() - by + mu * vec.y();
23088 if (gamma >= 0 && gamma <= rect.height())
23089 pointVectors.append(QVector2D(bx, by + gamma));
23093 if (containsStart) pointVectors.append(
start);
23094 if (containsEnd) pointVectors.append(
end);
23097 if (pointVectors.size() == 2) {
23098 result.setPoints(pointVectors.at(0).toPointF(),
23099 pointVectors.at(1).toPointF());
23100 }
else if (pointVectors.size() > 2) {
23103 double distSqrMax = 0;
23104 QVector2D pv1, pv2;
23105 for (
int i = 0; i < pointVectors.size() - 1; ++i) {
23106 for (
int k = i + 1; k < pointVectors.size(); ++k) {
23107 double distSqr = (pointVectors.at(i) - pointVectors.at(k))
23109 if (distSqr > distSqrMax) {
23110 pv1 = pointVectors.at(i);
23111 pv2 = pointVectors.at(k);
23112 distSqrMax = distSqr;
23116 result.setPoints(pv1.toPointF(), pv2.toPointF());
23159 start(createPosition(QLatin1String(
"start"))),
23160 startDir(createPosition(QLatin1String(
"startDir"))),
23161 endDir(createPosition(QLatin1String(
"endDir"))),
23162 end(createPosition(QLatin1String(
"end"))) {
23164 startDir->setCoords(0.5, 0);
23165 endDir->setCoords(0, 0.5);
23214 bool onlySelectable,
23215 QVariant *details)
const {
23224 QPainterPath cubicPath(startVec);
23225 cubicPath.cubicTo(startDirVec, endDirVec, endVec);
23227 QPolygonF
polygon = cubicPath.toSubpathPolygons().first();
23228 double minDistSqr = std::numeric_limits<double>::max();
23229 for (
int i = 1; i <
polygon.size(); ++i) {
23231 if (distSqr < minDistSqr) minDistSqr = distSqr;
23233 return qSqrt(minDistSqr);
23242 if (QVector2D(endVec - startVec).length() >
23246 QPainterPath cubicPath(startVec);
23247 cubicPath.cubicTo(startDirVec, endDirVec, endVec);
23252 QRect cubicRect = cubicPath.controlPointRect().toRect();
23253 if (cubicRect.isEmpty())
23255 cubicRect.adjust(0, 0, 1, 1);
23256 if (clip.intersects(cubicRect)) {
23258 painter->drawPath(cubicPath);
23259 painter->setBrush(Qt::SolidPattern);
23261 mTail.
draw(painter, QVector2D(startVec),
23262 M_PI - cubicPath.angleAtPercent(0) / 180.0 *
M_PI);
23265 -cubicPath.angleAtPercent(1) / 180.0 *
M_PI);
23297 topLeft(createPosition(QLatin1String(
"topLeft"))),
23298 bottomRight(createPosition(QLatin1String(
"bottomRight"))),
23299 top(createAnchor(QLatin1String(
"top"), aiTop)),
23300 topRight(createAnchor(QLatin1String(
"topRight"), aiTopRight)),
23301 right(createAnchor(QLatin1String(
"right"), aiRight)),
23302 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
23303 bottomLeft(createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
23304 left(createAnchor(QLatin1String(
"left"), aiLeft)) {
23305 topLeft->setCoords(0, 1);
23306 bottomRight->setCoords(1, 0);
23310 setBrush(Qt::NoBrush);
23311 setSelectedBrush(Qt::NoBrush);
23350 bool onlySelectable,
23351 QVariant *details)
const {
23358 mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0;
23366 if (p1.toPoint() == p2.toPoint())
return;
23367 QRectF rect = QRectF(p1, p2).normalized();
23368 double clipPad =
mainPen().widthF();
23369 QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
23370 if (boundingRect.intersects(
23376 painter->drawRect(rect);
23383 switch (anchorId) {
23385 return (rect.topLeft() + rect.topRight()) * 0.5;
23387 return rect.topRight();
23389 return (rect.topRight() + rect.bottomRight()) * 0.5;
23391 return (rect.bottomLeft() + rect.bottomRight()) * 0.5;
23393 return rect.bottomLeft();
23395 return (rect.topLeft() + rect.bottomLeft()) * 0.5;
23398 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
23445 position(createPosition(QLatin1String(
"position"))),
23446 topLeft(createAnchor(QLatin1String(
"topLeft"), aiTopLeft)),
23447 top(createAnchor(QLatin1String(
"top"), aiTop)),
23448 topRight(createAnchor(QLatin1String(
"topRight"), aiTopRight)),
23449 right(createAnchor(QLatin1String(
"right"), aiRight)),
23450 bottomRight(createAnchor(QLatin1String(
"bottomRight"), aiBottomRight)),
23451 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
23452 bottomLeft(createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
23453 left(createAnchor(QLatin1String(
"left"), aiLeft)) {
23457 setTextAlignment(Qt::AlignTop | Qt::AlignHCenter);
23458 setPositionAlignment(Qt::AlignCenter);
23459 setText(QLatin1String(
"text"));
23579 bool onlySelectable,
23580 QVariant *details)
const {
23588 QTransform inputTransform;
23589 inputTransform.translate(positionPixels.x(), positionPixels.y());
23591 inputTransform.translate(-positionPixels.x(), -positionPixels.y());
23592 QPointF rotatedPos = inputTransform.map(pos);
23593 QFontMetrics fontMetrics(
mFont);
23594 QRect textRect = fontMetrics.boundingRect(
23600 textBoxRect.moveTopLeft(textPos.toPoint());
23608 QTransform transform = painter->transform();
23609 transform.translate(pos.x(), pos.y());
23612 QRect textRect = painter->fontMetrics().boundingRect(
23620 textRect.moveTopLeft(textPos.toPoint() +
23622 textBoxRect.moveTopLeft(textPos.toPoint());
23623 double clipPad =
mainPen().widthF();
23624 QRect boundingRect =
23625 textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
23626 if (transform.mapRect(boundingRect)
23627 .intersects(painter->transform().mapRect(
clipRect()))) {
23628 painter->setTransform(transform);
23629 if ((
mainBrush().style() != Qt::NoBrush &&
23631 (
mainPen().style() != Qt::NoPen &&
23635 painter->drawRect(textBoxRect);
23637 painter->setBrush(Qt::NoBrush);
23647 QTransform transform;
23648 transform.translate(pos.x(), pos.y());
23650 QFontMetrics fontMetrics(
mainFont());
23651 QRect textRect = fontMetrics.boundingRect(
23659 textBoxRect.moveTopLeft(textPos.toPoint());
23660 QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect));
23662 switch (anchorId) {
23664 return rectPoly.at(0);
23666 return (rectPoly.at(0) + rectPoly.at(1)) * 0.5;
23668 return rectPoly.at(1);
23670 return (rectPoly.at(1) + rectPoly.at(2)) * 0.5;
23672 return rectPoly.at(2);
23674 return (rectPoly.at(2) + rectPoly.at(3)) * 0.5;
23676 return rectPoly.at(3);
23678 return (rectPoly.at(3) + rectPoly.at(0)) * 0.5;
23681 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
23697 const QRectF &rect,
23705 result.rx() -= rect.width() / 2.0;
23707 result.rx() -= rect.width();
23709 result.ry() -= rect.height() / 2.0;
23711 result.ry() -= rect.height();
23770 topLeft(createPosition(QLatin1String(
"topLeft"))),
23771 bottomRight(createPosition(QLatin1String(
"bottomRight"))),
23772 topLeftRim(createAnchor(QLatin1String(
"topLeftRim"), aiTopLeftRim)),
23773 top(createAnchor(QLatin1String(
"top"), aiTop)),
23774 topRightRim(createAnchor(QLatin1String(
"topRightRim"), aiTopRightRim)),
23775 right(createAnchor(QLatin1String(
"right"), aiRight)),
23777 createAnchor(QLatin1String(
"bottomRightRim"), aiBottomRightRim)),
23778 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
23780 createAnchor(QLatin1String(
"bottomLeftRim"), aiBottomLeftRim)),
23781 left(createAnchor(QLatin1String(
"left"), aiLeft)),
23782 center(createAnchor(QLatin1String(
"center"), aiCenter)) {
23828 bool onlySelectable,
23829 QVariant *details)
const {
23836 QPointF
center((p1 + p2) / 2.0);
23837 double a = qAbs(p1.x() - p2.x()) / 2.0;
23838 double b = qAbs(p1.y() - p2.y()) / 2.0;
23839 double x = pos.x() -
center.x();
23840 double y = pos.y() -
center.y();
23843 double c = 1.0 / qSqrt(
x *
x / (
a *
a) +
y *
y / (b * b));
23844 result = qAbs(c - 1) * qSqrt(
x *
x +
y *
y);
23847 mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0) {
23848 if (
x *
x / (
a *
a) +
y *
y / (b * b) <= 1)
23858 if (p1.toPoint() == p2.toPoint())
return;
23859 QRectF ellipseRect = QRectF(p1, p2).normalized();
23862 if (ellipseRect.intersects(clip))
23867 #ifdef __EXCEPTIONS
23871 painter->drawEllipse(ellipseRect);
23872 #ifdef __EXCEPTIONS
23874 qDebug() << Q_FUNC_INFO
23875 <<
"Item too large for memory, setting invisible";
23885 switch (anchorId) {
23887 return rect.center() +
23888 (rect.topLeft() - rect.center()) * 1 / qSqrt(2);
23890 return (rect.topLeft() + rect.topRight()) * 0.5;
23892 return rect.center() +
23893 (rect.topRight() - rect.center()) * 1 / qSqrt(2);
23895 return (rect.topRight() + rect.bottomRight()) * 0.5;
23897 return rect.center() +
23898 (rect.bottomRight() - rect.center()) * 1 / qSqrt(2);
23900 return (rect.bottomLeft() + rect.bottomRight()) * 0.5;
23902 return rect.center() +
23903 (rect.bottomLeft() - rect.center()) * 1 / qSqrt(2);
23905 return (rect.topLeft() + rect.bottomLeft()) * 0.5;
23907 return (rect.topLeft() + rect.bottomRight()) * 0.5;
23910 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
23957 topLeft(createPosition(QLatin1String(
"topLeft"))),
23958 bottomRight(createPosition(QLatin1String(
"bottomRight"))),
23959 top(createAnchor(QLatin1String(
"top"), aiTop)),
23960 topRight(createAnchor(QLatin1String(
"topRight"), aiTopRight)),
23961 right(createAnchor(QLatin1String(
"right"), aiRight)),
23962 bottom(createAnchor(QLatin1String(
"bottom"), aiBottom)),
23963 bottomLeft(createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
23964 left(createAnchor(QLatin1String(
"left"), aiLeft)) {
23970 setScaled(
false, Qt::KeepAspectRatio, Qt::SmoothTransformation);
23980 if (
mPixmap.isNull()) qDebug() << Q_FUNC_INFO <<
"pixmap is null";
23988 Qt::AspectRatioMode aspectRatioMode,
23989 Qt::TransformationMode transformationMode) {
24013 bool onlySelectable,
24014 QVariant *details)
const {
24023 bool flipHorz =
false;
24024 bool flipVert =
false;
24026 double clipPad =
mainPen().style() == Qt::NoPen ? 0 :
mainPen().widthF();
24027 QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
24028 if (boundingRect.intersects(
clipRect())) {
24032 if (
pen.style() != Qt::NoPen) {
24034 painter->setBrush(Qt::NoBrush);
24035 painter->drawRect(rect);
24047 if (flipHorz) rect.adjust(rect.width(), 0, -rect.width(), 0);
24048 if (flipVert) rect.adjust(0, rect.height(), 0, -rect.height());
24050 switch (anchorId) {
24052 return (rect.topLeft() + rect.topRight()) * 0.5;
24054 return rect.topRight();
24056 return (rect.topRight() + rect.bottomRight()) * 0.5;
24058 return (rect.bottomLeft() + rect.bottomRight()) * 0.5;
24060 return rect.bottomLeft();
24062 return (rect.topLeft() + rect.bottomLeft()) * 0.5;
24066 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
24086 if (
mPixmap.isNull())
return;
24089 if (finalRect.isNull()) finalRect =
getFinalRect(&flipHorz, &flipVert);
24093 if (flipHorz || flipVert)
24119 bool flipHorz =
false;
24120 bool flipVert =
false;
24123 if (p1 == p2)
return QRect(p1, QSize(0, 0));
24125 QSize newSize = QSize(p2.x() - p1.x(), p2.y() - p1.y());
24127 if (newSize.width() < 0) {
24129 newSize.rwidth() *= -1;
24132 if (newSize.height() < 0) {
24134 newSize.rheight() *= -1;
24137 QSize scaledSize =
mPixmap.size();
24143 if (flippedHorz) *flippedHorz = flipHorz;
24144 if (flippedVert) *flippedVert = flipVert;
24199 position(createPosition(QLatin1String(
"position"))),
24203 setBrush(Qt::NoBrush);
24204 setSelectedBrush(Qt::NoBrush);
24207 setStyle(tsCrosshair);
24209 setInterpolating(
false);
24281 qDebug() << Q_FUNC_INFO
24282 <<
"graph isn't in same QCustomPlot instance as this item";
24316 bool onlySelectable,
24317 QVariant *details)
const {
24322 double w =
mSize / 2.0;
24329 QRectF(center - QPointF(w, w), center + QPointF(w, w))
24332 center + QPointF(w, 0), pos),
24334 center + QPointF(0, w), pos)));
24340 QPointF(clip.right(), center.y()), pos),
24342 QPointF(center.x(), clip.bottom()), pos)));
24345 if (clip.intersects(
24346 QRectF(center - QPointF(w, w), center + QPointF(w, w))
24349 double centerDist = QVector2D(center - pos).length();
24350 double circleLine = w;
24351 double result = qAbs(centerDist - circleLine);
24354 mBrush.style() != Qt::NoBrush &&
24355 mBrush.color().alpha() != 0) {
24356 if (centerDist <= circleLine)
24364 if (clip.intersects(
24365 QRectF(center - QPointF(w, w), center + QPointF(w, w))
24368 QRectF(center - QPointF(w, w), center + QPointF(w, w));
24369 bool filledRect =
mBrush.style() != Qt::NoBrush &&
24370 mBrush.color().alpha() != 0;
24387 double w =
mSize / 2.0;
24393 if (clip.intersects(
24394 QRectF(center - QPointF(w, w), center + QPointF(w, w))
24396 painter->
drawLine(QLineF(center + QPointF(-w, 0),
24397 center + QPointF(w, 0)));
24398 painter->
drawLine(QLineF(center + QPointF(0, -w),
24399 center + QPointF(0, w)));
24404 if (center.y() > clip.top() && center.y() < clip.bottom())
24405 painter->
drawLine(QLineF(clip.left(), center.y(), clip.right(),
24407 if (center.x() > clip.left() && center.x() < clip.right())
24408 painter->
drawLine(QLineF(center.x(), clip.top(), center.x(),
24413 if (clip.intersects(
24414 QRectF(center - QPointF(w, w), center + QPointF(w, w))
24416 painter->drawEllipse(center, w, w);
24420 if (clip.intersects(
24421 QRectF(center - QPointF(w, w), center + QPointF(w, w))
24424 QRectF(center - QPointF(w, w), center + QPointF(w, w)));
24448 QCPDataMap::const_iterator first =
mGraph->
data()->constBegin();
24449 QCPDataMap::const_iterator last =
24456 QCPDataMap::const_iterator it =
24461 QCPDataMap::const_iterator prevIt = it - 1;
24465 if (!qFuzzyCompare((
double)it.key(),
24466 (
double)prevIt.key()))
24467 slope = (it.value().value -
24468 prevIt.value().value) /
24469 (it.key() - prevIt.key());
24473 prevIt.value().value);
24476 if (
mGraphKey < (prevIt.key() + it.key()) * 0.5)
24484 QCPDataMap::const_iterator it =
mGraph->
data()->constBegin();
24487 qDebug() << Q_FUNC_INFO <<
"graph has no data";
24489 qDebug() << Q_FUNC_INFO
24490 <<
"graph not contained in QCustomPlot instance (anymore)";
24545 left(createPosition(QLatin1String(
"left"))),
24546 right(createPosition(QLatin1String(
"right"))),
24547 center(createAnchor(QLatin1String(
"center"), aiCenter)) {
24548 left->setCoords(0, 0);
24549 right->setCoords(1, 1);
24554 setStyle(bsCalligraphic);
24601 bool onlySelectable,
24602 QVariant *details)
const {
24608 if (leftVec.toPoint() == rightVec.toPoint())
return -1;
24610 QVector2D widthVec = (rightVec - leftVec) * 0.5f;
24611 QVector2D lengthVec(-widthVec.y(), widthVec.x());
24612 lengthVec = lengthVec.normalized() *
mLength;
24613 QVector2D centerVec = (rightVec + leftVec) * 0.5f - lengthVec;
24619 (centerVec + widthVec).toPointF(), pos);
24621 distSqrToLine((centerVec - widthVec + lengthVec).toPointF(),
24622 (centerVec - widthVec).toPointF(), pos);
24624 distSqrToLine((centerVec + widthVec + lengthVec).toPointF(),
24625 (centerVec + widthVec).toPointF(), pos);
24626 return qSqrt(qMin(qMin(
a, b), c));
24631 (centerVec - widthVec * 0.75f + lengthVec * 0.15f)
24633 (centerVec + lengthVec * 0.3f).toPointF(), pos);
24635 (centerVec - widthVec + lengthVec * 0.7f).toPointF(),
24636 (centerVec - widthVec * 0.75f + lengthVec * 0.15f)
24640 (centerVec + widthVec * 0.75f + lengthVec * 0.15f)
24642 (centerVec + lengthVec * 0.3f).toPointF(), pos);
24644 (centerVec + widthVec + lengthVec * 0.7f).toPointF(),
24645 (centerVec + widthVec * 0.75f + lengthVec * 0.15f)
24648 return qSqrt(qMin(qMin(
a, b), qMin(c, d)));
24658 if (leftVec.toPoint() == rightVec.toPoint())
return;
24660 QVector2D widthVec = (rightVec - leftVec) * 0.5f;
24661 QVector2D lengthVec(-widthVec.y(), widthVec.x());
24662 lengthVec = lengthVec.normalized() *
mLength;
24663 QVector2D centerVec = (rightVec + leftVec) * 0.5f - lengthVec;
24665 QPolygon boundingPoly;
24666 boundingPoly << leftVec.toPoint() << rightVec.toPoint()
24667 << (rightVec - lengthVec).toPoint()
24668 << (leftVec - lengthVec).toPoint();
24671 if (clip.intersects(boundingPoly.boundingRect())) {
24675 painter->
drawLine((centerVec + widthVec).toPointF(),
24676 (centerVec - widthVec).toPointF());
24678 (centerVec + widthVec).toPointF(),
24679 (centerVec + widthVec + lengthVec).toPointF());
24681 (centerVec - widthVec).toPointF(),
24682 (centerVec - widthVec + lengthVec).toPointF());
24686 painter->setBrush(Qt::NoBrush);
24688 path.moveTo((centerVec + widthVec + lengthVec).toPointF());
24689 path.cubicTo((centerVec + widthVec).toPointF(),
24690 (centerVec + widthVec).toPointF(),
24691 centerVec.toPointF());
24692 path.cubicTo((centerVec - widthVec).toPointF(),
24693 (centerVec - widthVec).toPointF(),
24694 (centerVec - widthVec + lengthVec).toPointF());
24695 painter->drawPath(
path);
24699 painter->setBrush(Qt::NoBrush);
24701 path.moveTo((centerVec + widthVec + lengthVec).toPointF());
24703 (centerVec + widthVec - lengthVec * 0.8f).toPointF(),
24704 (centerVec + 0.4f * widthVec + lengthVec).toPointF(),
24705 centerVec.toPointF());
24707 (centerVec - 0.4f * widthVec + lengthVec).toPointF(),
24708 (centerVec - widthVec - lengthVec * 0.8f).toPointF(),
24709 (centerVec - widthVec + lengthVec).toPointF());
24710 painter->drawPath(
path);
24714 painter->
setPen(Qt::NoPen);
24717 path.moveTo((centerVec + widthVec + lengthVec).toPointF());
24720 (centerVec + widthVec - lengthVec * 0.8f).toPointF(),
24721 (centerVec + 0.4f * widthVec + 0.8f * lengthVec)
24723 centerVec.toPointF());
24725 (centerVec - 0.4f * widthVec + 0.8f * lengthVec)
24727 (centerVec - widthVec - lengthVec * 0.8f).toPointF(),
24728 (centerVec - widthVec + lengthVec).toPointF());
24731 (centerVec - widthVec - lengthVec * 0.5f).toPointF(),
24732 (centerVec - 0.2f * widthVec + 1.2f * lengthVec)
24734 (centerVec + lengthVec * 0.2f).toPointF());
24736 (centerVec + 0.2f * widthVec + 1.2f * lengthVec)
24738 (centerVec + widthVec - lengthVec * 0.5f).toPointF(),
24739 (centerVec + widthVec + lengthVec).toPointF());
24741 painter->drawPath(
path);
24752 if (leftVec.toPoint() == rightVec.toPoint())
return leftVec.toPointF();
24754 QVector2D widthVec = (rightVec - leftVec) * 0.5f;
24755 QVector2D lengthVec(-widthVec.y(), widthVec.x());
24756 lengthVec = lengthVec.normalized() *
mLength;
24757 QVector2D centerVec = (rightVec + leftVec) * 0.5f - lengthVec;
24759 switch (anchorId) {
24761 return centerVec.toPointF();
24763 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
filament::Texture::InternalFormat format
QPointF qtCompatWheelEventPos(const QWheelEvent *event) noexcept
void qtCompatMapInsertMulti(QMap< Key, T > *map, const Key &key, const T &value)
double qtCompatWheelEventDelta(const QWheelEvent *event) noexcept
void qtCompatMapUnite(QMap< Key, T > *map, const QMap< Key, T > &other)
boost::geometry::model::polygon< point_xy > polygon
The abstract base class for all items in a plot.
QCPItemAnchor * anchor(const QString &name) const
Q_SLOT void setSelected(bool selected)
QCPItemPosition * position(const QString &name) const
double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const
QList< QCPItemAnchor * > mAnchors
QPointer< QCPAxisRect > mClipAxisRect
virtual ~QCPAbstractItem()
void setClipToAxisRect(bool clip)
QList< QCPItemPosition * > mPositions
friend class QCPItemAnchor
bool clipToAxisRect() const
virtual QRect clipRect() const
virtual QPointF anchorPixelPoint(int anchorId) const
virtual QCP::Interaction selectionCategory() const
void selectableChanged(bool selectable)
QCPItemPosition * createPosition(const QString &name)
void setClipAxisRect(QCPAxisRect *rect)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
bool hasAnchor(const QString &name) const
Q_SLOT void setSelectable(bool selectable)
double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const
virtual void deselectEvent(bool *selectionStateChanged)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
QCPAbstractItem(QCustomPlot *parentPlot)
void selectionChanged(bool selected)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
QCPAxisRect * clipAxisRect() const
QCPItemAnchor * createAnchor(const QString &name, int anchorId)
The abstract base class for all entries in a QCPLegend.
void setFont(const QFont &font)
QColor mSelectedTextColor
void setSelectedTextColor(const QColor &color)
void setTextColor(const QColor &color)
Q_SLOT void setSelected(bool selected)
void selectionChanged(bool selected)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setSelectedFont(const QFont &font)
Q_SLOT void setSelectable(bool selectable)
virtual QCP::Interaction selectionCategory() const
void selectableChanged(bool selectable)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
virtual QRect clipRect() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void deselectEvent(bool *selectionStateChanged)
QCPLegend * mParentLegend
QCPAbstractLegendItem(QCPLegend *parent)
virtual int dataCount() const
The abstract base class for all data representing objects in a plot.
QCP::SelectionType selectable() const
void applyErrorBarsAntialiasingHint(QCPPainter *painter) const
void setAntialiasedFill(bool enabled)
void rescaleAxes(bool onlyEnlarge=false) const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
QCPAxis * keyAxis() const
void setAntialiasedScatters(bool enabled)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
void pixelsToCoords(double x, double y, double &key, double &value) const
QCP::SelectionType mSelectable
void selectionChanged(bool selected)
bool removeFromLegend(QCPLegend *legend) const
friend class QCPPlottableLegendItem
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const =0
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const =0
void applyDefaultAntialiasingHint(QCPPainter *painter) const
void selectableChanged(QCP::SelectionType selectable)
void setSelectedPen(const QPen &pen)
virtual void deselectEvent(bool *selectionStateChanged)
void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const
void setValueAxis(QCPAxis *axis)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const =0
void setAntialiasedErrorBars(bool enabled)
void setBrush(const QBrush &brush)
void coordsToPixels(double key, double value, double &x, double &y) const
QPointer< QCPAxis > mValueAxis
void setKeyAxis(QCPAxis *axis)
void applyFillAntialiasingHint(QCPPainter *painter) const
bool mAntialiasedScatters
bool addToLegend(QCPLegend *legend)
virtual QRect clipRect() const
void setPen(const QPen &pen)
void setName(const QString &name)
Q_SLOT void setSelectable(QCP::SelectionType selectable)
QPointer< QCPAxis > mKeyAxis
void applyScattersAntialiasingHint(QCPPainter *painter) const
bool removeFromLegend() const
bool mAntialiasedErrorBars
void setSelectedBrush(const QBrush &brush)
void rescaleKeyAxis(bool onlyEnlarge=false) const
QCPAxis * valueAxis() const
QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis)
double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const
virtual QCP::Interaction selectionCategory() const
Q_SLOT void setSelected(bool selected)
Holds multiple axes and arranges them in a rectangular shape.
QList< QCPAbstractItem * > items() const
bool removeAxis(QCPAxis *axis)
QList< QCPAxis * > axes() const
Qt::Orientations mRangeZoom
virtual void update(UpdatePhase phase)
QList< QCPRange > mDragStartHorzRange
QList< QCPGraph * > graphs() const
QCPAxis * addAxis(QCPAxis::AxisType type, QCPAxis *axis=0)
double mRangeZoomFactorVert
QPixmap mBackgroundPixmap
QList< QPointer< QCPAxis > > mRangeDragVertAxis
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details)
QCPAxis * axis(QCPAxis::AxisType type, int index=0) const
QList< QCPAbstractPlottable * > plottables() const
virtual void wheelEvent(QWheelEvent *event)
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
void setupFullAxesBox(bool connectRanges=false)
void updateAxesOffset(QCPAxis::AxisType type)
void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical)
QCPAxis * rangeZoomAxis(Qt::Orientation orientation)
QCPAxis * rangeDragAxis(Qt::Orientation orientation)
QCP::AntialiasedElements mNotAADragBackup
QList< QCPAxis * > addAxes(QCPAxis::AxisTypes types)
void setRangeZoom(Qt::Orientations orientations)
Qt::AspectRatioMode mBackgroundScaledMode
int axisCount(QCPAxis::AxisType type) const
void setRangeZoomFactor(double horizontalFactor, double verticalFactor)
QList< QCPAxis * > axes(QCPAxis::AxisTypes types) const
void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical)
QCPLayoutInset * insetLayout() const
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
QList< QPointer< QCPAxis > > mRangeZoomHorzAxis
QCP::AntialiasedElements mAADragBackup
QPixmap mScaledBackgroundPixmap
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
Qt::Orientations mRangeDrag
QList< QPointer< QCPAxis > > mRangeZoomVertAxis
QList< QCPRange > mDragStartVertRange
void drawBackground(QCPPainter *painter)
QList< QPointer< QCPAxis > > mRangeDragHorzAxis
double mRangeZoomFactorHorz
QHash< QCPAxis::AxisType, QList< QCPAxis * > > mAxes
double rangeZoomFactor(Qt::Orientation orientation)
void setRangeDrag(Qt::Orientations orientations)
void setBackgroundScaled(bool scaled)
virtual int calculateAutoMargin(QCP::MarginSide side)
QCPLayoutInset * mInsetLayout
void setBackground(const QPixmap &pm)
virtual void draw(QCPPainter *painter)
Manages a single axis inside a QCustomPlot.
void setSelectedLabelFont(const QFont &font)
void setOffset(int offset)
virtual QCP::Interaction selectionCategory() const
void setTickLabels(bool show)
void rangeChanged(const QCPRange &newRange)
void setLowerEnding(const QCPLineEnding &ending)
LabelType tickLabelType() const
QCPLineEnding lowerEnding() const
void setTickLabelSide(LabelSide side)
bool autoTickStep() const
QVector< double > mSubTickVector
void moveRange(double diff)
void setTickLabelRotation(double degrees)
LabelSide tickLabelSide() const
QString numberFormat() const
void setRangeReversed(bool reversed)
void setNumberPrecision(int precision)
SelectablePart getPartAt(const QPointF &pos) const
@ lsOutside
Tick labels will be displayed outside the axis rect.
int numberPrecision() const
virtual void draw(QCPPainter *painter)
void setDateTimeSpec(const Qt::TimeSpec &timeSpec)
void setSelectedSubTickPen(const QPen &pen)
void setTickLabelFont(const QFont &font)
QString dateTimeFormat() const
void setDateTimeFormat(const QString &format)
void scaleRange(double factor)
void setLabel(const QString &str)
void scaleTypeChanged(QCPAxis::ScaleType scaleType)
@ stLinear
Linear scaling.
QLatin1Char mNumberFormatChar
void setTickLabelColor(const QColor &color)
void setTickLengthOut(int outside)
QColor mSelectedTickLabelColor
int autoTickCount() const
QList< QCPAbstractItem * > items() const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setLabelPadding(int padding)
virtual int calculateMargin()
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void rescale(bool onlyVisiblePlottables=false)
void setSubTickCount(int count)
void setSubTickLengthOut(int outside)
QFont mSelectedTickLabelFont
virtual void deselectEvent(bool *selectionStateChanged)
double pixelToCoord(double value) const
void setTickLabelType(LabelType type)
void setPadding(int padding)
double tickLabelRotation() const
void setSelectedLabelColor(const QColor &color)
virtual void generateAutoTicks()
void selectionChanged(const QCPAxis::SelectableParts &parts)
void setTickLength(int inside, int outside=0)
void setUpperEnding(const QCPLineEnding &ending)
QFont getTickLabelFont() const
void setLabelColor(const QColor &color)
QVector< double > mTickVector
QCPAxisPainterPrivate * mAxisPainter
void setLabelFont(const QFont &font)
void setScaleLogBase(double base)
void setBasePen(const QPen &pen)
void setAutoTickCount(int approximateCount)
Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts)
void setSelectedTickPen(const QPen &pen)
void setSelectedTickLabelFont(const QFont &font)
void setTickVector(const QVector< double > &vec)
SelectableParts selectedParts() const
QColor getTickLabelColor() const
double scaleLogBase() const
SelectableParts mSelectedParts
void setTickVectorLabels(const QVector< QString > &vec)
double mScaleLogBaseLogInv
QColor mSelectedLabelColor
void setAutoTickStep(bool on)
void setSelectedTickLabelColor(const QColor &color)
QCPLineEnding upperEnding() const
AxisType axisType() const
void selectableChanged(const QCPAxis::SelectableParts &parts)
static AxisType opposite(AxisType type)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void setAutoTickLabels(bool on)
double basePow(double value) const
QPen getSubTickPen() const
Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts)
void setSubTickLength(int inside, int outside=0)
SelectableParts mSelectableParts
bool rangeReversed() const
Qt::Orientation orientation() const
@ spAxis
The axis backbone and tick marks.
@ spAxisLabel
The axis label.
@ spNone
None of the selectable parts.
static AxisType marginSideToAxisType(QCP::MarginSide side)
const QCPRange range() const
void setSubTickLengthIn(int inside)
QList< QCPAbstractPlottable * > plottables() const
QCPAxis(QCPAxisRect *parent, AxisType type)
int subTickLengthOut() const
QVector< QString > mTickVectorLabels
virtual int calculateAutoSubTickCount(double tickStep) const
void setRangeUpper(double upper)
ScaleType scaleType() const
int tickLengthOut() const
QList< QCPGraph * > graphs() const
void setTickPen(const QPen &pen)
void setAutoSubTicks(bool on)
Q_SLOT void setScaleType(QCPAxis::ScaleType type)
bool autoSubTicks() const
void setNumberFormat(const QString &formatCode)
double baseLog(double value) const
void setAutoTicks(bool on)
QColor getLabelColor() const
Qt::TimeSpec dateTimeSpec() const
QFont getLabelFont() const
void setSelectedBasePen(const QPen &pen)
Q_SLOT void setRange(const QCPRange &range)
void visibleTickBounds(int &lowIndex, int &highIndex) const
void setSubTickPen(const QPen &pen)
bool mNumberBeautifulPowers
double coordToPixel(double value) const
void setTickLabelPadding(int padding)
void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0)
void setTickStep(double step)
Qt::TimeSpec mDateTimeSpec
int subTickLengthIn() const
int tickLabelPadding() const
void setTickLengthIn(int inside)
QCPAxisRect * axisRect() const
void setRangeLower(double lower)
Holds the data of one single data point (one bar) for QCPBars.
Groups multiple QCPBars together so they appear side by side.
double getPixelSpacing(const QCPBars *bars, double keyCoord)
void remove(QCPBars *bars)
void setSpacingType(SpacingType spacingType)
void insert(int i, QCPBars *bars)
@ stAbsolute
Bar spacing is in absolute pixels.
QList< QCPBars * > bars() const
void registerBars(QCPBars *bars)
void append(QCPBars *bars)
SpacingType spacingType() const
double keyPixelOffset(const QCPBars *bars, double keyCoord)
QCPBarsGroup(QCustomPlot *parentPlot)
void setSpacing(double spacing)
void unregisterBars(QCPBars *bars)
A plottable representing a bar chart in a plot.
double getStackedBaseValue(double key, bool positive) const
QCPBars * barBelow() const
void removeData(double fromKey, double toKey)
void addData(const QVector< double > &keys, const QVector< double > &values, bool alreadySorted=false)
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
QPolygonF getBarPolygon(double key, double value) const
virtual void draw(QCPPainter *painter)
WidthType widthType() const
void setBaseValue(double baseValue)
QCPBarsGroup * barsGroup() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
@ wtAbsolute
Bar width is in absolute pixels.
QPointer< QCPBars > mBarAbove
void moveBelow(QCPBars *bars)
void setData(QSharedPointer< QCPBarsDataContainer > data)
static void connectBars(QCPBars *lower, QCPBars *upper)
QSharedPointer< QCPBarsDataContainer > data() const
void removeDataAfter(double key)
void removeDataBefore(double key)
QCPBarsGroup * mBarsGroup
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
void moveAbove(QCPBars *bars)
void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
QPointer< QCPBars > mBarBelow
void getPixelWidth(double key, double &lower, double &upper) const
void setWidthType(WidthType widthType)
void setBarsGroup(QCPBarsGroup *barsGroup)
void setWidth(double width)
Defines a color gradient for use with e.g. QCPColorMap.
ColorInterpolation mColorInterpolation
QRgb color(double position, const QCPRange &range, bool logarithmic=false)
void setLevelCount(int n)
void setPeriodic(bool enabled)
void setColorStopAt(double position, const QColor &color)
void setColorStops(const QMap< double, QColor > &colorStops)
bool operator==(const QCPColorGradient &other) const
QMap< double, QColor > mColorStops
QCPColorGradient inverted() const
void loadPreset(GradientPreset preset)
void setColorInterpolation(ColorInterpolation interpolation)
QMap< double, QColor > colorStops() const
void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false)
bool mColorBufferInvalidated
@ ciRGB
Color channels red, green and blue are linearly interpolated.
QVector< QRgb > mColorBuffer
@ gpCandy
Blue over pink to white.
Holds the two-dimensional data of a QCPColorMap plottable.
void setKeyRange(const QCPRange &keyRange)
void setValueSize(int valueSize)
void setSize(int keySize, int valueSize)
QCPRange keyRange() const
double data(double key, double value)
QCPRange valueRange() const
void setCell(int keyIndex, int valueIndex, double z)
QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange)
void setRange(const QCPRange &keyRange, const QCPRange &valueRange)
void recalculateDataBounds()
QCPRange dataBounds() const
void setKeySize(int keySize)
void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const
void setValueRange(const QCPRange &valueRange)
void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const
double cell(int keyIndex, int valueIndex)
void setData(double key, double value, double z)
QCPColorMapData & operator=(const QCPColorMapData &other)
A plottable representing a two-dimensional color map in a plot.
QCPColorMapData * data() const
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
QCPColorMapData * mMapData
void gradientChanged(const QCPColorGradient &newGradient)
virtual void draw(QCPPainter *painter)
QPointer< QCPColorScale > mColorScale
void setInterpolate(bool enabled)
void setData(QCPColorMapData *data, bool copy=false)
Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18))
virtual void updateMapImage()
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
Q_SLOT void setGradient(const QCPColorGradient &gradient)
void dataRangeChanged(const QCPRange &newRange)
void rescaleDataRange(bool recalculateDataBounds=false)
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
Q_SLOT void setDataRange(const QCPRange &dataRange)
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
QCPColorScale * colorScale() const
QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setColorScale(QCPColorScale *colorScale)
QCPColorGradient mGradient
QCPAxis::ScaleType mDataScaleType
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
bool mMapImageInvalidated
QImage mUndersampledMapImage
QCPColorGradient gradient() const
void setTightBoundary(bool enabled)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
QCPRange dataRange() const
A color scale for use with color coding data such as QCPColorMap.
void setType(QCPAxis::AxisType type)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
void setRangeDrag(bool enabled)
QCPAxis::ScaleType mDataScaleType
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details)
QCPColorGradient gradient() const
void rescaleDataRange(bool onlyVisibleMaps)
QCPRange dataRange() const
QList< QCPColorMap * > colorMaps() const
QPointer< QCPColorScaleAxisRectPrivate > mAxisRect
void gradientChanged(const QCPColorGradient &newGradient)
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
void dataRangeChanged(const QCPRange &newRange)
QCPAxis::AxisType type() const
void setRangeZoom(bool enabled)
QPointer< QCPAxis > mColorAxis
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
QCPColorScale(QCustomPlot *parentPlot)
virtual void wheelEvent(QWheelEvent *event)
virtual void update(UpdatePhase phase)
void setBarWidth(int width)
Q_SLOT void setDataRange(const QCPRange &dataRange)
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QCPColorGradient mGradient
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
void setLabel(const QString &str)
Holds the data of one single data point for QCPCurve.
void removeDataAfter(double t)
QCPScatterStyle mScatterStyle
virtual void drawScatterPlot(QCPPainter *painter, const QVector< QPointF > &points, const QCPScatterStyle &style) const
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
virtual void draw(QCPPainter *painter)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
@ lsNone
No line is drawn between data points (e.g. only scatters)
QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis)
void getCurveData(QVector< QPointF > *lineData) const
void setData(QSharedPointer< QCPCurveDataContainer > data)
void setLineStyle(LineStyle style)
void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector< QPointF > &beforeTraverse, QVector< QPointF > &afterTraverse) const
void setScatterStyle(const QCPScatterStyle &style)
QVector< QPointF > getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
void addData(const QVector< double > &t, const QVector< double > &keys, const QVector< double > &values, bool alreadySorted=false)
QSharedPointer< QCPCurveDataContainer > data() const
int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void removeData(double fromt, double tot)
bool mayTraverse(int prevRegion, int currentRegion) const
void removeDataBefore(double t)
bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const
Holds the data of one single data point for QCPGraph.
Holds the data of one single data point for QCPFinancial.
void removeData(double fromKey, double toKey)
void removeDataBefore(double key)
static QCPFinancialDataContainer timeSeriesToOhlc(const QVector< double > &time, const QVector< double > &value, double timeBinSize, double timeBinOffset=0)
@ csOhlc
Open-High-Low-Close bar representation.
@ csCandlestick
Candlestick representation.
void setTwoColored(bool twoColored)
double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const
void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected)
void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const
void addData(const QVector< double > &keys, const QVector< double > &open, const QVector< double > &high, const QVector< double > &low, const QVector< double > &close, bool alreadySorted=false)
QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
QCPFinancialDataMap * mData
QSharedPointer< QCPFinancialDataContainer > data() const
void setChartStyle(ChartStyle style)
void setBrushPositive(const QBrush &brush)
void setData(QSharedPointer< QCPFinancialDataContainer > data)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
void setBrushNegative(const QBrush &brush)
double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const
void setWidth(double width)
void removeDataAfter(double key)
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
void setPenPositive(const QPen &pen)
virtual void draw(QCPPainter *painter)
void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected)
void setPenNegative(const QPen &pen)
A plottable representing a graph in a plot.
QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setErrorBarSize(double size)
void setScatterStyle(const QCPScatterStyle &style)
void rescaleAxes(bool onlyEnlarge=false) const
void setData(QSharedPointer< QCPGraphDataContainer > data)
ErrorType errorType() const
virtual void drawImpulsePlot(QCPPainter *painter, const QVector< QPointF > &lines) const
QPointer< QCPGraph > mChannelFillGraph
void setChannelFillGraph(QCPGraph *targetGraph)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void removeData(double fromKey, double toKey)
QCPScatterStyle mScatterStyle
virtual void drawLinePlot(QCPPainter *painter, const QVector< QPointF > &lines) const
void setLineStyle(LineStyle ls)
void getStepRightPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
int findIndexBelowY(const QVector< QPointF > *data, double y) const
void getPlotData(QVector< QPointF > *lineData, QVector< QCPData > *scatterData) const
virtual void draw(QCPPainter *painter)
virtual void drawFill(QCPPainter *painter, QVector< QPointF > *lines) const
void getScatterPlotData(QVector< QCPData > *scatterData) const
void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const
void getLinePlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
QPointF upperFillBasePoint(double upperKey) const
void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const
void setDataBothError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError, const QVector< double > &valueError)
double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const
int findIndexAboveY(const QVector< QPointF > *data, double y) const
int findIndexBelowX(const QVector< QPointF > *data, double x) const
void addFillBasePoints(QVector< QPointF > *lineData) const
void getStepLeftPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
const QPolygonF getChannelFillPolygon(const QVector< QPointF > *lineData, QCPDataRange thisSegment, const QVector< QPointF > *otherData, QCPDataRange otherSegment) const
void removeDataBefore(double key)
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
int findIndexAboveX(const QVector< QPointF > *data, double x) const
void getImpulsePlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
void setErrorBarSkipSymbol(bool enabled)
void setAdaptiveSampling(bool enabled)
void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const
void getStepCenterPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
void setDataKeyError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError)
void setErrorPen(const QPen &pen)
virtual void drawScatterPlot(QCPPainter *painter, const QVector< QPointF > &scatters, const QCPScatterStyle &style) const
void setErrorType(ErrorType errorType)
void setDataValueError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &valueError)
QSharedPointer< QCPGraphDataContainer > data() const
QPointF lowerFillBasePoint(double lowerKey) const
@ etKey
Error bars for the key dimension of the data point are shown.
@ etNone
No error bars are shown.
@ lsLine
data points are connected by a straight line
void addData(const QVector< double > &keys, const QVector< double > &values, bool alreadySorted=false)
int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const
void removeDataAfter(double key)
void getPreparedData(QVector< QCPData > *lineData, QVector< QCPData > *scatterData) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void rescaleKeyAxis(bool onlyEnlarge=false) const
void removeFillBasePoints(QVector< QPointF > *lineData) const
Responsible for drawing the grid of a QCPAxis.
void setZeroLinePen(const QPen &pen)
void setAntialiasedZeroLine(bool enabled)
void setAntialiasedSubGrid(bool enabled)
void drawSubGridLines(QCPPainter *painter) const
bool mAntialiasedZeroLine
void setSubGridPen(const QPen &pen)
void setPen(const QPen &pen)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QCPGrid(QCPAxis *parentAxis)
virtual void draw(QCPPainter *painter)
void setSubGridVisible(bool visible)
void drawGridLines(QCPPainter *painter) const
An anchor of an item to which positions can be attached to.
void removeChildX(QCPItemPosition *pos)
QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1)
QCPAbstractItem * mParentItem
QSet< QCPItemPosition * > mChildrenY
QCustomPlot * mParentPlot
friend class QCPItemPosition
void removeChildY(QCPItemPosition *pos)
virtual QCPItemPosition * toQCPItemPosition()
virtual QPointF pixelPoint() const
QSet< QCPItemPosition * > mChildrenX
void addChildX(QCPItemPosition *pos)
void addChildY(QCPItemPosition *pos)
void setSelectedPen(const QPen &pen)
QCPItemBracket(QCustomPlot *parentPlot)
virtual QPointF anchorPixelPoint(int anchorId) const
BracketStyle style() const
void setStyle(BracketStyle style)
QCPItemPosition *const left
@ bsSquare
A brace with angled edges.
@ bsRound
A brace with round edges.
virtual void draw(QCPPainter *painter)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setPen(const QPen &pen)
QCPItemPosition *const right
void setLength(double length)
virtual ~QCPItemBracket()
QCPItemPosition *const startDir
void setPen(const QPen &pen)
QCPItemPosition *const start
void setHead(const QCPLineEnding &head)
QCPItemPosition *const end
void setSelectedPen(const QPen &pen)
virtual void draw(QCPPainter *painter)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPLineEnding head() const
QCPItemPosition *const endDir
QCPLineEnding tail() const
void setTail(const QCPLineEnding &tail)
QCPItemCurve(QCustomPlot *parentPlot)
QCPItemPosition *const bottomRight
QCPItemPosition *const topLeft
virtual ~QCPItemEllipse()
void setBrush(const QBrush &brush)
void setSelectedPen(const QPen &pen)
QCPItemEllipse(QCustomPlot *parentPlot)
void setSelectedBrush(const QBrush &brush)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPItemAnchor *const center
virtual QPointF anchorPixelPoint(int anchorId) const
void setPen(const QPen &pen)
virtual void draw(QCPPainter *painter)
QCPItemLine(QCustomPlot *parentPlot)
virtual void draw(QCPPainter *painter)
QCPItemPosition *const start
void setSelectedPen(const QPen &pen)
QCPItemPosition *const end
void setPen(const QPen &pen)
QCPLineEnding head() const
QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const
QCPLineEnding tail() const
void setTail(const QCPLineEnding &tail)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setHead(const QCPLineEnding &head)
QCPItemPosition *const bottomRight
virtual QPointF anchorPixelPoint(int anchorId) const
QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const
Qt::AspectRatioMode aspectRatioMode() const
QCPItemAnchor *const left
void setPixmap(const QPixmap &pixmap)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void draw(QCPPainter *painter)
QCPItemAnchor *const right
void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false)
Qt::AspectRatioMode mAspectRatioMode
QCPItemPixmap(QCustomPlot *parentPlot)
void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation)
Qt::TransformationMode transformationMode() const
Qt::TransformationMode mTransformationMode
void setPen(const QPen &pen)
QCPItemPosition *const topLeft
void setSelectedPen(const QPen &pen)
Manages the position of an item.
QCPItemAnchor * mParentAnchorX
QCPItemAnchor * parentAnchor() const
void setAxisRect(QCPAxisRect *axisRect)
void setTypeX(PositionType type)
void setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis)
QPointer< QCPAxis > mKeyAxis
QCPAxis * valueAxis() const
PositionType mPositionTypeY
QPointer< QCPAxis > mValueAxis
QCPItemAnchor * parentAnchorX() const
QPointer< QCPAxisRect > mAxisRect
virtual QPointF pixelPoint() const
QCPAxis * keyAxis() const
QCPItemAnchor * parentAnchorY() const
void setType(PositionType type)
void setCoords(double key, double value)
void setPixelPoint(const QPointF &pixelPoint)
PositionType type() const
bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
void setTypeY(PositionType type)
virtual ~QCPItemPosition()
bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
PositionType mPositionTypeX
QCPAxisRect * axisRect() const
QCPItemAnchor * mParentAnchorY
virtual void draw(QCPPainter *painter)
QCPItemRect(QCustomPlot *parentPlot)
void setPen(const QPen &pen)
void setSelectedPen(const QPen &pen)
QCPItemPosition *const bottomRight
QCPItemPosition *const topLeft
void setBrush(const QBrush &brush)
void setSelectedBrush(const QBrush &brush)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QPointF anchorPixelPoint(int anchorId) const
double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual ~QCPItemStraightLine()
virtual void draw(QCPPainter *painter)
QCPItemPosition *const point1
QCPItemStraightLine(QCustomPlot *parentPlot)
void setSelectedPen(const QPen &pen)
QCPItemPosition *const point2
void setPen(const QPen &pen)
QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, const QRect &rect) const
void setSelectedFont(const QFont &font)
Qt::Alignment positionAlignment() const
void setBrush(const QBrush &brush)
QCPItemPosition *const position
void setSelectedPen(const QPen &pen)
void setText(const QString &text)
virtual QPointF anchorPixelPoint(int anchorId) const
void setRotation(double degrees)
QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const
void setSelectedBrush(const QBrush &brush)
QCPItemAnchor *const bottomRight
Qt::Alignment mPositionAlignment
QCPItemText(QCustomPlot *parentPlot)
void setPositionAlignment(Qt::Alignment alignment)
virtual void draw(QCPPainter *painter)
void setFont(const QFont &font)
void setPen(const QPen &pen)
QCPItemAnchor *const topLeft
void setColor(const QColor &color)
void setTextAlignment(Qt::Alignment alignment)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Qt::Alignment mTextAlignment
void setSelectedColor(const QColor &color)
void setPadding(const QMargins &padding)
void setSelectedBrush(const QBrush &brush)
void setBrush(const QBrush &brush)
@ tsPlus
A plus shaped crosshair with limited size.
@ tsNone
The tracer is not visible.
void setStyle(TracerStyle style)
void setGraphKey(double key)
void setInterpolating(bool enabled)
virtual void draw(QCPPainter *painter)
QCPItemTracer(QCustomPlot *parentPlot)
void setSelectedPen(const QPen &pen)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setSize(double size)
QCPItemPosition *const position
void setGraph(QCPGraph *graph)
void setPen(const QPen &pen)
TracerStyle style() const
A layer that may contain objects, to control the rendering order.
QList< QCPLayerable * > mChildren
QList< QCPLayerable * > children() const
QCustomPlot * parentPlot() const
void addChild(QCPLayerable *layerable, bool prepend)
QCPLayer(QCustomPlot *parentPlot, const QString &layerName)
QCustomPlot * mParentPlot
void setVisible(bool visible)
void removeChild(QCPLayerable *layerable)
Base class for all drawable objects.
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const =0
QCustomPlot * mParentPlot
QCustomPlot * parentPlot() const
void setAntialiased(bool enabled)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0)
void initializeParentPlot(QCustomPlot *parentPlot)
virtual QCP::Interaction selectionCategory() const
void setParentLayerable(QCPLayerable *parentLayerable)
QCPLayerable * parentLayerable() const
bool realVisibility() const
Q_SLOT bool setLayer(QCPLayer *layer)
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
void layerChanged(QCPLayer *newLayer)
void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const
virtual QRect clipRect() const
virtual void draw(QCPPainter *painter)=0
virtual void deselectEvent(bool *selectionStateChanged)
QPointer< QCPLayerable > mParentLayerable
bool moveToLayer(QCPLayer *layer, bool prepend)
The abstract base class for all objects that form the layout system.
virtual int calculateAutoMargin(QCP::MarginSide side)
void setMinimumMargins(const QMargins &margins)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
@ upMargins
Phase in which the margins are calculated and set.
virtual ~QCPLayoutElement()
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
QHash< QCP::MarginSide, QCPMarginGroup * > mMarginGroups
virtual void wheelEvent(QWheelEvent *event)
void setOuterRect(const QRect &rect)
QCPLayout * layout() const
void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group)
void setMinimumSize(const QSize &size)
void setMaximumSize(const QSize &size)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
QCPLayoutElement(QCustomPlot *parentPlot=0)
QCPMarginGroup * marginGroup(QCP::MarginSide side) const
void setMargins(const QMargins &margins)
virtual void update(UpdatePhase phase)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
virtual QSize minimumSizeHint() const
virtual QSize maximumSizeHint() const
QCPLayout * mParentLayout
void setAutoMargins(QCP::MarginSides sides)
QCP::MarginSides mAutoMargins
A layout that arranges child elements in a grid.
virtual void updateLayout()
void insertColumn(int newIndex)
void setRowStretchFactors(const QList< double > &factors)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
virtual QSize maximumSizeHint() const
void setColumnSpacing(int pixels)
void insertRow(int newIndex)
void getMinimumRowColSizes(QVector< int > *minColWidths, QVector< int > *minRowHeights) const
QCPLayoutElement * element(int row, int column) const
virtual bool take(QCPLayoutElement *element)
void setColumnStretchFactors(const QList< double > &factors)
virtual int elementCount() const
void setRowStretchFactor(int row, double factor)
void expandTo(int newRowCount, int newColumnCount)
QList< QList< QCPLayoutElement * > > mElements
virtual QCPLayoutElement * elementAt(int index) const
void getMaximumRowColSizes(QVector< int > *maxColWidths, QVector< int > *maxRowHeights) const
virtual QSize minimumSizeHint() const
QList< double > mColumnStretchFactors
void setRowSpacing(int pixels)
bool hasElement(int row, int column)
virtual QCPLayoutElement * takeAt(int index)
bool addElement(int row, int column, QCPLayoutElement *element)
void setColumnStretchFactor(int column, double factor)
QList< double > mRowStretchFactors
A layout that places child elements aligned to the border or arbitrarily positioned.
virtual int elementCount() const
QList< QCPLayoutElement * > mElements
QList< InsetPlacement > mInsetPlacement
QList< Qt::Alignment > mInsetAlignment
Qt::Alignment insetAlignment(int index) const
void setInsetAlignment(int index, Qt::Alignment alignment)
void setInsetPlacement(int index, InsetPlacement placement)
InsetPlacement insetPlacement(int index) const
virtual void updateLayout()
virtual ~QCPLayoutInset()
virtual QCPLayoutElement * elementAt(int index) const
virtual bool take(QCPLayoutElement *element)
QList< QRectF > mInsetRect
void setInsetRect(int index, const QRectF &rect)
QRectF insetRect(int index) const
void addElement(QCPLayoutElement *element, Qt::Alignment alignment)
virtual QCPLayoutElement * takeAt(int index)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
The abstract base class for layouts.
virtual void updateLayout()
virtual void update(UpdatePhase phase)
virtual int elementCount() const =0
QVector< int > getSectionSizes(QVector< int > maxSizes, QVector< int > minSizes, QVector< double > stretchFactors, int totalSize) const
void releaseElement(QCPLayoutElement *el)
virtual QCPLayoutElement * takeAt(int index)=0
bool remove(QCPLayoutElement *element)
virtual bool take(QCPLayoutElement *element)=0
virtual QList< QCPLayoutElement * > elements(bool recursive) const
void sizeConstraintsChanged() const
void adoptElement(QCPLayoutElement *el)
virtual QCPLayoutElement * elementAt(int index) const =0
Manages a legend inside a QCustomPlot.
SelectableParts mSelectableParts
int iconTextPadding() const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QPen getBorderPen() const
Q_SLOT void setSelectedParts(const SelectableParts &selectedParts)
void setSelectedBorderPen(const QPen &pen)
void setIconBorderPen(const QPen &pen)
bool addItem(QCPAbstractLegendItem *item)
SelectableParts selectedParts() const
virtual void draw(QCPPainter *painter)
void setBrush(const QBrush &brush)
bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
virtual void deselectEvent(bool *selectionStateChanged)
@ spLegendBox
0x001 The legend box (frame)
QPen iconBorderPen() const
void setIconTextPadding(int padding)
QColor mSelectedTextColor
QPen mSelectedIconBorderPen
void setSelectedTextColor(const QColor &color)
void selectionChanged(QCPLegend::SelectableParts parts)
void setBorderPen(const QPen &pen)
void setSelectedBrush(const QBrush &brush)
void selectableChanged(QCPLegend::SelectableParts parts)
void setIconSize(const QSize &size)
virtual QCP::Interaction selectionCategory() const
SelectableParts mSelectedParts
QCPPlottableLegendItem * itemWithPlottable(const QCPAbstractPlottable *plottable) const
Q_SLOT void setSelectableParts(const SelectableParts &selectableParts)
void setFont(const QFont &font)
void setSelectedFont(const QFont &font)
QList< QCPAbstractLegendItem * > selectedItems() const
bool removeItem(int index)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPAbstractLegendItem * item(int index) const
SelectableParts selectableParts() const
bool hasItem(QCPAbstractLegendItem *item) const
QPen selectedIconBorderPen() const
void setSelectedIconBorderPen(const QPen &pen)
void setTextColor(const QColor &color)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
Handles the different ending decorations for line-like items.
EndingStyle style() const
double boundingDistance() const
void setWidth(double width)
void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const
void setStyle(EndingStyle style)
void setInverted(bool inverted)
@ esDiamond
A filled diamond (45 degrees rotated square)
@ esBar
A bar perpendicular to the line.
@ esNone
No ending decoration.
@ esLineArrow
A non-filled arrow head with open back.
@ esSpikeArrow
A filled arrow head with an indented back.
@ esSquare
A filled square.
double realLength() const
void setLength(double length)
A margin group allows synchronization of margin sides if working with multiple layout elements.
void removeChild(QCP::MarginSide side, QCPLayoutElement *element)
QList< QCPLayoutElement * > elements(QCP::MarginSide side) const
QHash< QCP::MarginSide, QList< QCPLayoutElement * > > mChildren
virtual ~QCPMarginGroup()
QCPMarginGroup(QCustomPlot *parentPlot)
void addChild(QCP::MarginSide side, QCPLayoutElement *element)
virtual int commonMargin(QCP::MarginSide side) const
QPainter subclass used internally.
bool begin(QPaintDevice *device)
void drawLine(const QLineF &line)
QStack< bool > mAntialiasingStack
bool antialiasing() const
void setModes(PainterModes modes)
void setAntialiasing(bool enabled)
PainterModes modes() const
void setMode(PainterMode mode, bool enabled=true)
void setPen(const QPen &pen)
A layout element displaying a plot title text.
void setSelectedTextColor(const QColor &color)
void setFont(const QFont &font)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void selectionChanged(bool selected)
void setSelectedFont(const QFont &font)
void selectableChanged(bool selectable)
void setTextColor(const QColor &color)
Q_SLOT void setSelectable(bool selectable)
QColor mSelectedTextColor
Q_SLOT void setSelected(bool selected)
QCPPlotTitle(QCustomPlot *parentPlot)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setText(const QString &text)
QColor mainTextColor() const
virtual void deselectEvent(bool *selectionStateChanged)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
virtual QSize maximumSizeHint() const
virtual void draw(QCPPainter *painter)
virtual QSize minimumSizeHint() const
A legend item representing a plottable with an icon and the plottable name.
virtual QSize minimumSizeHint() const
QColor getTextColor() const
virtual void draw(QCPPainter *painter)
QCPAbstractPlottable * mPlottable
QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable)
QPen getIconBorderPen() const
Represents the range an axis is encompassing.
void expand(const QCPRange &otherRange)
static const double maxRange
QCPRange sanitizedForLogScale() const
QCPRange sanitizedForLinScale() const
static const double minRange
QCPRange expanded(const QCPRange &otherRange) const
static bool validRange(double lower, double upper)
bool contains(double value) const
Represents the visual appearance of scatter points.
void setPixmap(const QPixmap &pixmap)
void setBrush(const QBrush &brush)
void setPen(const QPen &pen)
void setShape(ScatterShape shape)
void drawShape(QCPPainter *painter, const QPointF &pos) const
void setCustomPath(const QPainterPath &customPath)
void setSize(double size)
@ ssPlus
\enumimage{ssPlus.png} a plus
@ ssCircle
\enumimage{ssCircle.png} a circle
@ ssSquare
\enumimage{ssSquare.png} a square
@ ssCross
\enumimage{ssCross.png} a cross
@ ssDiamond
\enumimage{ssDiamond.png} a diamond
QPainterPath customPath() const
ScatterShape shape() const
void applyTo(QCPPainter *painter, const QPen &defaultPen) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const
void setData(QSharedPointer< QCPStatisticalBoxDataContainer > data)
void setWidth(double width)
QVector< double > mOutliers
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void setWhiskerPen(const QPen &pen)
virtual void drawMedian(QCPPainter *painter) const
void setMedian(double value)
void setUpperQuartile(double value)
void setLowerQuartile(double value)
virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=0) const
void setMedianPen(const QPen &pen)
virtual void draw(QCPPainter *painter)
QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setMinimum(double value)
virtual void drawOutliers(QCPPainter *painter) const
void setWhiskerBarPen(const QPen &pen)
void setMaximum(double value)
virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const
void setOutlierStyle(const QCPScatterStyle &style)
void setWhiskerWidth(double width)
QCPScatterStyle mOutlierStyle
virtual void drawWhiskers(QCPPainter *painter) const
void setOutliers(const QVector< double > &values)
double lowerQuartile() const
double upperQuartile() const
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
QCPLayer * currentLayer() const
void drawBackground(QCPPainter *painter)
QPixmap mScaledBackgroundPixmap
QCPLayer * layer(const QString &name) const
Qt::KeyboardModifier mMultiSelectModifier
virtual QSize minimumSizeHint() const
QCPLayerable * layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const
QList< QCPGraph * > mGraphs
QList< QCPAxisRect * > axisRects() const
QCPAbstractItem * item() const
void setBackground(const QPixmap &pm)
virtual void resizeEvent(QResizeEvent *event)
void toPainter(QCPPainter *painter, int width=0, int height=0)
void titleClick(QMouseEvent *event, QCPPlotTitle *title)
QCP::AntialiasedElements mNotAntialiasedElements
virtual void paintEvent(QPaintEvent *event)
const QCP::Interactions interactions() const
QPointer< QCPLayoutElement > mMouseEventElement
QCPAbstractPlottable * plottable(int index)
void setBackgroundScaled(bool scaled)
void setPlottingHint(QCP::PlottingHint hint, bool enabled=true)
void setViewport(const QRect &rect)
bool removeLayer(QCPLayer *layer)
void setInteraction(const QCP::Interaction &interaction, bool enabled=true)
QCustomPlot(QWidget *parent=0)
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
void setSelectionTolerance(int pixels)
void selectionChangedByUser()
virtual QSize sizeHint() const
int selectionTolerance() const
void setInteractions(const QCP::Interactions &interactions)
int plottableCount() const
QCP::AntialiasedElements antialiasedElements() const
void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
QCPGraph * addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0)
virtual void mouseReleaseEvent(QMouseEvent *event)
bool hasPlottable(QCPAbstractPlottable *plottable) const
bool setCurrentLayer(const QString &name)
void mouseMove(QMouseEvent *event)
QList< QCPAbstractPlottable * > selectedPlottables() const
QCP::AntialiasedElements notAntialiasedElements() const
@ limAbove
Layer is inserted above other layer.
bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
void setNoAntialiasingOnDrag(bool enabled)
QList< QCPAbstractItem * > mItems
void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
virtual void wheelEvent(QWheelEvent *event)
QList< QCPAxis * > selectedAxes() const
void updateLayerIndices() const
void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event)
virtual void axisRemoved(QCPAxis *axis)
int axisRectCount() const
void setMultiSelectModifier(Qt::KeyboardModifier modifier)
bool removeGraph(QCPGraph *graph)
void setPlottingHints(const QCP::PlottingHints &hints)
void mouseDoubleClick(QMouseEvent *event)
virtual void legendRemoved(QCPLegend *legend)
Q_SLOT void deselectAll()
QCP::PlottingHints mPlottingHints
QCP::AntialiasedElements mAntialiasedElements
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint)
bool addItem(QCPAbstractItem *item)
QPixmap toPixmap(int width=0, int height=0, double scale=1.0)
QList< QCPAbstractPlottable * > mPlottables
bool mAutoAddPlottableToLegend
bool addPlottable(QCPAbstractPlottable *plottable)
Qt::AspectRatioMode mBackgroundScaledMode
QCPLayoutGrid * mPlotLayout
virtual void mousePressEvent(QMouseEvent *event)
void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
QCPAbstractItem * itemAt(const QPointF &pos, bool onlySelectable=false) const
virtual void mouseMoveEvent(QMouseEvent *event)
QCP::PlottingHints plottingHints() const
void mouseWheel(QWheelEvent *event)
void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event)
bool mNoAntialiasingOnDrag
QList< QCPLegend * > selectedLegends() const
void mouseRelease(QMouseEvent *event)
bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
bool noAntialiasingOnDrag() const
void mousePress(QMouseEvent *event)
QCPAbstractPlottable * plottableAt(const QPointF &pos, bool onlySelectable=false) const
QList< QCPLayer * > mLayers
QList< QCPGraph * > selectedGraphs() const
void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title)
bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove)
bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString())
QCP::Interactions mInteractions
bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
virtual void draw(QCPPainter *painter)
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false)
void setAutoAddPlottableToLegend(bool on)
QCPAbstractPlottable * plottable()
bool removeItem(QCPAbstractItem *item)
void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements)
void itemClick(QCPAbstractItem *item, QMouseEvent *event)
bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch)
QCPAxisRect * axisRect(int index=0) const
bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove)
QPixmap mBackgroundPixmap
void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true)
bool hasItem(QCPAbstractItem *item) const
bool removePlottable(QCPAbstractPlottable *plottable)
void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event)
void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements)
QCPLayoutElement * layoutElementAt(const QPointF &pos) const
void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true)
QList< QCPAbstractItem * > selectedItems() const
bool isInvalidData(double value)
int getMarginValue(const QMargins &margins, QCP::MarginSide side)
@ msRight
0x02 right margin
@ msBottom
0x08 bottom margin
@ aeAxes
0x0001 Axis base line and tick marks
@ aeItems
0x0040 Main lines of items
@ aeLegendItems
0x0010 Legend items
@ aeErrorBars
0x0100 Error bars
@ aePlottables
0x0020 Main lines of plottables
@ aeNone
0x0000 No elements
@ aeSubGrid
0x0004 Sub grid lines
@ aeAll
0xFFFF All elements
@ aeGrid
0x0002 Grid lines
@ aeLegend
0x0008 Legend box
void setMarginValue(QMargins &margins, QCP::MarginSide side, int value)
bool setColor(ccHObject::Container selectedEntities, bool colorize, QWidget *parent)
static const std::string path
MiniVec< float, N > floor(const MiniVec< float, N > &a)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
constexpr Rgb black(0, 0, 0)
constexpr Rgb white(MAX, MAX, MAX)
constexpr Rgb blue(0, 0, MAX)