53 mIsAntialiasing(false)
70 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. 72 setRenderHint(QPainter::NonCosmeticDefaultPen);
88 QPainter::setPen(pen);
102 QPainter::setPen(color);
116 QPainter::setPen(penStyle);
132 QPainter::drawLine(line);
134 QPainter::drawLine(line.toLine());
145 setRenderHint(QPainter::Antialiasing, enabled);
154 translate(-0.5, -0.5);
182 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) // before Qt5, default pens used to be cosmetic if NonCosmeticDefaultPen flag isn't set. So we set it to get consistency across Qt versions. 184 setRenderHint(QPainter::NonCosmeticDefaultPen);
196 if (!enabled &&
mModes.testFlag(mode))
198 else if (enabled && !
mModes.testFlag(mode))
229 qDebug() << Q_FUNC_INFO <<
"Unbalanced save/restore";
239 if (qFuzzyIsNull(pen().widthF()))
523 painter->setBrush(
mBrush);
544 double w =
mSize/2.0;
550 painter->
drawLine(QPointF(x, y), QPointF(x+0.0001, y));
555 painter->
drawLine(QLineF(x-w, y-w, x+w, y+w));
556 painter->
drawLine(QLineF(x-w, y+w, x+w, y-w));
561 painter->
drawLine(QLineF(x-w, y, x+w, y));
562 painter->
drawLine(QLineF( x, y+w, x, y-w));
567 painter->drawEllipse(QPointF(x , y), w, w);
572 QBrush b = painter->brush();
573 painter->setBrush(painter->pen().color());
574 painter->drawEllipse(QPointF(x , y), w, w);
575 painter->setBrush(b);
580 painter->drawRect(QRectF(x-w, y-w,
mSize,
mSize));
585 painter->
drawLine(QLineF(x-w, y, x, y-w));
586 painter->
drawLine(QLineF( x, y-w, x+w, y));
587 painter->
drawLine(QLineF(x+w, y, x, y+w));
588 painter->
drawLine(QLineF( x, y+w, x-w, y));
593 painter->
drawLine(QLineF(x-w, y, x+w, y));
594 painter->
drawLine(QLineF( x, y+w, x, y-w));
595 painter->
drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707));
596 painter->
drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707));
601 painter->
drawLine(QLineF(x-w, y+0.755*w, x+w, y+0.755*w));
602 painter->
drawLine(QLineF(x+w, y+0.755*w, x, y-0.977*w));
603 painter->
drawLine(QLineF( x, y-0.977*w, x-w, y+0.755*w));
608 painter->
drawLine(QLineF(x-w, y-0.755*w, x+w, y-0.755*w));
609 painter->
drawLine(QLineF(x+w, y-0.755*w, x, y+0.977*w));
610 painter->
drawLine(QLineF( x, y+0.977*w, x-w, y-0.755*w));
615 painter->
drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95));
616 painter->
drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w));
617 painter->drawRect(QRectF(x-w, y-w,
mSize,
mSize));
622 painter->
drawLine(QLineF(x-w, y, x+w*0.95, y));
623 painter->
drawLine(QLineF( x, y+w, x, y-w));
624 painter->drawRect(QRectF(x-w, y-w,
mSize,
mSize));
629 painter->
drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.670, y+w*0.670));
630 painter->
drawLine(QLineF(x-w*0.707, y+w*0.670, x+w*0.670, y-w*0.707));
631 painter->drawEllipse(QPointF(x, y), w, w);
636 painter->
drawLine(QLineF(x-w, y, x+w, y));
637 painter->
drawLine(QLineF( x, y+w, x, y-w));
638 painter->drawEllipse(QPointF(x, y), w, w);
643 painter->
drawLine(QLineF(x, y-w, x, y+w));
644 painter->
drawLine(QLineF(x, y, x-w*0.707, y+w*0.707));
645 painter->
drawLine(QLineF(x, y, x+w*0.707, y+w*0.707));
646 painter->drawEllipse(QPointF(x, y), w, w);
656 QTransform oldTransform = painter->transform();
657 painter->translate(x, y);
660 painter->setTransform(oldTransform);
741 mParentPlot(parentPlot),
761 qDebug() << Q_FUNC_INFO <<
"The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or 0 beforehand.";
796 qDebug() << Q_FUNC_INFO <<
"layerable is already child of this layer" <<
reinterpret_cast<quintptr
>(layerable);
811 qDebug() << Q_FUNC_INFO <<
"layerable is not child of this layer" <<
reinterpret_cast<quintptr
>(layerable);
924 mParentLayerable(parentLayerable),
930 if (targetLayer.isEmpty())
933 qDebug() << Q_FUNC_INFO <<
"setting QCPlayerable initial layer to" << targetLayer <<
"failed.";
976 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
984 qDebug() << Q_FUNC_INFO <<
"there is no layer with name" << layerName;
1055 Q_UNUSED(onlySelectable)
1081 qDebug() << Q_FUNC_INFO <<
"called with mParentPlot already initialized";
1086 qDebug() << Q_FUNC_INFO <<
"called with parentPlot zero";
1120 qDebug() << Q_FUNC_INFO <<
"no parent QCustomPlot set";
1125 qDebug() << Q_FUNC_INFO <<
"layer" << layer->
name() <<
"is not in same QCustomPlot as this layerable";
1175 Q_UNUSED(parentPlot)
1244 Q_UNUSED(selectionStateChanged)
1261 Q_UNUSED(selectionStateChanged)
1366 result.
expand(otherRange);
1384 double rangeFac = 1e-3;
1389 if (sanitizedRange.
lower == 0.0 && sanitizedRange.
upper != 0.0)
1392 if (rangeFac < sanitizedRange.
upper*rangeFac)
1393 sanitizedRange.
lower = rangeFac;
1395 sanitizedRange.
lower = sanitizedRange.
upper*rangeFac;
1397 else if (sanitizedRange.
lower != 0.0 && sanitizedRange.
upper == 0.0)
1400 if (-rangeFac > sanitizedRange.
lower*rangeFac)
1401 sanitizedRange.
upper = -rangeFac;
1403 sanitizedRange.
upper = sanitizedRange.
lower*rangeFac;
1404 }
else if (sanitizedRange.
lower < 0 && sanitizedRange.
upper > 0)
1407 if (-sanitizedRange.
lower > sanitizedRange.
upper)
1410 if (-rangeFac > sanitizedRange.
lower*rangeFac)
1411 sanitizedRange.
upper = -rangeFac;
1413 sanitizedRange.
upper = sanitizedRange.
lower*rangeFac;
1417 if (rangeFac < sanitizedRange.
upper*rangeFac)
1418 sanitizedRange.
lower = rangeFac;
1420 sanitizedRange.
lower = sanitizedRange.
upper*rangeFac;
1424 return sanitizedRange;
1435 return sanitizedRange;
1544 QObject(parentPlot),
1545 mParentPlot(parentPlot)
1564 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement*> > it(
mChildren);
1565 while (it.hasNext())
1568 if (!it.value().isEmpty())
1581 QHashIterator<QCP::MarginSide, QList<QCPLayoutElement*> > it(
mChildren);
1582 while (it.hasNext())
1585 const QList<QCPLayoutElement*>
elements = it.value();
1586 for (
int i=elements.size()-1; i>=0; --i)
1587 elements.at(i)->setMarginGroup(it.key(), 0);
1606 for (
int i=0; i<elements.size(); ++i)
1608 if (!elements.at(i)->autoMargins().testFlag(side))
1610 int m = qMax(elements.at(i)->calculateAutoMargin(side),
QCP::getMarginValue(elements.at(i)->minimumMargins(), side));
1628 qDebug() << Q_FUNC_INFO <<
"element is already child of this margin group side" <<
reinterpret_cast<quintptr
>(element);
1639 if (!
mChildren[side].removeOne(element))
1640 qDebug() << Q_FUNC_INFO <<
"element is not child of this margin group side" <<
reinterpret_cast<quintptr
>(element);
1732 mMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX),
1734 mOuterRect(0, 0, 0, 0),
1735 mMargins(0, 0, 0, 0),
1736 mMinimumMargins(0, 0, 0, 0),
1885 QVector<QCP::MarginSide> sideVector;
1891 for (
int i=0; i<sideVector.size(); ++i)
1985 return QList<QCPLayoutElement*>();
2012 qDebug() << Q_FUNC_INFO <<
"parent plot not defined";
2145 const int elCount = elementCount();
2146 for (
int i=0; i<elCount; ++i)
2156 const int c = elementCount();
2157 QList<QCPLayoutElement*> result;
2158 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) 2161 for (
int i=0; i<c; ++i)
2162 result.append(elementAt(i));
2165 for (
int i=0; i<c; ++i)
2168 result << result.at(i)->elements(recursive);
2235 for (
int i=elementCount()-1; i>=0; --i)
2253 if (QWidget *w = qobject_cast<QWidget*>(parent()))
2254 w->updateGeometry();
2255 else if (
QCPLayout *l = qobject_cast<QCPLayout*>(parent()))
2256 l->sizeConstraintsChanged();
2294 el->setParent(
this);
2298 qDebug() << Q_FUNC_INFO <<
"Null element passed";
2320 qDebug() << Q_FUNC_INFO <<
"Null element passed";
2354 if (maxSizes.size() != minSizes.size() || minSizes.size() != stretchFactors.size())
2356 qDebug() << Q_FUNC_INFO <<
"Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors;
2357 return QVector<int>();
2359 if (stretchFactors.isEmpty())
2360 return QVector<int>();
2361 int sectionCount = stretchFactors.size();
2362 QVector<double> sectionSizes(sectionCount);
2365 for (
int i=0; i<sectionCount; ++i)
2366 minSizeSum += minSizes.at(i);
2367 if (totalSize < minSizeSum)
2370 for (
int i=0; i<sectionCount; ++i)
2372 stretchFactors[i] = minSizes.at(i);
2377 QList<int> minimumLockedSections;
2378 QList<int> unfinishedSections;
2379 for (
int i=0; i<sectionCount; ++i)
2380 unfinishedSections.append(i);
2381 double freeSize = totalSize;
2383 int outerIterations = 0;
2384 while (!unfinishedSections.isEmpty() && outerIterations < sectionCount*2)
2387 int innerIterations = 0;
2388 while (!unfinishedSections.isEmpty() && innerIterations < sectionCount*2)
2393 double nextMax = 1e12;
2394 for (
int i=0; i<unfinishedSections.size(); ++i)
2396 int secId = unfinishedSections.at(i);
2397 double hitsMaxAt = (maxSizes.at(secId)-sectionSizes.at(secId))/stretchFactors.at(secId);
2398 if (hitsMaxAt < nextMax)
2400 nextMax = hitsMaxAt;
2406 double stretchFactorSum = 0;
2407 for (
int i=0; i<unfinishedSections.size(); ++i)
2408 stretchFactorSum += stretchFactors.at(unfinishedSections.at(i));
2409 double nextMaxLimit = freeSize/stretchFactorSum;
2410 if (nextMax < nextMaxLimit)
2412 for (
int i=0; i<unfinishedSections.size(); ++i)
2414 sectionSizes[unfinishedSections.at(i)] += nextMax*stretchFactors.at(unfinishedSections.at(i));
2415 freeSize -= nextMax*stretchFactors.at(unfinishedSections.at(i));
2417 unfinishedSections.removeOne(nextId);
2420 for (
int i=0; i<unfinishedSections.size(); ++i)
2421 sectionSizes[unfinishedSections.at(i)] += nextMaxLimit*stretchFactors.at(unfinishedSections.at(i));
2422 unfinishedSections.clear();
2425 if (innerIterations == sectionCount*2)
2426 qDebug() << Q_FUNC_INFO <<
"Exceeded maximum expected inner iteration count, layouting aborted. Input was:" << maxSizes << minSizes << stretchFactors << totalSize;
2429 bool foundMinimumViolation =
false;
2430 for (
int i=0; i<sectionSizes.size(); ++i)
2432 if (minimumLockedSections.contains(i))
2434 if (sectionSizes.at(i) < minSizes.at(i))
2436 sectionSizes[i] = minSizes.at(i);
2437 foundMinimumViolation =
true;
2438 minimumLockedSections.append(i);
2441 if (foundMinimumViolation)
2443 freeSize = totalSize;
2444 for (
int i=0; i<sectionCount; ++i)
2446 if (!minimumLockedSections.contains(i))
2447 unfinishedSections.append(i);
2449 freeSize -= sectionSizes.at(i);
2452 for (
int i=0; i<unfinishedSections.size(); ++i)
2453 sectionSizes[unfinishedSections.at(i)] = 0;
2456 if (outerIterations == sectionCount*2)
2457 qDebug() << Q_FUNC_INFO <<
"Exceeded maximum expected outer iteration count, layouting aborted. Input was:" << maxSizes << minSizes << stretchFactors << totalSize;
2459 QVector<int> result(sectionCount);
2460 for (
int i=0; i<sectionCount; ++i)
2461 result[i] = qRound(sectionSizes.at(i));
2514 if (column >= 0 && column <
mElements.first().size())
2519 qDebug() << Q_FUNC_INFO <<
"Requested cell is empty. Row:" << row <<
"Column:" << column;
2521 qDebug() << Q_FUNC_INFO <<
"Invalid column. Row:" << row <<
"Column:" << column;
2523 qDebug() << Q_FUNC_INFO <<
"Invalid row. Row:" << row <<
"Column:" << column;
2573 qDebug() << Q_FUNC_INFO <<
"There is already an element in the specified row/column:" << row << column;
2575 qDebug() << Q_FUNC_INFO <<
"Can't add null element to row/column:" << row << column;
2611 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" << factor;
2613 qDebug() << Q_FUNC_INFO <<
"Invalid column:" << column;
2636 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" <<
mColumnStretchFactors.at(i);
2641 qDebug() << Q_FUNC_INFO <<
"Column count not equal to passed stretch factor count:" << factors;
2662 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" << factor;
2664 qDebug() << Q_FUNC_INFO <<
"Invalid row:" << row;
2687 qDebug() << Q_FUNC_INFO <<
"Invalid stretch factor, must be positive:" <<
mRowStretchFactors.at(i);
2692 qDebug() << Q_FUNC_INFO <<
"Row count not equal to passed stretch factor count:" << factors;
2734 mElements.append(QList<QCPLayoutElement*>());
2738 int newColCount = qMax(
columnCount(), newColumnCount);
2741 while (
mElements.at(i).size() < newColCount)
2768 QList<QCPLayoutElement*> newRow;
2794 for (
int row=0; row<
rowCount(); ++row)
2801 QVector<int> minColWidths, minRowHeights, maxColWidths, maxRowHeights;
2811 int yOffset =
mRect.top();
2812 for (
int row=0; row<
rowCount(); ++row)
2816 int xOffset =
mRect.left();
2822 mElements.at(row).at(col)->setOuterRect(QRect(xOffset, yOffset, colWidths.at(col), rowHeights.at(row)));
2852 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
2870 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
2872 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
2879 QList<QCPLayoutElement*> result;
2882 #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) 2883 result.reserve(colC*rowC);
2885 for (
int row=0; row<rowC; ++row)
2887 for (
int col=0; col<colC; ++col)
2889 result.append(
mElements.at(row).at(col));
2894 int c = result.size();
2895 for (
int i=0; i<c; ++i)
2898 result << result.at(i)->elements(recursive);
2910 for (
int row=
rowCount()-1; row>=0; --row)
2912 bool hasElements =
false;
2933 bool hasElements =
false;
2934 for (
int row=0; row<
rowCount(); ++row)
2945 for (
int row=0; row<
rowCount(); ++row)
2954 QVector<int> minColWidths, minRowHeights;
2957 for (
int i=0; i<minColWidths.size(); ++i)
2958 result.rwidth() += minColWidths.at(i);
2959 for (
int i=0; i<minRowHeights.size(); ++i)
2960 result.rheight() += minRowHeights.at(i);
2969 QVector<int> maxColWidths, maxRowHeights;
2973 for (
int i=0; i<maxColWidths.size(); ++i)
2974 result.setWidth(qMin(result.width()+maxColWidths.at(i), QWIDGETSIZE_MAX));
2975 for (
int i=0; i<maxRowHeights.size(); ++i)
2976 result.setHeight(qMin(result.height()+maxRowHeights.at(i), QWIDGETSIZE_MAX));
2997 *minRowHeights = QVector<int>(
rowCount(), 0);
2998 for (
int row=0; row<
rowCount(); ++row)
3004 QSize minHint =
mElements.at(row).at(col)->minimumSizeHint();
3005 QSize min =
mElements.at(row).at(col)->minimumSize();
3006 QSize
final(min.width() > 0 ? min.width() : minHint.width(), min.height() > 0 ? min.height() : minHint.height());
3007 if (minColWidths->at(col) <
final.width())
3008 (*minColWidths)[col] =
final.width();
3009 if (minRowHeights->at(row) <
final.height())
3010 (*minRowHeights)[row] =
final.height();
3030 *maxColWidths = QVector<int>(
columnCount(), QWIDGETSIZE_MAX);
3031 *maxRowHeights = QVector<int>(
rowCount(), QWIDGETSIZE_MAX);
3032 for (
int row=0; row<
rowCount(); ++row)
3038 QSize maxHint =
mElements.at(row).at(col)->maximumSizeHint();
3040 QSize
final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(), max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height());
3041 if (maxColWidths->at(col) >
final.width())
3042 (*maxColWidths)[col] =
final.width();
3043 if (maxRowHeights->at(row) >
final.height())
3044 (*maxRowHeights)[row] =
final.height();
3102 return mInsetPlacement.at(index);
3105 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3117 return mInsetAlignment.at(index);
3120 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3132 return mInsetRect.at(index);
3135 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3148 mInsetPlacement[index] = placement;
3150 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3164 mInsetAlignment[index] = alignment;
3166 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3183 mInsetRect[index] =
rect;
3185 qDebug() << Q_FUNC_INFO <<
"Invalid element index:" << index;
3194 QSize finalMinSize, finalMaxSize;
3195 QSize minSizeHint =
mElements.at(i)->minimumSizeHint();
3196 QSize maxSizeHint =
mElements.at(i)->maximumSizeHint();
3197 finalMinSize.setWidth(
mElements.at(i)->minimumSize().width() > 0 ?
mElements.at(i)->minimumSize().width() : minSizeHint.width());
3198 finalMinSize.setHeight(
mElements.at(i)->minimumSize().height() > 0 ?
mElements.at(i)->minimumSize().height() : minSizeHint.height());
3199 finalMaxSize.setWidth(
mElements.at(i)->maximumSize().width() < QWIDGETSIZE_MAX ?
mElements.at(i)->maximumSize().width() : maxSizeHint.width());
3200 finalMaxSize.setHeight(
mElements.at(i)->maximumSize().height() < QWIDGETSIZE_MAX ?
mElements.at(i)->maximumSize().height() : maxSizeHint.height());
3201 if (mInsetPlacement.at(i) == ipFree)
3203 insetRect = QRect(
rect().x()+
rect().width()*mInsetRect.at(i).x(),
3204 rect().y()+
rect().height()*mInsetRect.at(i).y(),
3205 rect().width()*mInsetRect.at(i).width(),
3206 rect().height()*mInsetRect.at(i).height());
3207 if (insetRect.size().width() < finalMinSize.width())
3208 insetRect.setWidth(finalMinSize.width());
3209 if (insetRect.size().height() < finalMinSize.height())
3210 insetRect.setHeight(finalMinSize.height());
3211 if (insetRect.size().width() > finalMaxSize.width())
3212 insetRect.setWidth(finalMaxSize.width());
3213 if (insetRect.size().height() > finalMaxSize.height())
3214 insetRect.setHeight(finalMaxSize.height());
3215 }
else if (mInsetPlacement.at(i) == ipBorderAligned)
3217 insetRect.setSize(finalMinSize);
3218 Qt::Alignment al = mInsetAlignment.at(i);
3219 if (al.testFlag(Qt::AlignLeft)) insetRect.moveLeft(
rect().x());
3220 else if (al.testFlag(Qt::AlignRight)) insetRect.moveRight(
rect().x()+
rect().width());
3221 else insetRect.moveLeft(
rect().x()+
rect().width()*0.5-finalMinSize.width()*0.5);
3222 if (al.testFlag(Qt::AlignTop)) insetRect.moveTop(
rect().y());
3223 else if (al.testFlag(Qt::AlignBottom)) insetRect.moveBottom(
rect().y()+
rect().height());
3224 else insetRect.moveTop(
rect().y()+
rect().height()*0.5-finalMinSize.height()*0.5);
3226 mElements.at(i)->setOuterRect(insetRect);
3239 if (index >= 0 && index <
mElements.size())
3252 mInsetPlacement.removeAt(index);
3253 mInsetAlignment.removeAt(index);
3254 mInsetRect.removeAt(index);
3258 qDebug() << Q_FUNC_INFO <<
"Attempt to take invalid index:" << index;
3276 qDebug() << Q_FUNC_INFO <<
"Element not in this layout, couldn't take";
3278 qDebug() << Q_FUNC_INFO <<
"Can't take null element";
3301 if (
mElements.at(i)->realVisibility() &&
mElements.at(i)->selectTest(pos, onlySelectable) >= 0)
3325 mInsetPlacement.append(ipBorderAligned);
3326 mInsetAlignment.append(alignment);
3327 mInsetRect.append(QRectF(0.6, 0.6, 0.4, 0.4));
3330 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
3351 mInsetPlacement.append(ipFree);
3352 mInsetAlignment.append(Qt::AlignRight|Qt::AlignTop);
3353 mInsetRect.append(rect);
3356 qDebug() << Q_FUNC_INFO <<
"Can't add null element";
3528 QVector2D lengthVec(dir.normalized());
3529 if (lengthVec.isNull())
3530 lengthVec = QVector2D(1, 0);
3531 QVector2D widthVec(-lengthVec.y(), lengthVec.x());
3535 QPen penBackup = painter->pen();
3536 QBrush brushBackup = painter->brush();
3537 QPen miterPen = penBackup;
3538 miterPen.setJoinStyle(Qt::MiterJoin);
3539 QBrush brush(painter->pen().color(), Qt::SolidPattern);
3545 QPointF points[3] = {pos.toPointF(),
3546 (pos-lengthVec+widthVec).toPointF(),
3547 (pos-lengthVec-widthVec).toPointF()
3549 painter->
setPen(miterPen);
3550 painter->setBrush(brush);
3551 painter->drawConvexPolygon(points, 3);
3552 painter->setBrush(brushBackup);
3553 painter->
setPen(penBackup);
3558 QPointF points[4] = {pos.toPointF(),
3559 (pos-lengthVec+widthVec).toPointF(),
3560 (pos-lengthVec*0.8f).toPointF(),
3561 (pos-lengthVec-widthVec).toPointF()
3563 painter->
setPen(miterPen);
3564 painter->setBrush(brush);
3565 painter->drawConvexPolygon(points, 4);
3566 painter->setBrush(brushBackup);
3567 painter->
setPen(penBackup);
3572 QPointF points[3] = {(pos-lengthVec+widthVec).toPointF(),
3574 (pos-lengthVec-widthVec).toPointF()
3576 painter->
setPen(miterPen);
3577 painter->drawPolyline(points, 3);
3578 painter->
setPen(penBackup);
3583 painter->setBrush(brush);
3584 painter->drawEllipse(pos.toPointF(),
mWidth*0.5,
mWidth*0.5);
3585 painter->setBrush(brushBackup);
3590 QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
3591 QPointF points[4] = {(pos-widthVecPerp+widthVec).toPointF(),
3592 (pos-widthVecPerp-widthVec).toPointF(),
3593 (pos+widthVecPerp-widthVec).toPointF(),
3594 (pos+widthVecPerp+widthVec).toPointF()
3596 painter->
setPen(miterPen);
3597 painter->setBrush(brush);
3598 painter->drawConvexPolygon(points, 4);
3599 painter->setBrush(brushBackup);
3600 painter->
setPen(penBackup);
3605 QVector2D widthVecPerp(-widthVec.y(), widthVec.x());
3606 QPointF points[4] = {(pos-widthVecPerp).toPointF(),
3607 (pos-widthVec).toPointF(),
3608 (pos+widthVecPerp).toPointF(),
3609 (pos+widthVec).toPointF()
3611 painter->
setPen(miterPen);
3612 painter->setBrush(brush);
3613 painter->drawConvexPolygon(points, 4);
3614 painter->setBrush(brushBackup);
3615 painter->
setPen(penBackup);
3620 painter->
drawLine((pos+widthVec).toPointF(), (pos-widthVec).toPointF());
3625 painter->
drawLine((pos+widthVec).toPointF(), pos.toPointF());
3634 (pos-widthVec-lengthVec*0.2f*(
mInverted?-1:1)).toPointF());
3638 painter->
drawLine((pos+widthVec+lengthVec*0.2f*(
mInverted?-1:1)+dir.normalized()*qMax(1.0f, (
float)painter->pen().widthF())*0.5f).toPointF(),
3639 (pos-widthVec-lengthVec*0.2f*(
mInverted?-1:1)+dir.normalized()*qMax(1.0f, (
float)painter->pen().widthF())*0.5f).toPointF());
3653 draw(painter, pos, QVector2D(qCos(angle), qSin(angle)));
3680 QCPLayerable(parentAxis->parentPlot(), QString(), parentAxis),
3681 mParentAxis(parentAxis)
3684 setParent(parentAxis);
3685 setPen(QPen(QColor(200,200,200), 0, Qt::DotLine));
3772 if (!
mParentAxis) { qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
return; }
3787 if (!
mParentAxis) { qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
return; }
3795 int zeroLineIndex = -1;
3801 for (
int i=lowTick; i <= highTick; ++i)
3815 for (
int i=lowTick; i <= highTick; ++i)
3817 if (i == zeroLineIndex)
continue;
3824 int zeroLineIndex = -1;
3830 for (
int i=lowTick; i <= highTick; ++i)
3844 for (
int i=lowTick; i <= highTick; ++i)
3846 if (i == zeroLineIndex)
continue;
3861 if (!
mParentAxis) { qDebug() << Q_FUNC_INFO <<
"invalid parent axis";
return; }
4001 mOrientation(orientation(type)),
4002 mSelectableParts(spAxis | spTickLabels | spAxisLabel),
4003 mSelectedParts(spNone),
4004 mBasePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
4005 mSelectedBasePen(QPen(Qt::blue, 2)),
4009 mSelectedLabelFont(QFont(mLabelFont.family(), mLabelFont.pointSize(), QFont::Bold)),
4010 mLabelColor(Qt::black),
4011 mSelectedLabelColor(Qt::blue),
4014 mAutoTickLabels(true),
4015 mTickLabelType(ltNumber),
4017 mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)),
4018 mTickLabelColor(Qt::black),
4019 mSelectedTickLabelColor(Qt::blue),
4020 mDateTimeFormat(QLatin1String(
"hh:mm:ss\ndd.MM.yy")),
4021 mDateTimeSpec(Qt::LocalTime),
4022 mNumberPrecision(6),
4023 mNumberFormatChar(
'g'),
4024 mNumberBeautifulPowers(true),
4031 mAutoTickStep(true),
4032 mAutoSubTicks(true),
4033 mTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
4034 mSelectedTickPen(QPen(Qt::blue, 2)),
4035 mSubTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
4036 mSelectedSubTickPen(QPen(Qt::blue, 2)),
4039 mRangeReversed(false),
4040 mScaleType(stLinear),
4042 mScaleLogBaseLogInv(1.0/qLn(mScaleLogBase)),
4046 mLowestVisibleTick(0),
4047 mHighestVisibleTick(-1),
4048 mCachedMarginValid(false),
4067 }
else if (type ==
atLeft)
4105 result.append(QLatin1Char(
'b'));
4107 result.append(QLatin1Char(
'c'));
4200 qDebug() << Q_FUNC_INFO <<
"Invalid logarithmic scale base (must be greater 1):" << base;
4316 if (alignment == Qt::AlignLeft)
4318 else if (alignment == Qt::AlignRight)
4321 setRange(position-size/2.0, position+size/2.0);
4427 if (approximateCount > 0)
4432 qDebug() << Q_FUNC_INFO <<
"approximateCount must be greater than zero:" << approximateCount;
4698 if (formatCode.isEmpty())
4700 qDebug() << Q_FUNC_INFO <<
"Passed formatCode is empty";
4706 QString allowedFormatChars(QLatin1String(
"eEfgG"));
4707 if (allowedFormatChars.contains(formatCode.at(0)))
4712 qDebug() << Q_FUNC_INFO <<
"Invalid number format code (first char not in 'eEfgG'):" << formatCode;
4715 if (formatCode.length() < 2)
4728 qDebug() << Q_FUNC_INFO <<
"Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode;
4731 if (formatCode.length() < 3)
4738 if (formatCode.at(2) == QLatin1Char(
'c'))
4741 }
else if (formatCode.at(2) == QLatin1Char(
'd'))
4746 qDebug() << Q_FUNC_INFO <<
"Invalid number format code (third char neither 'c' nor 'd'):" << formatCode;
5198 qDebug() << Q_FUNC_INFO <<
"Center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center;
5220 int otherPixelSize, ownPixelSize;
5232 double newRangeSize = ratio*otherAxis->
range().
size()*ownPixelSize/(double)otherPixelSize;
5244 QList<QCPAbstractPlottable*> p =
plottables();
5246 bool haveRange =
false;
5247 for (
int i=0; i<p.size(); ++i)
5249 if (!p.at(i)->realVisibility() && onlyVisiblePlottables)
5252 bool currentFoundRange;
5256 if (p.at(i)->keyAxis() ==
this)
5257 plottableRange = p.at(i)->getKeyRange(currentFoundRange, signDomain);
5259 plottableRange = p.at(i)->getValueRange(currentFoundRange, signDomain);
5260 if (currentFoundRange)
5263 newRange = plottableRange;
5265 newRange.
expand(plottableRange);
5273 double center = (newRange.
lower+newRange.
upper)*0.5;
5343 else if (value <= 0 && mRange.upper > 0)
5365 else if (value <= 0 && mRange.upper > 0)
5411 details->setValue(part);
5424 QList<QCPAbstractPlottable*> result;
5442 QList<QCPGraph*> result;
5461 QList<QCPAbstractItem*> result;
5466 QList<QCPItemPosition*> positions =
mParentPlot->
mItems.at(itemId)->positions();
5467 for (
int posId=0; posId<positions.size(); ++posId)
5469 if (positions.at(posId)->keyAxis() ==
this || positions.at(posId)->valueAxis() ==
this)
5493 qDebug() << Q_FUNC_INFO <<
"Invalid margin side passed:" << (int)side;
5508 default: qDebug() << Q_FUNC_INFO <<
"invalid axis type";
return atLeft;
break;
5544 double subTickStep = 0;
5545 double subTickPosition = 0;
5546 int subTickIndex = 0;
5550 for (
int i=lowTick+1; i<=highTick; ++i)
5555 subTickPosition =
mTickVector.at(i-1) + k*subTickStep;
5584 #if QT_VERSION < QT_VERSION_CHECK(4, 7, 0) // use fromMSecsSinceEpoch function if available, to gain sub-second accuracy on tick labels (e.g. for format "hh:mm:ss:zzz") 5620 double magnitudeFactor = qPow(10.0, qFloor(qLn(
mTickStep)/qLn(10.0)));
5621 double tickStepMantissa =
mTickStep/magnitudeFactor;
5622 if (tickStepMantissa < 5)
5625 mTickStep = (int)(tickStepMantissa*2)/2.0*magnitudeFactor;
5629 mTickStep = (int)(tickStepMantissa/2.0)*2.0*magnitudeFactor;
5637 int tickcount = lastStep-firstStep+1;
5638 if (tickcount < 0) tickcount = 0;
5640 for (
int i=0; i<tickcount; ++i)
5648 double currentMag = lowerMag;
5651 while (currentMag < mRange.upper && currentMag > 0)
5659 double currentMag = lowerMag;
5662 while (currentMag <
mRange.
upper && currentMag < 0)
5670 qDebug() << Q_FUNC_INFO <<
"Invalid range for logarithmic plot: " <<
mRange.
lower <<
"-" <<
mRange.
upper;
5693 double magnitudeFactor = qPow(10.0, qFloor(qLn(tickStep)/qLn(10.0)));
5694 double tickStepMantissa = tickStep/magnitudeFactor;
5697 double epsilon = 0.01;
5700 double fracPart = modf(tickStepMantissa, &intPartf);
5704 if (fracPart < epsilon || 1.0-fracPart < epsilon)
5706 if (1.0-fracPart < epsilon)
5710 case 1: result = 4;
break;
5711 case 2: result = 3;
break;
5712 case 3: result = 2;
break;
5713 case 4: result = 3;
break;
5714 case 5: result = 4;
break;
5715 case 6: result = 2;
break;
5716 case 7: result = 6;
break;
5717 case 8: result = 3;
break;
5718 case 9: result = 2;
break;
5723 if (qAbs(fracPart-0.5) < epsilon)
5727 case 1: result = 2;
break;
5728 case 2: result = 4;
break;
5729 case 3: result = 4;
break;
5730 case 4: result = 2;
break;
5731 case 5: result = 4;
break;
5732 case 6: result = 4;
break;
5733 case 7: result = 2;
break;
5734 case 8: result = 4;
break;
5735 case 9: result = 4;
break;
5753 if (selectionStateChanged)
5763 if (selectionStateChanged)
5794 QVector<double> subTickPositions;
5795 QVector<double> tickPositions;
5797 tickPositions.reserve(highTick-lowTick+1);
5798 tickLabels.reserve(highTick-lowTick+1);
5803 for (
int i=lowTick; i<=highTick; ++i)
5857 bool lowFound =
false;
5858 bool highFound =
false;
5881 if (!lowFound && highFound)
5882 lowIndex = highIndex+1;
5883 else if (lowFound && !highFound)
5884 highIndex = lowIndex-1;
6007 int lowTick, highTick;
6009 QVector<double> tickPositions;
6011 tickPositions.reserve(highTick-lowTick+1);
6012 tickLabels.reserve(highTick-lowTick+1);
6015 for (
int i=lowTick; i<=highTick; ++i)
6069 basePen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
6076 substituteExponent(true),
6077 numberMultiplyCross(false),
6082 tickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
6083 subTickPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::SquareCap)),
6085 abbreviateDecimalPowers(false),
6086 reversedEndings(false),
6121 double xCor = 0, yCor = 0;
6133 baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(
axisRect.width()+xCor, yCor));
6135 baseLine.setPoints(origin+QPointF(xCor, yCor), origin+QPointF(xCor, -
axisRect.height()+yCor));
6137 baseLine = QLineF(baseLine.p2(), baseLine.p1());
6177 painter->setBrush(QBrush(
basePen.color()));
6178 QVector2D baseLineVector(baseLine.dx(), baseLine.dy());
6189 oldClipRect = painter->clipRegion().boundingRect();
6192 QSize tickLabelsSize(0, 0);
6200 int distanceToAxis = margin;
6203 for (
int i=0; i<maxLabelIndex; ++i)
6209 painter->setClipRect(oldClipRect);
6213 if (!
label.isEmpty())
6218 labelBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip,
label);
6221 QTransform oldTransform = painter->transform();
6222 painter->translate((origin.x()-margin-labelBounds.height()), origin.y());
6223 painter->rotate(-90);
6224 painter->drawText(0, 0,
axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6225 painter->setTransform(oldTransform);
6229 QTransform oldTransform = painter->transform();
6230 painter->translate((origin.x()+margin+labelBounds.height()), origin.y()-
axisRect.height());
6231 painter->rotate(90);
6232 painter->drawText(0, 0,
axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6233 painter->setTransform(oldTransform);
6236 painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(),
axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6238 painter->drawText(origin.x(), origin.y()+margin,
axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter,
label);
6242 int selectionTolerance = 0;
6246 qDebug() << Q_FUNC_INFO <<
"mParentPlot is null";
6248 int selAxisInSize = selectionTolerance;
6249 int selTickLabelSize;
6250 int selTickLabelOffset;
6253 selTickLabelSize = (
QCPAxis::orientation(
type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width());
6257 selTickLabelSize = -(
QCPAxis::orientation(
type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width());
6260 int selLabelSize = labelBounds.height();
6307 QSize tickLabelsSize(0, 0);
6318 if (!
label.isEmpty())
6322 bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter,
label);
6381 if (text.isEmpty())
return;
6383 QPointF labelAnchor;
6400 cachedLabel->
pixmap.fill(Qt::transparent);
6402 cachePainter.
setPen(painter->pen());
6406 bool labelClippedByBorder =
false;
6414 if (!labelClippedByBorder)
6416 painter->drawPixmap(labelAnchor+cachedLabel->
offset, cachedLabel->
pixmap);
6417 finalSize = cachedLabel->
pixmap.size();
6425 bool labelClippedByBorder =
false;
6433 if (!labelClippedByBorder)
6435 drawTickLabel(painter, finalPosition.x(), finalPosition.y(), labelData);
6441 if (finalSize.width() > tickLabelsSize->width())
6442 tickLabelsSize->setWidth(finalSize.width());
6443 if (finalSize.height() > tickLabelsSize->height())
6444 tickLabelsSize->setHeight(finalSize.height());
6459 QTransform oldTransform = painter->transform();
6460 QFont oldFont = painter->font();
6463 painter->translate(x, y);
6468 if (!labelData.
expPart.isEmpty())
6470 painter->setFont(labelData.
baseFont);
6471 painter->drawText(0, 0, 0, 0, Qt::TextDontClip, labelData.
basePart);
6472 painter->setFont(labelData.
expFont);
6476 painter->setFont(labelData.
baseFont);
6481 painter->setTransform(oldTransform);
6482 painter->setFont(oldFont);
6498 bool useBeautifulPowers =
false;
6502 ePos = text.indexOf(QLatin1Char(
'e'));
6504 useBeautifulPowers =
true;
6509 if (result.
baseFont.pointSizeF() > 0)
6511 if (useBeautifulPowers)
6517 result.
basePart = QLatin1String(
"10");
6520 result.
expPart = text.mid(ePos+1);
6522 while (result.
expPart.length() > 2 && result.
expPart.at(1) == QLatin1Char(
'0'))
6524 if (!result.
expPart.isEmpty() && result.
expPart.at(0) == QLatin1Char(
'+'))
6528 if (result.
expFont.pointSize() > 0)
6539 result.
totalBounds = QFontMetrics(result.
baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.
basePart);
6547 QTransform transform;
6605 x = +qSin(radians)*labelData.
totalBounds.height();
6627 x = -qSin(-radians)*labelData.
totalBounds.height()/2.0;
6628 y = -qCos(-radians)*labelData.
totalBounds.height();
6641 x = +qSin(radians)*labelData.
totalBounds.height()/2.0;
6646 y = +qSin(-radians)*labelData.
totalBounds.width();
6655 return QPointF(x, y);
6672 finalSize = cachedLabel->
pixmap.size();
6680 if (finalSize.width() > tickLabelsSize->width())
6681 tickLabelsSize->setWidth(finalSize.width());
6682 if (finalSize.height() > tickLabelsSize->height())
6683 tickLabelsSize->setHeight(finalSize.height());
6841 mAntialiasedFill(true),
6842 mAntialiasedScatters(true),
6843 mAntialiasedErrorBars(false),
6845 mSelectedPen(Qt::black),
6846 mBrush(Qt::NoBrush),
6847 mSelectedBrush(Qt::NoBrush),
6849 mValueAxis(valueAxis),
6854 qDebug() << Q_FUNC_INFO <<
"Parent plot of keyAxis is not the same as that of valueAxis.";
6856 qDebug() << Q_FUNC_INFO <<
"keyAxis and valueAxis must be orthogonal to each other.";
7051 if (!keyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
7065 double center = (newRange.
lower+newRange.
upper)*0.5;
7091 if (!valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid value axis";
return; }
7105 double center = (newRange.
lower+newRange.
upper)*0.5;
7195 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
7217 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPointF(); }
7239 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
7365 double vLengthSqr = v.lengthSquared();
7366 if (!qFuzzyIsNull(vLengthSqr))
7368 double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr;
7370 return (a-p).lengthSquared();
7372 return (b-p).lengthSquared();
7374 return ((a + mu*v)-p).lengthSquared();
7376 return (a-p).lengthSquared();
7388 if (selectionStateChanged)
7389 *selectionStateChanged =
mSelected != selBefore;
7400 if (selectionStateChanged)
7401 *selectionStateChanged =
mSelected != selBefore;
7453 mParentItem(parentItem),
7488 qDebug() << Q_FUNC_INFO <<
"no valid anchor id set:" <<
mAnchorId;
7493 qDebug() << Q_FUNC_INFO <<
"no parent item set";
7511 qDebug() << Q_FUNC_INFO <<
"provided pos is child already" <<
reinterpret_cast<quintptr
>(pos);
7523 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child" <<
reinterpret_cast<quintptr
>(pos);
7539 qDebug() << Q_FUNC_INFO <<
"provided pos is child already" <<
reinterpret_cast<quintptr
>(pos);
7551 qDebug() << Q_FUNC_INFO <<
"provided pos isn't child" <<
reinterpret_cast<quintptr
>(pos);
7625 mPositionTypeX(ptAbsolute),
7626 mPositionTypeY(ptAbsolute),
7706 bool retainPixelPosition =
true;
7708 retainPixelPosition =
false;
7710 retainPixelPosition =
false;
7713 if (retainPixelPosition)
7718 if (retainPixelPosition)
7736 bool retainPixelPosition =
true;
7738 retainPixelPosition =
false;
7740 retainPixelPosition =
false;
7743 if (retainPixelPosition)
7748 if (retainPixelPosition)
7775 return successX && successY;
7788 if (parentAnchor ==
this)
7790 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7795 while (currentParent)
7800 if (currentParentPos ==
this)
7802 qDebug() << Q_FUNC_INFO <<
"can't create recursive parent-child-relationship" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7805 currentParent = currentParentPos->parentAnchorX();
7813 qDebug() << Q_FUNC_INFO <<
"can't set parent to be an anchor which itself depends on this position" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7826 if (keepPixelPosition)
7836 if (keepPixelPosition)
7853 if (parentAnchor ==
this)
7855 qDebug() << Q_FUNC_INFO <<
"can't set self as parent anchor" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7860 while (currentParent)
7865 if (currentParentPos ==
this)
7867 qDebug() << Q_FUNC_INFO <<
"can't create recursive parent-child-relationship" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7870 currentParent = currentParentPos->parentAnchorY();
7878 qDebug() << Q_FUNC_INFO <<
"can't set parent to be an anchor which itself depends on this position" <<
reinterpret_cast<quintptr
>(
parentAnchor);
7891 if (keepPixelPosition)
7901 if (keepPixelPosition)
7978 result.rx() +=
mAxisRect.data()->left();
7980 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptAxisRectRatio, but no axis rect was defined";
7990 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptPlotCoords, but no axes were defined";
8024 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptAxisRectRatio, but no axis rect was defined";
8034 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptPlotCoords, but no axes were defined";
8075 double x = pixelPoint.x();
8076 double y = pixelPoint.y();
8105 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptAxisRectRatio, but no axis rect was defined";
8111 x =
mKeyAxis.data()->pixelToCoord(x);
8115 qDebug() << Q_FUNC_INFO <<
"Item position type x is ptPlotCoords, but no axes were defined";
8145 y /= (double)
mAxisRect.data()->height();
8147 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptAxisRectRatio, but no axis rect was defined";
8153 x =
mKeyAxis.data()->pixelToCoord(y);
8157 qDebug() << Q_FUNC_INFO <<
"Item position type y is ptPlotCoords, but no axes were defined";
8340 mClipToAxisRect(false),
8344 QList<QCPAxisRect*> rects = parentPlot->
axisRects();
8345 if (rects.size() > 0)
8448 qDebug() << Q_FUNC_INFO <<
"position with name not found:" << name;
8464 for (
int i=0; i<
mAnchors.size(); ++i)
8466 if (
mAnchors.at(i)->name() == name)
8469 qDebug() << Q_FUNC_INFO <<
"anchor with name not found:" << name;
8483 for (
int i=0; i<
mAnchors.size(); ++i)
8485 if (
mAnchors.at(i)->name() == name)
8545 double vLengthSqr = v.lengthSquared();
8546 if (!qFuzzyIsNull(vLengthSqr))
8548 double mu = QVector2D::dotProduct(p-a, v)/vLengthSqr;
8550 return (a-p).lengthSquared();
8552 return (b-p).lengthSquared();
8554 return ((a + mu*v)-p).lengthSquared();
8556 return (a-p).lengthSquared();
8579 QList<QLineF> lines;
8580 lines << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight())
8581 << QLineF(rect.topLeft(), rect.bottomLeft()) << QLineF(rect.topRight(), rect.bottomRight());
8583 for (
int i=0; i<lines.size(); ++i)
8585 double distSqr =
distSqrToLine(lines.at(i).p1(), lines.at(i).p2(), pos);
8586 if (distSqr < minDistSqr)
8587 minDistSqr = distSqr;
8589 result = qSqrt(minDistSqr);
8594 if (rect.contains(pos))
8612 qDebug() << Q_FUNC_INFO <<
"called on item which shouldn't have any anchors (this method not reimplemented). anchorId" << anchorId;
8633 qDebug() << Q_FUNC_INFO <<
"anchor/position with name exists already:" << name;
8667 qDebug() << Q_FUNC_INFO <<
"anchor/position with name exists already:" << name;
8682 if (selectionStateChanged)
8683 *selectionStateChanged =
mSelected != selBefore;
8694 if (selectionStateChanged)
8695 *selectionStateChanged =
mSelected != selBefore;
9023 mAutoAddPlottableToLegend(true),
9027 mSelectionTolerance(8),
9028 mNoAntialiasingOnDrag(false),
9029 mBackgroundBrush(Qt::white, Qt::SolidPattern),
9030 mBackgroundScaled(true),
9031 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
9034 mMultiSelectModifier(Qt::ControlModifier),
9035 mPaintBuffer(
size()),
9036 mMouseEventElement(0),
9039 setAttribute(Qt::WA_NoMousePropagation);
9040 setAttribute(Qt::WA_OpaquePaintEvent);
9041 setMouseTracking(
true);
9042 QLocale currentLocale = locale();
9043 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
9044 setLocale(currentLocale);
9071 defaultAxisRect->
setLayer(QLatin1String(
"background"));
9462 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9497 qDebug() << Q_FUNC_INFO <<
"plottable already added to this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
plottable);
9502 qDebug() << Q_FUNC_INFO <<
"plottable not created with this QCustomPlot as parent:" <<
reinterpret_cast<quintptr
>(
plottable);
9513 if (!plottable->
layer())
9529 qDebug() << Q_FUNC_INFO <<
"plottable not in list:" <<
reinterpret_cast<quintptr
>(
plottable);
9554 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9569 for (
int i=c-1; i >= 0; --i)
9593 QList<QCPAbstractPlottable*> result;
9597 result.append(plottable);
9621 if (onlySelectable && !plottable->
selectable())
9625 double currentDistance = plottable->
selectTest(pos,
false);
9626 if (currentDistance >= 0 && currentDistance < resultDistance)
9629 resultDistance = currentDistance;
9634 return resultPlottable;
9657 if (index >= 0 && index <
mGraphs.size())
9662 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9697 if (!keyAxis) keyAxis =
xAxis;
9698 if (!valueAxis) valueAxis =
yAxis;
9699 if (!keyAxis || !valueAxis)
9701 qDebug() << Q_FUNC_INFO <<
"can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)";
9706 qDebug() << Q_FUNC_INFO <<
"passed keyAxis or valueAxis doesn't have this QCustomPlot as parent";
9713 newGraph->
setName(QLatin1String(
"Graph ")+QString::number(
mGraphs.size()));
9742 if (index >= 0 && index <
mGraphs.size())
9758 for (
int i=c-1; i >= 0; --i)
9783 QList<QCPGraph*> result;
9787 result.append(graph);
9802 if (index >= 0 && index <
mItems.size())
9807 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9844 qDebug() << Q_FUNC_INFO <<
"item either already in list or not created with this QCustomPlot as parent:" <<
reinterpret_cast<quintptr
>(
item);
9858 if (
mItems.contains(item))
9865 qDebug() << Q_FUNC_INFO <<
"item not in list:" <<
reinterpret_cast<quintptr
>(
item);
9876 if (index >= 0 && index <
mItems.size())
9880 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
9895 for (
int i=c-1; i >= 0; --i)
9917 QList<QCPAbstractItem*> result;
9921 result.append(item);
9950 double currentDistance = item->
selectTest(pos,
false);
9951 if (currentDistance >= 0 && currentDistance < resultDistance)
9954 resultDistance = currentDistance;
9969 return mItems.contains(item);
9984 if (layer->
name() == name)
9998 if (index >= 0 && index <
mLayers.size())
10003 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
10033 qDebug() << Q_FUNC_INFO <<
"layer with name doesn't exist:" << name;
10048 if (!
mLayers.contains(layer))
10050 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
layer);
10085 if (!
mLayers.contains(otherLayer))
10087 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(otherLayer);
10092 qDebug() << Q_FUNC_INFO <<
"A layer exists already with the name" << name;
10118 if (!
mLayers.contains(layer))
10120 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
layer);
10125 qDebug() << Q_FUNC_INFO <<
"can't remove last layer";
10130 int removedIndex = layer->
index();
10131 bool isFirstLayer = removedIndex==0;
10133 QList<QCPLayerable*> children = layer->
children();
10136 for (
int i=children.size()-1; i>=0; --i)
10137 children.at(i)->moveToLayer(targetLayer,
true);
10140 for (
int i=0; i<children.size(); ++i)
10141 children.at(i)->moveToLayer(targetLayer,
false);
10164 if (!
mLayers.contains(layer))
10166 qDebug() << Q_FUNC_INFO <<
"layer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(
layer);
10169 if (!
mLayers.contains(otherLayer))
10171 qDebug() << Q_FUNC_INFO <<
"otherLayer not a layer of this QCustomPlot:" <<
reinterpret_cast<quintptr
>(otherLayer);
10205 const QList<QCPAxisRect*> rectList =
axisRects();
10206 if (index >= 0 && index < rectList.size())
10208 return rectList.at(index);
10211 qDebug() << Q_FUNC_INFO <<
"invalid axis rect index" << index;
10223 QList<QCPAxisRect*> result;
10224 QStack<QCPLayoutElement*> elementStack;
10228 while (!elementStack.isEmpty())
10234 elementStack.push(element);
10235 if (
QCPAxisRect *ar = qobject_cast<QCPAxisRect*>(element))
10256 bool searchSubElements =
true;
10257 while (searchSubElements && currentElement)
10259 searchSubElements =
false;
10264 currentElement = subElement;
10265 searchSubElements =
true;
10270 return currentElement;
10282 QList<QCPAxis*> result, allAxes;
10284 allAxes << rect->
axes();
10286 foreach (
QCPAxis *axis, allAxes)
10289 result.append(axis);
10304 QList<QCPLegend*> result;
10306 QStack<QCPLayoutElement*> elementStack;
10310 while (!elementStack.isEmpty())
10316 elementStack.push(subElement);
10317 if (
QCPLegend *leg = qobject_cast<QCPLegend*>(subElement))
10320 result.append(leg);
10370 if (painter.isActive())
10372 painter.setRenderHint(QPainter::HighQualityAntialiasing);
10382 qDebug() << Q_FUNC_INFO <<
"Couldn't activate painter on buffer. This usually happens because QCustomPlot has width or height zero.";
10398 QList<QCPAxis*> allAxes;
10400 allAxes << rect->
axes();
10402 foreach (
QCPAxis *axis, allAxes)
10403 axis->
rescale(onlyVisiblePlottables);
10443 bool QCustomPlot::savePdf(
const QString &fileName,
bool noCosmeticPen,
int width,
int height,
const QString &pdfCreator,
const QString &pdfTitle)
10445 bool success =
false;
10446 #ifdef QT_NO_PRINTER 10448 Q_UNUSED(noCosmeticPen)
10451 Q_UNUSED(pdfCreator)
10453 qDebug() << Q_FUNC_INFO <<
"Qt was built without printer support (QT_NO_PRINTER). PDF not created.";
10455 int newWidth, newHeight;
10456 if (width == 0 || height == 0)
10458 newWidth = this->width();
10459 newHeight = this->height();
10463 newHeight = height;
10466 QPrinter printer(QPrinter::ScreenResolution);
10467 printer.setOutputFileName(fileName);
10468 printer.setOutputFormat(QPrinter::PdfFormat);
10469 printer.setColorMode(QPrinter::Color);
10470 printer.printEngine()->setProperty(QPrintEngine::PPK_Creator, pdfCreator);
10471 printer.printEngine()->setProperty(QPrintEngine::PPK_DocumentName, pdfTitle);
10474 #if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) 10475 printer.setFullPage(
true);
10476 printer.setPaperSize(
viewport().
size(), QPrinter::DevicePixel);
10478 QPageLayout pageLayout;
10479 pageLayout.setMode(QPageLayout::FullPageMode);
10480 pageLayout.setOrientation(QPageLayout::Portrait);
10481 pageLayout.setMargins(QMarginsF(0, 0, 0, 0));
10482 pageLayout.setPageSize(QPageSize(
viewport().
size(), QPageSize::Point, QString(), QPageSize::ExactMatch));
10483 printer.setPageLayout(pageLayout);
10486 if (printpainter.
begin(&printer))
10497 draw(&printpainter);
10498 printpainter.end();
10502 #endif // QT_NO_PRINTER 10545 return saveRastered(fileName, width, height, scale,
"PNG", quality);
10584 return saveRastered(fileName, width, height, scale,
"JPG", quality);
10620 return saveRastered(fileName, width, height, scale,
"BMP");
10654 QPainter painter(
this);
10691 else if (
QCPAxis *ax = qobject_cast<QCPAxis*>(clickedLayerable))
10693 else if (
QCPAbstractItem *ai = qobject_cast<QCPAbstractItem*>(clickedLayerable))
10695 else if (
QCPLegend *lg = qobject_cast<QCPLegend*>(clickedLayerable))
10699 else if (
QCPPlotTitle *pt = qobject_cast<QCPPlotTitle*>(clickedLayerable))
10704 el->mouseDoubleClickEvent(event);
10733 QWidget::mousePressEvent(event);
10753 QWidget::mouseMoveEvent(event);
10773 bool doReplot =
false;
10777 if (event->button() == Qt::LeftButton)
10782 bool selectionStateChanged =
false;
10793 bool selChanged =
false;
10795 selectionStateChanged |= selChanged;
10803 bool selChanged =
false;
10804 clickedLayerable->
selectEvent(event, additive, details, &selChanged);
10805 selectionStateChanged |= selChanged;
10807 if (selectionStateChanged)
10819 else if (
QCPAxis *ax = qobject_cast<QCPAxis*>(clickedLayerable))
10821 else if (
QCPAbstractItem *ai = qobject_cast<QCPAbstractItem*>(clickedLayerable))
10823 else if (
QCPLegend *lg = qobject_cast<QCPLegend*>(clickedLayerable))
10827 else if (
QCPPlotTitle *pt = qobject_cast<QCPPlotTitle*>(clickedLayerable))
10841 QWidget::mouseReleaseEvent(event);
10856 el->wheelEvent(event);
10858 QWidget::wheelEvent(event);
10886 painter->setClipRect(child->
clipRect().translated(0, -1));
10888 child->
draw(painter);
10972 if (this->legend == legend)
10984 for (
int i=0; i<
mLayers.size(); ++i)
11002 for (
int layerIndex=
mLayers.size()-1; layerIndex>=0; --layerIndex)
11004 const QList<QCPLayerable*> layerables =
mLayers.at(layerIndex)->children();
11007 for (
int i=layerables.size()-1; i>=0; --i)
11009 if (!layerables.at(i)->realVisibility())
11012 double dist = layerables.at(i)->
selectTest(pos, onlySelectable, &details);
11013 if (dist >= 0 && dist < minimumDistance)
11015 minimumDistance = dist;
11016 minimumDistanceLayerable = layerables.at(i);
11017 if (selectionDetails) *selectionDetails = details;
11021 return minimumDistanceLayerable;
11039 QPixmap buffer =
toPixmap(width, height, scale);
11040 if (!buffer.isNull())
11041 return buffer.save(fileName, format, quality);
11057 int newWidth, newHeight;
11058 if (width == 0 || height == 0)
11060 newWidth = this->width();
11061 newHeight = this->height();
11065 newHeight = height;
11067 int scaledWidth = qRound(scale*newWidth);
11068 int scaledHeight = qRound(scale*newHeight);
11070 QPixmap result(scaledWidth, scaledHeight);
11073 painter.
begin(&result);
11074 if (painter.isActive())
11079 if (!qFuzzyCompare(scale, 1.0))
11083 painter.scale(scale, scale);
11092 qDebug() << Q_FUNC_INFO <<
"Couldn't activate painter on pixmap";
11113 int newWidth, newHeight;
11114 if (width == 0 || height == 0)
11116 newWidth = this->width();
11117 newHeight = this->height();
11121 newHeight = height;
11124 if (painter->isActive())
11134 qDebug() << Q_FUNC_INFO <<
"Passed painter is not active";
11174 mColorInterpolation(ciRGB),
11176 mColorBufferInvalidated(true)
11185 return ((other.
mLevelCount == this->mLevelCount) &&
11187 (other.
mPeriodic == this->mPeriodic) &&
11201 qDebug() << Q_FUNC_INFO <<
"n must be greater or equal 2 but was" << n;
11292 qDebug() << Q_FUNC_INFO <<
"null pointer given as data";
11297 qDebug() << Q_FUNC_INFO <<
"null pointer given as scanLine";
11308 for (
int i=0; i<n; ++i)
11310 int index = (int)((data[dataIndexFactor*i]-range.
lower)*posToIndexFactor) %
mLevelCount;
11317 for (
int i=0; i<n; ++i)
11319 int index = (data[dataIndexFactor*i]-range.
lower)*posToIndexFactor;
11331 for (
int i=0; i<n; ++i)
11340 for (
int i=0; i<n; ++i)
11519 for (QMap<double, QColor>::const_iterator it=
mColorStops.constBegin(); it!=
mColorStops.constEnd(); ++it)
11535 double indexToPosFactor = 1.0/(double)(
mLevelCount-1);
11538 double position = i*indexToPosFactor;
11539 QMap<double, QColor>::const_iterator it =
mColorStops.lowerBound(position);
11548 QMap<double, QColor>::const_iterator high = it;
11549 QMap<double, QColor>::const_iterator low = it-1;
11550 double t = (position-low.key())/(high.key()-low.key());
11555 mColorBuffer[i] = qRgb((1-t)*low.value().red() + t*high.value().red(),
11556 (1-t)*low.value().green() + t*high.value().green(),
11557 (1-t)*low.value().blue() + t*high.value().blue());
11562 QColor lowHsv = low.value().toHsv();
11563 QColor highHsv = high.value().toHsv();
11565 double hueDiff = highHsv.hueF()-lowHsv.hueF();
11567 hue = lowHsv.hueF() - t*(1.0-hueDiff);
11568 else if (hueDiff < -0.5)
11569 hue = lowHsv.hueF() + t*(1.0+hueDiff);
11571 hue = lowHsv.hueF() + t*hueDiff;
11572 if (hue < 0) hue += 1.0;
11573 else if (hue >= 1.0) hue -= 1.0;
11574 mColorBuffer[i] = QColor::fromHsvF(hue, (1-t)*lowHsv.saturationF() + t*highHsv.saturationF(), (1-t)*lowHsv.valueF() + t*highHsv.valueF()).rgb();
11722 mBackgroundBrush(Qt::NoBrush),
11723 mBackgroundScaled(true),
11724 mBackgroundScaledMode(Qt::KeepAspectRatioByExpanding),
11726 mRangeDrag(Qt::Horizontal|Qt::Vertical),
11727 mRangeZoom(Qt::Horizontal|Qt::Vertical),
11728 mRangeZoomFactorHorz(0.85),
11729 mRangeZoomFactorVert(0.85),
11743 if (setupDefaultAxes)
11769 QList<QCPAxis*> axesList =
axes();
11770 for (
int i=0; i<axesList.size(); ++i)
11781 return mAxes.value(type).size();
11791 QList<QCPAxis*> ax(
mAxes.value(type));
11792 if (index >= 0 && index < ax.size())
11794 return ax.at(index);
11797 qDebug() << Q_FUNC_INFO <<
"Axis index out of bounds:" << index;
11812 QList<QCPAxis*> result;
11830 QList<QCPAxis*> result;
11831 QHashIterator<QCPAxis::AxisType, QList<QCPAxis*> > it(
mAxes);
11832 while (it.hasNext())
11835 result << it.value();
11864 newAxis =
new QCPAxis(
this, type);
11869 qDebug() << Q_FUNC_INFO <<
"passed axis has different axis type than specified in type parameter";
11874 qDebug() << Q_FUNC_INFO <<
"passed axis doesn't have this axis rect as parent axis rect";
11877 if (
axes().contains(newAxis))
11879 qDebug() << Q_FUNC_INFO <<
"passed axis is already owned by this axis rect";
11889 mAxes[type].append(newAxis);
11903 QList<QCPAxis*> result;
11925 QHashIterator<QCPAxis::AxisType, QList<QCPAxis*> > it(
mAxes);
11926 while (it.hasNext())
11929 if (it.value().contains(axis))
11931 mAxes[it.key()].removeOne(axis);
11932 if (qobject_cast<QCustomPlot*>(
parentPlot()))
11938 qDebug() << Q_FUNC_INFO <<
"Axis isn't in axis rect:" <<
reinterpret_cast<quintptr
>(
axis);
11970 QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
12032 connect(xAxis, SIGNAL(rangeChanged(
QCPRange)), xAxis2, SLOT(setRange(
QCPRange)));
12033 connect(yAxis, SIGNAL(rangeChanged(
QCPRange)), yAxis2, SLOT(setRange(
QCPRange)));
12048 QList<QCPAbstractPlottable*> result;
12068 QList<QCPGraph*> result;
12091 QList<QCPAbstractItem*> result;
12099 QList<QCPItemPosition*> positions =
mParentPlot->
mItems.at(itemId)->positions();
12100 for (
int posId=0; posId<positions.size(); ++posId)
12102 if (positions.at(posId)->axisRect() ==
this ||
12103 positions.at(posId)->keyAxis()->axisRect() ==
this ||
12104 positions.at(posId)->valueAxis()->axisRect() ==
this)
12130 QList<QCPAxis*> allAxes =
axes();
12131 for (
int i=0; i<allAxes.size(); ++i)
12132 allAxes.at(i)->setupTickVectors();
12150 QList<QCPLayoutElement*> result;
12155 result << mInsetLayout->
elements(recursive);
12427 const QList<QCPAxis*> axesList =
mAxes.value(type);
12428 if (axesList.isEmpty())
12431 bool isFirstVisible = !axesList.first()->visible();
12432 for (
int i=1; i<axesList.size(); ++i)
12434 int offset = axesList.at(i-1)->offset() + axesList.at(i-1)->calculateMargin();
12435 if (axesList.at(i)->visible())
12437 if (!isFirstVisible)
12438 offset += axesList.at(i)->tickLengthIn();
12439 isFirstVisible =
false;
12441 axesList.at(i)->setOffset(offset);
12449 qDebug() << Q_FUNC_INFO <<
"Called with side that isn't specified as auto margin";
12455 if (axesList.size() > 0)
12456 return axesList.last()->offset() + axesList.last()->calculateMargin();
12475 if (event->buttons() & Qt::LeftButton)
12513 double diff = rangeDragHorzAxis->pixelToCoord(
mDragStart.x()) - rangeDragHorzAxis->pixelToCoord(event->pos().x());
12517 double diff = rangeDragHorzAxis->pixelToCoord(
mDragStart.x()) / rangeDragHorzAxis->pixelToCoord(event->pos().x());
12528 double diff = rangeDragVertAxis->pixelToCoord(
mDragStart.y()) - rangeDragVertAxis->pixelToCoord(event->pos().y());
12532 double diff = rangeDragVertAxis->pixelToCoord(
mDragStart.y()) / rangeDragVertAxis->pixelToCoord(event->pos().y());
12580 double wheelSteps =
event->delta()/120.0;
12643 mParentLegend(parent),
12644 mFont(parent->font()),
12645 mTextColor(parent->textColor()),
12646 mSelectedFont(parent->selectedFont()),
12647 mSelectedTextColor(parent->selectedTextColor()),
12651 setLayer(QLatin1String(
"legend"));
12736 if (
mRect.contains(pos.toPoint()))
12763 if (selectionStateChanged)
12764 *selectionStateChanged =
mSelected != selBefore;
12775 if (selectionStateChanged)
12776 *selectionStateChanged =
mSelected != selBefore;
12819 mPlottable(plottable)
12865 QRectF textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip,
mPlottable->
name());
12866 QRectF iconRect(
mRect.topLeft(), iconSize);
12867 int textHeight = qMax(textRect.height(), iconSize.height());
12871 painter->setClipRect(iconRect, Qt::IntersectClip);
12878 painter->setBrush(Qt::NoBrush);
12879 painter->drawRect(iconRect);
12891 QSize result(0, 0);
12893 QFontMetrics fontMetrics(
getFont());
12895 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip,
mPlottable->
name());
12897 result.setHeight(qMax(textRect.height(), iconSize.height()) +
mMargins.top() +
mMargins.bottom());
12950 setColumnSpacing(10);
12953 setIconSize(32, 18);
12955 setIconTextPadding(7);
12957 setSelectableParts(spLegendBox | spItems);
12958 setSelectedParts(spNone);
12960 setBorderPen(QPen(Qt::black));
12961 setSelectedBorderPen(QPen(Qt::blue, 2));
12962 setIconBorderPen(Qt::NoPen);
12963 setSelectedIconBorderPen(QPen(Qt::blue, 2));
12964 setBrush(Qt::white);
12965 setSelectedBrush(Qt::white);
12981 bool hasSelectedItems =
false;
12982 for (
int i=0; i<itemCount(); ++i)
12984 if (item(i) && item(i)->selected())
12986 hasSelectedItems =
true;
12990 if (hasSelectedItems)
12991 return mSelectedParts | spItems;
12993 return mSelectedParts & ~spItems;
13024 for (
int i=0; i<itemCount(); ++i)
13027 item(i)->setFont(
mFont);
13043 for (
int i=0; i<itemCount(); ++i)
13046 item(i)->setTextColor(color);
13063 mIconSize.setWidth(width);
13064 mIconSize.setHeight(height);
13074 mIconTextPadding = padding;
13085 mIconBorderPen = pen;
13100 if (mSelectableParts != selectable)
13130 SelectableParts newSelected =
selected;
13131 mSelectedParts = this->selectedParts();
13133 if (mSelectedParts != newSelected)
13135 if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems))
13137 qDebug() << Q_FUNC_INFO <<
"spItems flag can not be set, it can only be unset with this function";
13138 newSelected &= ~spItems;
13140 if (mSelectedParts.testFlag(spItems) && !newSelected.testFlag(spItems))
13142 for (
int i=0; i<itemCount(); ++i)
13145 item(i)->setSelected(
false);
13148 mSelectedParts = newSelected;
13161 mSelectedBorderPen = pen;
13171 mSelectedIconBorderPen = pen;
13182 mSelectedBrush = brush;
13195 for (
int i=0; i<itemCount(); ++i)
13198 item(i)->setSelectedFont(font);
13212 for (
int i=0; i<itemCount(); ++i)
13215 item(i)->setSelectedTextColor(color);
13237 for (
int i=0; i<itemCount(); ++i)
13254 return elementCount();
13262 for (
int i=0; i<itemCount(); ++i)
13264 if (item == this->item(i))
13278 return itemWithPlottable(plottable);
13290 if (!hasItem(item))
13292 return addElement(rowCount(), 0, item);
13308 bool success =
remove(ali);
13325 bool success =
remove(item);
13335 for (
int i=itemCount()-1; i>=0; --i)
13347 QList<QCPAbstractLegendItem*> result;
13348 for (
int i=0; i<itemCount(); ++i)
13352 if (ali->selected())
13353 result.append(ali);
13384 return mSelectedParts.testFlag(spLegendBox) ? mSelectedBorderPen : mBorderPen;
13394 return mSelectedParts.testFlag(spLegendBox) ? mSelectedBrush : mBrush;
13405 painter->setBrush(getBrush());
13406 painter->
setPen(getBorderPen());
13414 if (onlySelectable && !mSelectableParts.testFlag(spLegendBox))
13419 if (details) details->setValue(spLegendBox);
13429 mSelectedParts = selectedParts();
13430 if (details.value<
SelectablePart>() == spLegendBox && mSelectableParts.testFlag(spLegendBox))
13432 SelectableParts selBefore = mSelectedParts;
13433 setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox);
13434 if (selectionStateChanged)
13435 *selectionStateChanged = mSelectedParts != selBefore;
13442 mSelectedParts = selectedParts();
13443 if (mSelectableParts.testFlag(spLegendBox))
13445 SelectableParts selBefore = mSelectedParts;
13446 setSelectedParts(selectedParts() & ~spLegendBox);
13447 if (selectionStateChanged)
13448 *selectionStateChanged = mSelectedParts != selBefore;
13467 Q_UNUSED(parentPlot)
13509 mFont(QFont(QLatin1String(
"sans serif"), 13*1.5, QFont::Bold)),
13511 mSelectedFont(QFont(QLatin1String(
"sans serif"), 13*1.6, QFont::Bold)),
13519 mFont = QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.5, QFont::Bold);
13520 mSelectedFont = QFont(parentPlot->font().family(), parentPlot->font().pointSize()*1.6, QFont::Bold);
13532 mFont(QFont(parentPlot->
font().family(), parentPlot->
font().pointSize()*1.5, QFont::Bold)),
13534 mSelectedFont(QFont(parentPlot->
font().family(), parentPlot->
font().pointSize()*1.6, QFont::Bold)),
13641 QFontMetrics metrics(
mFont);
13642 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size();
13651 QFontMetrics metrics(
mFont);
13652 QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter,
mText).size();
13654 result.setWidth(QWIDGETSIZE_MAX);
13667 if (selectionStateChanged)
13668 *selectionStateChanged =
mSelected != selBefore;
13679 if (selectionStateChanged)
13680 *selectionStateChanged =
mSelected != selBefore;
13807 mDataScaleType(
QCPAxis::stLinear),
13826 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
13838 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
13852 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
13872 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
13879 double logBaseTransfer = 10;
13880 QString labelTransfer;
13886 logBaseTransfer =
mColorAxis.data()->scaleLogBase();
13902 mColorAxis.data()->setScaleLogBase(logBaseTransfer);
13966 mAxisRect.data()->mGradientImageInvalidated =
true;
13979 qDebug() << Q_FUNC_INFO <<
"internal color axis undefined";
14005 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14025 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14040 QList<QCPColorMap*> result;
14044 if (cm->colorScale() ==
this)
14058 QList<QCPColorMap*> maps =
colorMaps();
14060 bool haveRange =
false;
14064 for (
int i=0; i<maps.size(); ++i)
14066 if (!maps.at(i)->realVisibility() && onlyVisibleMaps)
14069 if (maps.at(i)->colorScale() ==
this)
14071 bool currentFoundRange =
true;
14072 mapRange = maps.at(i)->data()->dataBounds();
14075 if (mapRange.
lower <= 0 && mapRange.
upper > 0)
14077 else if (mapRange.
lower <= 0 && mapRange.
upper <= 0)
14078 currentFoundRange =
false;
14079 }
else if (sign == -1)
14081 if (mapRange.
upper >= 0 && mapRange.
lower < 0)
14083 else if (mapRange.
upper >= 0 && mapRange.
lower >= 0)
14084 currentFoundRange =
false;
14086 if (currentFoundRange)
14089 newRange = mapRange;
14091 newRange.
expand(mapRange);
14100 double center = (newRange.
lower+newRange.
upper)*0.5;
14121 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14162 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14165 mAxisRect.data()->mousePressEvent(event);
14173 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14176 mAxisRect.data()->mouseMoveEvent(event);
14184 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14187 mAxisRect.data()->mouseReleaseEvent(event);
14195 qDebug() << Q_FUNC_INFO <<
"internal axis rect was deleted";
14221 mParentColorScale(parentColorScale),
14222 mGradientImageInvalidated(true)
14232 connect(
axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)),
this, SLOT(
axisSelectionChanged(QCPAxis::SelectableParts)));
14233 connect(
axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)),
this, SLOT(
axisSelectableChanged(QCPAxis::SelectableParts)));
14261 bool mirrorHorz =
false;
14262 bool mirrorVert =
false;
14269 painter->drawImage(
rect().adjusted(0, -1, 0, -1),
mGradientImage.mirrored(mirrorHorz, mirrorVert));
14280 if (
rect().isEmpty())
14285 QVector<double> data(n);
14286 for (
int i=0; i<n; ++i)
14291 h =
rect().height();
14293 QVector<QRgb*> pixels;
14294 for (
int y=0; y<h; ++y)
14295 pixels.append(reinterpret_cast<QRgb*>(
mGradientImage.scanLine(y)));
14297 for (
int y=1; y<h; ++y)
14298 memcpy(pixels.at(y), pixels.first(), n*
sizeof(QRgb));
14301 w =
rect().width();
14304 for (
int y=0; y<h; ++y)
14306 QRgb *pixels =
reinterpret_cast<QRgb*
>(
mGradientImage.scanLine(y));
14308 for (
int x=0; x<w; ++x)
14309 pixels[x] = lineColor;
14326 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis*>(sender()))
14327 if (senderAxis->axisType() == type)
14351 if (
QCPAxis *senderAxis = qobject_cast<QCPAxis*>(sender()))
14352 if (senderAxis->axisType() == type)
14482 setPen(QPen(Qt::blue, 0));
14515 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
14537 int n = key.size();
14538 n = qMin(n, value.size());
14540 for (
int i=0; i<n; ++i)
14542 newData.
key = key[i];
14543 newData.value = value[i];
14544 mData->insertMulti(newData.key, newData);
14560 int n = key.size();
14561 n = qMin(n, value.size());
14562 n = qMin(n, valueError.size());
14564 for (
int i=0; i<n; ++i)
14566 newData.
key = key[i];
14567 newData.value = value[i];
14568 newData.valueErrorMinus = valueError[i];
14569 newData.valueErrorPlus = valueError[i];
14570 mData->insertMulti(key[i], newData);
14583 void QCPGraph::setDataValueError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &valueErrorMinus,
const QVector<double> &valueErrorPlus)
14586 int n = key.size();
14587 n = qMin(n, value.size());
14588 n = qMin(n, valueErrorMinus.size());
14589 n = qMin(n, valueErrorPlus.size());
14591 for (
int i=0; i<n; ++i)
14593 newData.
key = key[i];
14594 newData.value = value[i];
14595 newData.valueErrorMinus = valueErrorMinus[i];
14596 newData.valueErrorPlus = valueErrorPlus[i];
14597 mData->insertMulti(key[i], newData);
14613 int n = key.size();
14614 n = qMin(n, value.size());
14615 n = qMin(n, keyError.size());
14617 for (
int i=0; i<n; ++i)
14619 newData.
key = key[i];
14620 newData.value = value[i];
14621 newData.keyErrorMinus = keyError[i];
14622 newData.keyErrorPlus = keyError[i];
14623 mData->insertMulti(key[i], newData);
14636 void QCPGraph::setDataKeyError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyErrorMinus,
const QVector<double> &keyErrorPlus)
14639 int n = key.size();
14640 n = qMin(n, value.size());
14641 n = qMin(n, keyErrorMinus.size());
14642 n = qMin(n, keyErrorPlus.size());
14644 for (
int i=0; i<n; ++i)
14646 newData.
key = key[i];
14647 newData.value = value[i];
14648 newData.keyErrorMinus = keyErrorMinus[i];
14649 newData.keyErrorPlus = keyErrorPlus[i];
14650 mData->insertMulti(key[i], newData);
14663 void QCPGraph::setDataBothError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyError,
const QVector<double> &valueError)
14666 int n = key.size();
14667 n = qMin(n, value.size());
14668 n = qMin(n, valueError.size());
14669 n = qMin(n, keyError.size());
14671 for (
int i=0; i<n; ++i)
14673 newData.
key = key[i];
14674 newData.value = value[i];
14675 newData.keyErrorMinus = keyError[i];
14676 newData.keyErrorPlus = keyError[i];
14677 newData.valueErrorMinus = valueError[i];
14678 newData.valueErrorPlus = valueError[i];
14679 mData->insertMulti(key[i], newData);
14692 void QCPGraph::setDataBothError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyErrorMinus,
const QVector<double> &keyErrorPlus,
const QVector<double> &valueErrorMinus,
const QVector<double> &valueErrorPlus)
14695 int n = key.size();
14696 n = qMin(n, value.size());
14697 n = qMin(n, valueErrorMinus.size());
14698 n = qMin(n, valueErrorPlus.size());
14699 n = qMin(n, keyErrorMinus.size());
14700 n = qMin(n, keyErrorPlus.size());
14702 for (
int i=0; i<n; ++i)
14704 newData.
key = key[i];
14705 newData.value = value[i];
14706 newData.keyErrorMinus = keyErrorMinus[i];
14707 newData.keyErrorPlus = keyErrorPlus[i];
14708 newData.valueErrorMinus = valueErrorMinus[i];
14709 newData.valueErrorPlus = valueErrorPlus[i];
14710 mData->insertMulti(key[i], newData);
14795 if (targetGraph ==
this)
14797 qDebug() << Q_FUNC_INFO <<
"targetGraph is this graph itself";
14804 qDebug() << Q_FUNC_INFO <<
"targetGraph not in same plot";
14858 mData->unite(dataMap);
14871 mData->insertMulti(data.
key, data);
14886 newData.
value = value;
14887 mData->insertMulti(newData.
key, newData);
14900 int n = qMin(keys.size(), values.size());
14902 for (
int i=0; i<n; ++i)
14904 newData.
key = keys[i];
14905 newData.value = values[i];
14906 mData->insertMulti(newData.key, newData);
14916 QCPDataMap::iterator it =
mData->begin();
14917 while (it !=
mData->end() && it.key() < key)
14918 it =
mData->erase(it);
14927 if (
mData->isEmpty())
return;
14928 QCPDataMap::iterator it =
mData->upperBound(key);
14929 while (it !=
mData->end())
14930 it =
mData->erase(it);
14942 if (fromKey >= toKey ||
mData->isEmpty())
return;
14943 QCPDataMap::iterator it =
mData->upperBound(fromKey);
14944 QCPDataMap::iterator itEnd =
mData->upperBound(toKey);
14945 while (it != itEnd)
14946 it =
mData->erase(it);
14959 mData->remove(key);
14977 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
14979 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
15009 if (
mData->isEmpty())
return;
15012 if (!keyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
15045 if (
mData->isEmpty())
return;
15048 if (!valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid value axis";
return; }
15073 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15074 if (
mKeyAxis.data()->range().size() <= 0 ||
mData->isEmpty())
return;
15078 QVector<QPointF> *lineData =
new QVector<QPointF>;
15079 QVector<QCPData> *scatterData = 0;
15081 scatterData =
new QVector<QCPData>;
15087 #ifdef QCUSTOMPLOT_CHECK_DATA 15088 QCPDataMap::const_iterator it;
15089 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
15094 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"invalid." <<
"Plottable name:" <<
name();
15114 delete scatterData;
15121 if (
mBrush.style() != Qt::NoBrush)
15124 painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0),
mBrush);
15131 painter->
drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0));
15141 scaledStyle.
setPixmap(scaledStyle.
pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
15143 scaledStyle.
drawShape(painter, QRectF(rect).center());
15214 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15215 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as linePixelData";
return; }
15217 QVector<QCPData> lineData;
15219 linePixelData->reserve(lineData.size()+2);
15220 linePixelData->resize(lineData.size());
15225 for (
int i=0; i<lineData.size(); ++i)
15227 (*linePixelData)[i].setX(valueAxis->
coordToPixel(lineData.at(i).value));
15228 (*linePixelData)[i].setY(keyAxis->
coordToPixel(lineData.at(i).key));
15232 for (
int i=0; i<lineData.size(); ++i)
15234 (*linePixelData)[i].setX(keyAxis->
coordToPixel(lineData.at(i).key));
15235 (*linePixelData)[i].setY(valueAxis->
coordToPixel(lineData.at(i).value));
15255 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15256 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
return; }
15258 QVector<QCPData> lineData;
15260 linePixelData->reserve(lineData.size()*2+2);
15261 linePixelData->resize(lineData.size()*2);
15266 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15268 for (
int i=0; i<lineData.size(); ++i)
15271 (*linePixelData)[i*2+0].setX(lastValue);
15272 (*linePixelData)[i*2+0].setY(key);
15273 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15274 (*linePixelData)[i*2+1].setX(lastValue);
15275 (*linePixelData)[i*2+1].setY(key);
15279 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15281 for (
int i=0; i<lineData.size(); ++i)
15284 (*linePixelData)[i*2+0].setX(key);
15285 (*linePixelData)[i*2+0].setY(lastValue);
15286 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15287 (*linePixelData)[i*2+1].setX(key);
15288 (*linePixelData)[i*2+1].setY(lastValue);
15308 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15309 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
return; }
15311 QVector<QCPData> lineData;
15313 linePixelData->reserve(lineData.size()*2+2);
15314 linePixelData->resize(lineData.size()*2);
15319 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15321 for (
int i=0; i<lineData.size(); ++i)
15323 value = valueAxis->
coordToPixel(lineData.at(i).value);
15324 (*linePixelData)[i*2+0].setX(value);
15325 (*linePixelData)[i*2+0].setY(lastKey);
15327 (*linePixelData)[i*2+1].setX(value);
15328 (*linePixelData)[i*2+1].setY(lastKey);
15332 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15334 for (
int i=0; i<lineData.size(); ++i)
15336 value = valueAxis->
coordToPixel(lineData.at(i).value);
15337 (*linePixelData)[i*2+0].setX(lastKey);
15338 (*linePixelData)[i*2+0].setY(value);
15340 (*linePixelData)[i*2+1].setX(lastKey);
15341 (*linePixelData)[i*2+1].setY(value);
15361 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15362 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as lineData";
return; }
15364 QVector<QCPData> lineData;
15366 linePixelData->reserve(lineData.size()*2+2);
15367 linePixelData->resize(lineData.size()*2);
15371 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15372 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15374 (*linePixelData)[0].setX(lastValue);
15375 (*linePixelData)[0].setY(lastKey);
15376 for (
int i=1; i<lineData.size(); ++i)
15378 key = (keyAxis->
coordToPixel(lineData.at(i).key)+lastKey)*0.5;
15379 (*linePixelData)[i*2-1].setX(lastValue);
15380 (*linePixelData)[i*2-1].setY(key);
15381 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15383 (*linePixelData)[i*2+0].setX(lastValue);
15384 (*linePixelData)[i*2+0].setY(key);
15386 (*linePixelData)[lineData.size()*2-1].setX(lastValue);
15387 (*linePixelData)[lineData.size()*2-1].setY(lastKey);
15390 double lastKey = keyAxis->
coordToPixel(lineData.first().key);
15391 double lastValue = valueAxis->
coordToPixel(lineData.first().value);
15393 (*linePixelData)[0].setX(lastKey);
15394 (*linePixelData)[0].setY(lastValue);
15395 for (
int i=1; i<lineData.size(); ++i)
15397 key = (keyAxis->
coordToPixel(lineData.at(i).key)+lastKey)*0.5;
15398 (*linePixelData)[i*2-1].setX(key);
15399 (*linePixelData)[i*2-1].setY(lastValue);
15400 lastValue = valueAxis->
coordToPixel(lineData.at(i).value);
15402 (*linePixelData)[i*2+0].setX(key);
15403 (*linePixelData)[i*2+0].setY(lastValue);
15405 (*linePixelData)[lineData.size()*2-1].setX(lastKey);
15406 (*linePixelData)[lineData.size()*2-1].setY(lastValue);
15426 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15427 if (!linePixelData) { qDebug() << Q_FUNC_INFO <<
"null pointer passed as linePixelData";
return; }
15429 QVector<QCPData> lineData;
15431 linePixelData->resize(lineData.size()*2);
15438 for (
int i=0; i<lineData.size(); ++i)
15441 (*linePixelData)[i*2+0].setX(zeroPointX);
15442 (*linePixelData)[i*2+0].setY(key);
15443 (*linePixelData)[i*2+1].setX(valueAxis->
coordToPixel(lineData.at(i).value));
15444 (*linePixelData)[i*2+1].setY(key);
15450 for (
int i=0; i<lineData.size(); ++i)
15453 (*linePixelData)[i*2+0].setX(key);
15454 (*linePixelData)[i*2+0].setY(zeroPointY);
15455 (*linePixelData)[i*2+1].setX(key);
15456 (*linePixelData)[i*2+1].setY(valueAxis->
coordToPixel(lineData.at(i).value));
15484 painter->
setPen(Qt::NoPen);
15486 painter->drawPolygon(QPolygonF(*lineData));
15491 painter->
setPen(Qt::NoPen);
15510 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15519 for (
int i=0; i<scatterData->size(); ++i)
15523 for (
int i=0; i<scatterData->size(); ++i)
15533 for (
int i=0; i<scatterData->size(); ++i)
15534 if (!qIsNaN(scatterData->at(i).value))
15538 for (
int i=0; i<scatterData->size(); ++i)
15539 if (!qIsNaN(scatterData->at(i).value))
15556 if (
mainPen().style() != Qt::NoPen &&
mainPen().color().alpha() != 0)
15560 painter->setBrush(Qt::NoBrush);
15579 painter->pen().style() == Qt::SolidLine &&
15584 bool lastIsNan =
false;
15585 const int lineDataSize = lineData->size();
15586 while (i < lineDataSize && (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x())))
15589 while (i < lineDataSize)
15591 if (!qIsNaN(lineData->at(i).y()) && !qIsNaN(lineData->at(i).x()))
15594 painter->
drawLine(lineData->at(i-1), lineData->at(i));
15603 int segmentStart = 0;
15605 const int lineDataSize = lineData->size();
15606 while (i < lineDataSize)
15608 if (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x()))
15610 painter->drawPolyline(lineData->constData()+segmentStart, i-segmentStart);
15611 segmentStart = i+1;
15616 painter->drawPolyline(lineData->constData()+segmentStart, lineDataSize-segmentStart);
15631 if (
mainPen().style() != Qt::NoPen &&
mainPen().color().alpha() != 0)
15635 pen.setCapStyle(Qt::FlatCap);
15637 painter->setBrush(Qt::NoBrush);
15638 painter->drawLines(*lineData);
15658 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15660 QCPDataMap::const_iterator lower, upper;
15662 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
15670 maxCount = 2*keyPixelSpan+2;
15678 QCPDataMap::const_iterator it = lower;
15679 QCPDataMap::const_iterator upperEnd = upper+1;
15680 double minValue = it.value().value;
15681 double maxValue = it.value().value;
15682 QCPDataMap::const_iterator currentIntervalFirstPoint = it;
15686 double lastIntervalEndKey = currentIntervalStartKey;
15687 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
15689 int intervalDataCount = 1;
15691 while (it != upperEnd)
15693 if (it.key() < currentIntervalStartKey+keyEpsilon)
15695 if (it.value().value < minValue)
15696 minValue = it.value().value;
15697 else if (it.value().value > maxValue)
15698 maxValue = it.value().value;
15699 ++intervalDataCount;
15702 if (intervalDataCount >= 2)
15704 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon)
15705 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint.value().value));
15706 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue));
15707 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue));
15708 if (it.key() > currentIntervalStartKey+keyEpsilon*2)
15709 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.8, (it-1).value().value));
15711 lineData->append(
QCPData(currentIntervalFirstPoint.key(), currentIntervalFirstPoint.value().value));
15712 lastIntervalEndKey = (it-1).value().key;
15713 minValue = it.value().value;
15714 maxValue = it.value().value;
15715 currentIntervalFirstPoint = it;
15717 if (keyEpsilonVariable)
15718 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
15719 intervalDataCount = 1;
15724 if (intervalDataCount >= 2)
15726 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon)
15727 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint.value().value));
15728 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.25, minValue));
15729 lineData->append(
QCPData(currentIntervalStartKey+keyEpsilon*0.75, maxValue));
15731 lineData->append(
QCPData(currentIntervalFirstPoint.key(), currentIntervalFirstPoint.value().value));
15736 double valueMaxRange = valueAxis->
range().
upper;
15737 double valueMinRange = valueAxis->
range().
lower;
15738 QCPDataMap::const_iterator it = lower;
15739 QCPDataMap::const_iterator upperEnd = upper+1;
15740 double minValue = it.value().value;
15741 double maxValue = it.value().value;
15742 QCPDataMap::const_iterator minValueIt = it;
15743 QCPDataMap::const_iterator maxValueIt = it;
15744 QCPDataMap::const_iterator currentIntervalStart = it;
15748 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
15750 int intervalDataCount = 1;
15752 while (it != upperEnd)
15754 if (it.key() < currentIntervalStartKey+keyEpsilon)
15756 if (it.value().value < minValue && it.value().value > valueMinRange && it.value().value < valueMaxRange)
15758 minValue = it.value().value;
15760 }
else if (it.value().value > maxValue && it.value().value > valueMinRange && it.value().value < valueMaxRange)
15762 maxValue = it.value().value;
15765 ++intervalDataCount;
15768 if (intervalDataCount >= 2)
15772 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0)));
15773 QCPDataMap::const_iterator intervalIt = currentIntervalStart;
15775 while (intervalIt != it)
15777 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt.value().value > valueMinRange && intervalIt.value().value < valueMaxRange)
15778 scatterData->append(intervalIt.value());
15782 }
else if (currentIntervalStart.value().value > valueMinRange && currentIntervalStart.value().value < valueMaxRange)
15783 scatterData->append(currentIntervalStart.value());
15784 minValue = it.value().value;
15785 maxValue = it.value().value;
15786 currentIntervalStart = it;
15788 if (keyEpsilonVariable)
15789 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->
pixelToCoord(keyAxis->
coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
15790 intervalDataCount = 1;
15795 if (intervalDataCount >= 2)
15799 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0)));
15800 QCPDataMap::const_iterator intervalIt = currentIntervalStart;
15802 while (intervalIt != it)
15804 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt.value().value > valueMinRange && intervalIt.value().value < valueMaxRange)
15805 scatterData->append(intervalIt.value());
15809 }
else if (currentIntervalStart.value().value > valueMinRange && currentIntervalStart.value().value < valueMaxRange)
15810 scatterData->append(currentIntervalStart.value());
15814 QVector<QCPData> *dataVector = 0;
15816 dataVector = lineData;
15817 else if (scatterData)
15818 dataVector = scatterData;
15821 QCPDataMap::const_iterator it = lower;
15822 QCPDataMap::const_iterator upperEnd = upper+1;
15823 dataVector->reserve(dataCount+2);
15824 while (it != upperEnd)
15826 dataVector->append(it.value());
15830 if (lineData && scatterData)
15831 *scatterData = *dataVector;
15844 if (qIsNaN(data.
value))
15848 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
15866 if (a-y > skipSymbolMargin)
15867 painter->
drawLine(QLineF(x, a, x, y+skipSymbolMargin));
15868 if (y-b > skipSymbolMargin)
15869 painter->
drawLine(QLineF(x, y-skipSymbolMargin, x, b));
15871 painter->
drawLine(QLineF(x, a, x, b));
15873 painter->
drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a));
15874 painter->
drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b));
15885 if (x-a > skipSymbolMargin)
15886 painter->
drawLine(QLineF(a, y, x-skipSymbolMargin, y));
15887 if (b-x > skipSymbolMargin)
15888 painter->
drawLine(QLineF(x+skipSymbolMargin, y, b, y));
15890 painter->
drawLine(QLineF(a, y, b, y));
15892 painter->
drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf));
15893 painter->
drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf));
15907 if (x-a > skipSymbolMargin)
15908 painter->
drawLine(QLineF(a, y, x-skipSymbolMargin, y));
15909 if (b-x > skipSymbolMargin)
15910 painter->
drawLine(QLineF(x+skipSymbolMargin, y, b, y));
15912 painter->
drawLine(QLineF(a, y, b, y));
15914 painter->
drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf));
15915 painter->
drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf));
15926 if (a-y > skipSymbolMargin)
15927 painter->
drawLine(QLineF(x, a, x, y+skipSymbolMargin));
15928 if (y-b > skipSymbolMargin)
15929 painter->
drawLine(QLineF(x, y-skipSymbolMargin, x, b));
15931 painter->
drawLine(QLineF(x, a, x, b));
15933 painter->
drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a));
15934 painter->
drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b));
15955 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
15956 if (
mData->isEmpty())
15958 lower =
mData->constEnd();
15959 upper =
mData->constEnd();
15964 QCPDataMap::const_iterator lbound =
mData->lowerBound(
mKeyAxis.data()->range().lower);
15965 QCPDataMap::const_iterator ubound =
mData->upperBound(
mKeyAxis.data()->range().upper);
15966 bool lowoutlier = lbound !=
mData->constBegin();
15967 bool highoutlier = ubound !=
mData->constEnd();
15969 lower = (lowoutlier ? lbound-1 : lbound);
15970 upper = (highoutlier ? ubound : ubound-1);
15985 if (upper ==
mData->constEnd() && lower ==
mData->constEnd())
15987 QCPDataMap::const_iterator it = lower;
15989 while (it != upper && count < maxCount)
16014 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
16017 if (
mKeyAxis.data()->orientation() == Qt::Vertical)
16036 lineData->remove(lineData->size()-2, 2);
16057 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPointF(); }
16065 point.setY(lowerKey);
16069 point.setY(lowerKey);
16072 point.setX(lowerKey);
16076 point.setX(lowerKey);
16090 point.setY(lowerKey);
16093 point.setX(lowerKey);
16122 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPointF(); }
16130 point.setY(upperKey);
16134 point.setY(upperKey);
16137 point.setX(upperKey);
16141 point.setX(upperKey);
16155 point.setY(upperKey);
16158 point.setX(upperKey);
16181 return QPolygonF();
16185 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPolygonF(); }
16186 if (!
mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"channel fill target key axis invalid";
return QPolygonF(); }
16189 return QPolygonF();
16191 if (lineData->isEmpty())
return QPolygonF();
16192 QVector<QPointF> otherData;
16194 if (otherData.isEmpty())
return QPolygonF();
16195 QVector<QPointF> thisData;
16196 thisData.reserve(lineData->size()+otherData.size());
16197 for (
int i=0; i<lineData->size(); ++i)
16198 thisData << lineData->at(i);
16201 QVector<QPointF> *staticData = &thisData;
16202 QVector<QPointF> *croppedData = &otherData;
16209 if (staticData->first().x() > staticData->last().x())
16211 int size = staticData->size();
16212 for (
int i=0; i<size/2; ++i)
16213 qSwap((*staticData)[i], (*staticData)[size-1-i]);
16215 if (croppedData->first().x() > croppedData->last().x())
16217 int size = croppedData->size();
16218 for (
int i=0; i<size/2; ++i)
16219 qSwap((*croppedData)[i], (*croppedData)[size-1-i]);
16222 if (staticData->first().x() < croppedData->first().x())
16223 qSwap(staticData, croppedData);
16224 int lowBound =
findIndexBelowX(croppedData, staticData->first().x());
16225 if (lowBound == -1)
return QPolygonF();
16226 croppedData->remove(0, lowBound);
16229 if (croppedData->size() < 2)
return QPolygonF();
16231 if (croppedData->at(1).x()-croppedData->at(0).x() != 0)
16232 slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x());
16235 (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x()));
16236 (*croppedData)[0].setX(staticData->first().x());
16239 if (staticData->last().x() > croppedData->last().x())
16240 qSwap(staticData, croppedData);
16241 int highBound =
findIndexAboveX(croppedData, staticData->last().x());
16242 if (highBound == -1)
return QPolygonF();
16243 croppedData->remove(highBound+1, croppedData->size()-(highBound+1));
16246 if (croppedData->size() < 2)
return QPolygonF();
16247 int li = croppedData->size()-1;
16248 if (croppedData->at(li).x()-croppedData->at(li-1).x() != 0)
16249 slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x());
16252 (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x()));
16253 (*croppedData)[li].setX(staticData->last().x());
16260 if (staticData->first().y() < staticData->last().y())
16262 int size = staticData->size();
16263 for (
int i=0; i<size/2; ++i)
16264 qSwap((*staticData)[i], (*staticData)[size-1-i]);
16266 if (croppedData->first().y() < croppedData->last().y())
16268 int size = croppedData->size();
16269 for (
int i=0; i<size/2; ++i)
16270 qSwap((*croppedData)[i], (*croppedData)[size-1-i]);
16273 if (staticData->first().y() > croppedData->first().y())
16274 qSwap(staticData, croppedData);
16275 int lowBound =
findIndexAboveY(croppedData, staticData->first().y());
16276 if (lowBound == -1)
return QPolygonF();
16277 croppedData->remove(0, lowBound);
16280 if (croppedData->size() < 2)
return QPolygonF();
16282 if (croppedData->at(1).y()-croppedData->at(0).y() != 0)
16283 slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y());
16286 (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y()));
16287 (*croppedData)[0].setY(staticData->first().y());
16290 if (staticData->last().y() < croppedData->last().y())
16291 qSwap(staticData, croppedData);
16292 int highBound =
findIndexBelowY(croppedData, staticData->last().y());
16293 if (highBound == -1)
return QPolygonF();
16294 croppedData->remove(highBound+1, croppedData->size()-(highBound+1));
16297 if (croppedData->size() < 2)
return QPolygonF();
16298 int li = croppedData->size()-1;
16299 if (croppedData->at(li).y()-croppedData->at(li-1).y() != 0)
16300 slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y());
16303 (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y()));
16304 (*croppedData)[li].setY(staticData->last().y());
16308 for (
int i=otherData.size()-1; i>=0; --i)
16309 thisData << otherData.at(i);
16310 return QPolygonF(thisData);
16322 for (
int i=data->size()-1; i>=0; --i)
16324 if (data->at(i).x() < x)
16326 if (i<data->
size()-1)
16329 return data->size()-1;
16344 for (
int i=0; i<data->size(); ++i)
16346 if (data->at(i).x() > x)
16366 for (
int i=0; i<data->size(); ++i)
16368 if (data->at(i).y() < y)
16390 if (
mData->isEmpty())
16399 QVector<QCPData> scatterData;
16401 if (scatterData.size() > 0)
16404 for (
int i=0; i<scatterData.size(); ++i)
16406 double currentDistSqr = QVector2D(
coordsToPixels(scatterData.at(i).key, scatterData.at(i).value)-pixelPoint).lengthSquared();
16407 if (currentDistSqr < minDistSqr)
16408 minDistSqr = currentDistSqr;
16410 return qSqrt(minDistSqr);
16416 QVector<QPointF> lineData;
16418 if (lineData.size() > 1)
16424 for (
int i=0; i<lineData.size()-1; i+=2)
16426 double currentDistSqr =
distSqrToLine(lineData.at(i), lineData.at(i+1), pixelPoint);
16427 if (currentDistSqr < minDistSqr)
16428 minDistSqr = currentDistSqr;
16433 for (
int i=0; i<lineData.size()-1; ++i)
16435 double currentDistSqr =
distSqrToLine(lineData.at(i), lineData.at(i+1), pixelPoint);
16436 if (currentDistSqr < minDistSqr)
16437 minDistSqr = currentDistSqr;
16440 return qSqrt(minDistSqr);
16441 }
else if (lineData.size() > 0)
16443 return QVector2D(lineData.at(0)-pixelPoint).length();
16459 for (
int i=data->size()-1; i>=0; --i)
16461 if (data->at(i).y() > y)
16463 if (i<data->
size()-1)
16466 return data->size()-1;
16477 return getKeyRange(foundRange, inSignDomain,
true);
16497 bool haveLower =
false;
16498 bool haveUpper =
false;
16500 double current, currentErrorMinus, currentErrorPlus;
16502 if (inSignDomain ==
sdBoth)
16504 QCPDataMap::const_iterator it =
mData->constBegin();
16505 while (it !=
mData->constEnd())
16507 if (!qIsNaN(it.value().value))
16509 current = it.value().key;
16510 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
16511 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
16512 if (current-currentErrorMinus < range.
lower || !haveLower)
16514 range.
lower = current-currentErrorMinus;
16517 if (current+currentErrorPlus > range.
upper || !haveUpper)
16519 range.
upper = current+currentErrorPlus;
16527 QCPDataMap::const_iterator it =
mData->constBegin();
16528 while (it !=
mData->constEnd())
16530 if (!qIsNaN(it.value().value))
16532 current = it.value().key;
16533 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
16534 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
16535 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus < 0)
16537 range.
lower = current-currentErrorMinus;
16540 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus < 0)
16542 range.
upper = current+currentErrorPlus;
16547 if ((current < range.
lower || !haveLower) && current < 0)
16549 range.
lower = current;
16552 if ((current > range.
upper || !haveUpper) && current < 0)
16554 range.
upper = current;
16563 QCPDataMap::const_iterator it =
mData->constBegin();
16564 while (it !=
mData->constEnd())
16566 if (!qIsNaN(it.value().value))
16568 current = it.value().key;
16569 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
16570 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
16571 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus > 0)
16573 range.
lower = current-currentErrorMinus;
16576 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus > 0)
16578 range.
upper = current+currentErrorPlus;
16583 if ((current < range.
lower || !haveLower) && current > 0)
16585 range.
lower = current;
16588 if ((current > range.
upper || !haveUpper) && current > 0)
16590 range.
upper = current;
16599 foundRange = haveLower && haveUpper;
16612 bool haveLower =
false;
16613 bool haveUpper =
false;
16615 double current, currentErrorMinus, currentErrorPlus;
16617 if (inSignDomain ==
sdBoth)
16619 QCPDataMap::const_iterator it =
mData->constBegin();
16620 while (it !=
mData->constEnd())
16622 current = it.value().value;
16623 if (!qIsNaN(current))
16625 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
16626 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
16627 if (current-currentErrorMinus < range.
lower || !haveLower)
16629 range.
lower = current-currentErrorMinus;
16632 if (current+currentErrorPlus > range.
upper || !haveUpper)
16634 range.
upper = current+currentErrorPlus;
16642 QCPDataMap::const_iterator it =
mData->constBegin();
16643 while (it !=
mData->constEnd())
16645 current = it.value().value;
16646 if (!qIsNaN(current))
16648 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
16649 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
16650 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus < 0)
16652 range.
lower = current-currentErrorMinus;
16655 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus < 0)
16657 range.
upper = current+currentErrorPlus;
16662 if ((current < range.
lower || !haveLower) && current < 0)
16664 range.
lower = current;
16667 if ((current > range.
upper || !haveUpper) && current < 0)
16669 range.
upper = current;
16678 QCPDataMap::const_iterator it =
mData->constBegin();
16679 while (it !=
mData->constEnd())
16681 current = it.value().value;
16682 if (!qIsNaN(current))
16684 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
16685 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
16686 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus > 0)
16688 range.
lower = current-currentErrorMinus;
16691 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus > 0)
16693 range.
upper = current+currentErrorPlus;
16698 if ((current < range.
lower || !haveLower) && current > 0)
16700 range.
lower = current;
16703 if ((current > range.
upper || !haveUpper) && current > 0)
16705 range.
upper = current;
16714 foundRange = haveLower && haveUpper;
16804 mPen.setColor(Qt::blue);
16805 mPen.setStyle(Qt::SolidLine);
16806 mBrush.setColor(Qt::blue);
16807 mBrush.setStyle(Qt::NoBrush);
16833 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
16852 void QCPCurve::setData(
const QVector<double> &t,
const QVector<double> &key,
const QVector<double> &value)
16856 n = qMin(n, key.size());
16857 n = qMin(n, value.size());
16859 for (
int i=0; i<n; ++i)
16862 newData.key = key[i];
16863 newData.value = value[i];
16864 mData->insertMulti(newData.t, newData);
16876 int n = key.size();
16877 n = qMin(n, value.size());
16879 for (
int i=0; i<n; ++i)
16882 newData.key = key[i];
16883 newData.value = value[i];
16884 mData->insertMulti(newData.t, newData);
16918 mData->unite(dataMap);
16927 mData->insertMulti(data.
t, data);
16939 newData.
value = value;
16940 mData->insertMulti(newData.
t, newData);
16954 if (!
mData->isEmpty())
16955 newData.
t = (
mData->constEnd()-1).key()+1;
16959 newData.
value = value;
16960 mData->insertMulti(newData.
t, newData);
16967 void QCPCurve::addData(
const QVector<double> &ts,
const QVector<double> &keys,
const QVector<double> &values)
16970 n = qMin(n, keys.size());
16971 n = qMin(n, values.size());
16973 for (
int i=0; i<n; ++i)
16976 newData.key = keys[i];
16977 newData.value = values[i];
16978 mData->insertMulti(newData.t, newData);
16988 QCPCurveDataMap::iterator it =
mData->begin();
16989 while (it !=
mData->end() && it.key() < t)
16990 it =
mData->erase(it);
16999 if (
mData->isEmpty())
return;
17000 QCPCurveDataMap::iterator it =
mData->upperBound(t);
17001 while (it !=
mData->end())
17002 it =
mData->erase(it);
17014 if (fromt >= tot ||
mData->isEmpty())
return;
17015 QCPCurveDataMap::iterator it =
mData->upperBound(fromt);
17016 QCPCurveDataMap::iterator itEnd =
mData->upperBound(tot);
17017 while (it != itEnd)
17018 it =
mData->erase(it);
17050 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
17052 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
17061 if (
mData->isEmpty())
return;
17064 QVector<QPointF> *lineData =
new QVector<QPointF>;
17070 #ifdef QCUSTOMPLOT_CHECK_DATA 17071 QCPCurveDataMap::const_iterator it;
17072 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
17076 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"invalid." <<
"Plottable name:" <<
name();
17084 painter->
setPen(Qt::NoPen);
17086 painter->drawPolygon(QPolygonF(*lineData));
17094 painter->setBrush(Qt::NoBrush);
17097 painter->pen().style() == Qt::SolidLine &&
17102 bool lastIsNan =
false;
17103 const int lineDataSize = lineData->size();
17104 while (i < lineDataSize && (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x())))
17107 while (i < lineDataSize)
17109 if (!qIsNaN(lineData->at(i).y()) && !qIsNaN(lineData->at(i).x()))
17112 painter->
drawLine(lineData->at(i-1), lineData->at(i));
17121 int segmentStart = 0;
17123 const int lineDataSize = lineData->size();
17124 while (i < lineDataSize)
17126 if (qIsNaN(lineData->at(i).y()) || qIsNaN(lineData->at(i).x()))
17128 painter->drawPolyline(lineData->constData()+segmentStart, i-segmentStart);
17129 segmentStart = i+1;
17134 painter->drawPolyline(lineData->constData()+segmentStart, lineDataSize-segmentStart);
17150 if (
mBrush.style() != Qt::NoBrush)
17153 painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0),
mBrush);
17160 painter->
drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0));
17170 scaledStyle.
setPixmap(scaledStyle.
pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
17172 scaledStyle.
drawShape(painter, QRectF(rect).center());
17191 for (
int i=0; i<pointData->size(); ++i)
17192 if (!qIsNaN(pointData->at(i).x()) && !qIsNaN(pointData->at(i).y()))
17213 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
17216 double strokeMargin = qMax(qreal(1.0), qreal(
mainPen().widthF()*0.75));
17224 QCPCurveDataMap::const_iterator it =
mData->constBegin();
17225 QCPCurveDataMap::const_iterator prevIt =
mData->constEnd()-1;
17226 int prevRegion =
getRegion(prevIt.value().key, prevIt.value().value, rectLeft, rectTop, rectRight, rectBottom);
17227 QVector<QPointF> trailingPoints;
17228 while (it !=
mData->constEnd())
17230 currentRegion =
getRegion(it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17231 if (currentRegion != prevRegion)
17233 if (currentRegion != 5)
17235 QPointF crossA, crossB;
17236 if (prevRegion == 5)
17238 lineData->append(
getOptimizedPoint(currentRegion, it.value().key, it.value().value, prevIt.value().key, prevIt.value().value, rectLeft, rectTop, rectRight, rectBottom));
17240 *lineData <<
getOptimizedCornerPoints(prevRegion, currentRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17241 }
else if (
mayTraverse(prevRegion, currentRegion) &&
17242 getTraverse(prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom, crossA, crossB))
17245 QVector<QPointF> beforeTraverseCornerPoints, afterTraverseCornerPoints;
17246 getTraverseCornerPoints(prevRegion, currentRegion, rectLeft, rectTop, rectRight, rectBottom, beforeTraverseCornerPoints, afterTraverseCornerPoints);
17247 if (it !=
mData->constBegin())
17249 *lineData << beforeTraverseCornerPoints;
17250 lineData->append(crossA);
17251 lineData->append(crossB);
17252 *lineData << afterTraverseCornerPoints;
17255 lineData->append(crossB);
17256 *lineData << afterTraverseCornerPoints;
17257 trailingPoints << beforeTraverseCornerPoints << crossA ;
17261 *lineData <<
getOptimizedCornerPoints(prevRegion, currentRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17265 if (it ==
mData->constBegin())
17266 trailingPoints <<
getOptimizedPoint(prevRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom);
17268 lineData->append(
getOptimizedPoint(prevRegion, prevIt.value().key, prevIt.value().value, it.value().key, it.value().value, rectLeft, rectTop, rectRight, rectBottom));
17269 lineData->append(
coordsToPixels(it.value().key, it.value().value));
17273 if (currentRegion == 5)
17275 lineData->append(
coordsToPixels(it.value().key, it.value().value));
17282 prevRegion = currentRegion;
17285 *lineData << trailingPoints;
17306 int QCPCurve::getRegion(
double x,
double y,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom)
const 17312 else if (y < rectBottom)
17316 }
else if (x > rectRight)
17320 else if (y < rectBottom)
17328 else if (y < rectBottom)
17350 QPointF
QCPCurve::getOptimizedPoint(
int otherRegion,
double otherKey,
double otherValue,
double key,
double value,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom)
const 17352 double intersectKey = rectLeft;
17353 double intersectValue = rectTop;
17354 switch (otherRegion)
17358 intersectValue = rectTop;
17359 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17360 if (intersectKey < rectLeft || intersectKey > rectRight)
17362 intersectKey = rectLeft;
17363 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17369 intersectKey = rectLeft;
17370 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17375 intersectValue = rectBottom;
17376 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17377 if (intersectKey < rectLeft || intersectKey > rectRight)
17379 intersectKey = rectLeft;
17380 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17386 intersectValue = rectTop;
17387 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17396 intersectValue = rectBottom;
17397 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17402 intersectValue = rectTop;
17403 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17404 if (intersectKey < rectLeft || intersectKey > rectRight)
17406 intersectKey = rectRight;
17407 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17413 intersectKey = rectRight;
17414 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17419 intersectValue = rectBottom;
17420 intersectKey = otherKey + (key-otherKey)/(value-otherValue)*(intersectValue-otherValue);
17421 if (intersectKey < rectLeft || intersectKey > rectRight)
17423 intersectKey = rectRight;
17424 intersectValue = otherValue + (value-otherValue)/(key-otherKey)*(intersectKey-otherKey);
17450 QVector<QPointF>
QCPCurve::getOptimizedCornerPoints(
int prevRegion,
int currentRegion,
double prevKey,
double prevValue,
double key,
double value,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom)
const 17452 QVector<QPointF> result;
17453 switch (prevRegion)
17457 switch (currentRegion)
17466 if ((value-prevValue)/(key-prevKey)*(rectLeft-key)+value < rectBottom)
17477 switch (currentRegion)
17480 case 3: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17481 case 4: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last());
break; }
17482 case 6: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last());
break; }
17483 case 7: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last()); result <<
coordsToPixels(rectRight, rectTop);
break; }
17484 case 9: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectRight, rectBottom);
break; }
17490 switch (currentRegion)
17492 case 2: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17493 case 6: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17497 case 8: { result <<
coordsToPixels(rectLeft, rectBottom) <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
17499 if ((value-prevValue)/(key-prevKey)*(rectRight-key)+value < rectBottom)
17510 switch (currentRegion)
17513 case 7: { result <<
coordsToPixels(rectRight, rectTop);
break; }
17514 case 2: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last());
break; }
17515 case 8: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last());
break; }
17516 case 3: { result <<
coordsToPixels(rectLeft, rectTop); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17517 case 9: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last()); result <<
coordsToPixels(rectRight, rectBottom);
break; }
17523 switch (currentRegion)
17526 case 7: { result <<
coordsToPixels(rectRight, rectTop);
break; }
17527 case 9: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
17528 case 3: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17534 switch (currentRegion)
17536 case 3: { result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17537 case 9: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
17538 case 2: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last());
break; }
17539 case 8: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
17540 case 1: { result <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectTop);
break; }
17541 case 7: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectRight, rectTop);
break; }
17547 switch (currentRegion)
17549 case 4: { result <<
coordsToPixels(rectRight, rectTop);
break; }
17550 case 8: { result <<
coordsToPixels(rectRight, rectTop);
break; }
17554 case 6: { result <<
coordsToPixels(rectRight, rectTop) <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
17556 if ((value-prevValue)/(key-prevKey)*(rectRight-key)+value < rectBottom)
17567 switch (currentRegion)
17569 case 7: { result <<
coordsToPixels(rectRight, rectTop);
break; }
17570 case 9: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
17571 case 4: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last());
break; }
17572 case 6: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last());
break; }
17573 case 1: { result <<
coordsToPixels(rectRight, rectTop); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectTop);
break; }
17574 case 3: { result <<
coordsToPixels(rectRight, rectBottom); result.append(result.last()); result <<
coordsToPixels(rectLeft, rectBottom);
break; }
17580 switch (currentRegion)
17582 case 6: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
17583 case 8: { result <<
coordsToPixels(rectRight, rectBottom);
break; }
17586 case 2: { result <<
coordsToPixels(rectRight, rectBottom) <<
coordsToPixels(rectLeft, rectBottom); result.append(result.last());
break; }
17587 case 4: { result <<
coordsToPixels(rectRight, rectBottom) <<
coordsToPixels(rectRight, rectTop); result.append(result.last());
break; }
17589 if ((value-prevValue)/(key-prevKey)*(rectLeft-key)+value < rectBottom)
17616 switch (prevRegion)
17620 switch (currentRegion)
17625 case 3:
return false;
17626 default:
return true;
17631 switch (currentRegion)
17634 case 3:
return false;
17635 default:
return true;
17640 switch (currentRegion)
17645 case 9:
return false;
17646 default:
return true;
17651 switch (currentRegion)
17654 case 7:
return false;
17655 default:
return true;
17658 case 5:
return false;
17661 switch (currentRegion)
17664 case 9:
return false;
17665 default:
return true;
17670 switch (currentRegion)
17675 case 9:
return false;
17676 default:
return true;
17681 switch (currentRegion)
17684 case 9:
return false;
17685 default:
return true;
17690 switch (currentRegion)
17695 case 7:
return false;
17696 default:
return true;
17699 default:
return true;
17717 bool QCPCurve::getTraverse(
double prevKey,
double prevValue,
double key,
double value,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom, QPointF &crossA, QPointF &crossB)
const 17719 QList<QPointF> intersections;
17720 if (qFuzzyIsNull(key-prevKey))
17723 intersections.append(QPointF(key, rectBottom));
17724 intersections.append(QPointF(key, rectTop));
17725 }
else if (qFuzzyIsNull(value-prevValue))
17728 intersections.append(QPointF(rectLeft, value));
17729 intersections.append(QPointF(rectRight, value));
17733 double keyPerValue = (key-prevKey)/(value-prevValue);
17735 gamma = prevKey + (rectTop-prevValue)*keyPerValue;
17736 if (gamma >= rectLeft && gamma <= rectRight)
17737 intersections.append(QPointF(gamma, rectTop));
17739 gamma = prevKey + (rectBottom-prevValue)*keyPerValue;
17740 if (gamma >= rectLeft && gamma <= rectRight)
17741 intersections.append(QPointF(gamma, rectBottom));
17742 double valuePerKey = 1.0/keyPerValue;
17744 gamma = prevValue + (rectLeft-prevKey)*valuePerKey;
17745 if (gamma >= rectBottom && gamma <= rectTop)
17746 intersections.append(QPointF(rectLeft, gamma));
17748 gamma = prevValue + (rectRight-prevKey)*valuePerKey;
17749 if (gamma >= rectBottom && gamma <= rectTop)
17750 intersections.append(QPointF(rectRight, gamma));
17754 if (intersections.size() > 2)
17757 double distSqrMax = 0;
17759 for (
int i=0; i<intersections.size()-1; ++i)
17761 for (
int k=i+1; k<intersections.size(); ++k)
17763 QPointF distPoint = intersections.at(i)-intersections.at(k);
17764 double distSqr = distPoint.x()*distPoint.x()+distPoint.y()+distPoint.y();
17765 if (distSqr > distSqrMax)
17767 pv1 = intersections.at(i);
17768 pv2 = intersections.at(k);
17769 distSqrMax = distSqr;
17773 intersections = QList<QPointF>() << pv1 << pv2;
17774 }
else if (intersections.size() != 2)
17781 if ((key-prevKey)*(intersections.at(1).x()-intersections.at(0).x()) + (value-prevValue)*(intersections.at(1).y()-intersections.at(0).y()) < 0)
17782 intersections.move(0, 1);
17783 crossA =
coordsToPixels(intersections.at(0).x(), intersections.at(0).y());
17784 crossB =
coordsToPixels(intersections.at(1).x(), intersections.at(1).y());
17813 void QCPCurve::getTraverseCornerPoints(
int prevRegion,
int currentRegion,
double rectLeft,
double rectTop,
double rectRight,
double rectBottom, QVector<QPointF> &beforeTraverse, QVector<QPointF> &afterTraverse)
const 17815 switch (prevRegion)
17819 switch (currentRegion)
17821 case 6: { beforeTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
17823 case 8: { beforeTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
17829 switch (currentRegion)
17831 case 7: { afterTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
17832 case 9: { afterTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
17838 switch (currentRegion)
17840 case 4: { beforeTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
17842 case 8: { beforeTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
17848 switch (currentRegion)
17850 case 3: { afterTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
17851 case 9: { afterTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
17858 switch (currentRegion)
17860 case 1: { afterTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
17861 case 7: { afterTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
17867 switch (currentRegion)
17869 case 2: { beforeTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
17871 case 6: { beforeTraverse <<
coordsToPixels(rectRight, rectTop);
break; }
17877 switch (currentRegion)
17879 case 1: { afterTraverse <<
coordsToPixels(rectLeft, rectTop);
break; }
17880 case 3: { afterTraverse <<
coordsToPixels(rectLeft, rectBottom);
break; }
17886 switch (currentRegion)
17888 case 2: { beforeTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
17890 case 4: { beforeTraverse <<
coordsToPixels(rectRight, rectBottom);
break; }
17905 if (
mData->isEmpty())
17907 qDebug() << Q_FUNC_INFO <<
"requested point distance on curve" <<
mName <<
"without data";
17910 if (
mData->size() == 1)
17913 return QVector2D(dataPoint-pixelPoint).length();
17917 QVector<QPointF> *lineData =
new QVector<QPointF>;
17920 for (
int i=0; i<lineData->size()-1; ++i)
17922 double currentDistSqr =
distSqrToLine(lineData->at(i), lineData->at(i+1), pixelPoint);
17923 if (currentDistSqr < minDistSqr)
17924 minDistSqr = currentDistSqr;
17927 return qSqrt(minDistSqr);
17934 bool haveLower =
false;
17935 bool haveUpper =
false;
17939 QCPCurveDataMap::const_iterator it =
mData->constBegin();
17940 while (it !=
mData->constEnd())
17942 current = it.value().key;
17943 if (!qIsNaN(current) && !qIsNaN(it.value().value))
17947 if (current < range.
lower || !haveLower)
17949 range.
lower = current;
17952 if (current > range.
upper || !haveUpper)
17954 range.
upper = current;
17962 foundRange = haveLower && haveUpper;
17970 bool haveLower =
false;
17971 bool haveUpper =
false;
17975 QCPCurveDataMap::const_iterator it =
mData->constBegin();
17976 while (it !=
mData->constEnd())
17978 current = it.value().value;
17979 if (!qIsNaN(current) && !qIsNaN(it.value().key))
17983 if (current < range.
lower || !haveLower)
17985 range.
lower = current;
17988 if (current > range.
upper || !haveUpper)
17990 range.
upper = current;
17998 foundRange = haveLower && haveUpper;
18075 QObject(parentPlot),
18077 mSpacingType(stAbsolute),
18118 if (index >= 0 && index <
mBars.size())
18120 return mBars.at(index);
18123 qDebug() << Q_FUNC_INFO <<
"index out of bounds:" << index;
18149 qDebug() << Q_FUNC_INFO <<
"bars is 0";
18153 if (!
mBars.contains(bars))
18156 qDebug() << Q_FUNC_INFO <<
"bars plottable is already in this bars group:" <<
reinterpret_cast<quintptr
>(
bars);
18172 qDebug() << Q_FUNC_INFO <<
"bars is 0";
18177 if (!
mBars.contains(bars))
18192 qDebug() << Q_FUNC_INFO <<
"bars is 0";
18196 if (
mBars.contains(bars))
18199 qDebug() << Q_FUNC_INFO <<
"bars plottable is not in this bars group:" <<
reinterpret_cast<quintptr
>(
bars);
18211 if (!
mBars.contains(bars))
18212 mBars.append(bars);
18224 mBars.removeOne(bars);
18236 QList<const QCPBars*> baseBars;
18241 if (!baseBars.contains(b))
18242 baseBars.append(b);
18251 int index = baseBars.indexOf(thisBase);
18255 double lowerPixelWidth, upperPixelWidth;
18256 if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2)
18259 }
else if (index < (baseBars.size()-1)/2.0)
18261 if (baseBars.size() % 2 == 0)
18263 startIndex = baseBars.size()/2-1;
18267 startIndex = (baseBars.size()-1)/2-1;
18268 baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18269 result -= qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18270 result -=
getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord);
18272 for (
int i=startIndex; i>index; --i)
18274 baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18275 result -= qAbs(upperPixelWidth-lowerPixelWidth);
18279 baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18280 result -= qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18283 if (baseBars.size() % 2 == 0)
18285 startIndex = baseBars.size()/2;
18289 startIndex = (baseBars.size()-1)/2+1;
18290 baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18291 result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18292 result +=
getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord);
18294 for (
int i=startIndex; i<index; ++i)
18296 baseBars.at(i)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18297 result += qAbs(upperPixelWidth-lowerPixelWidth);
18301 baseBars.at(index)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
18302 result += qAbs(upperPixelWidth-lowerPixelWidth)*0.5;
18448 mWidthType(wtPlotCoords),
18453 mPen.setColor(Qt::blue);
18454 mPen.setStyle(Qt::SolidLine);
18455 mBrush.setColor(QColor(40, 50, 255, 30));
18456 mBrush.setStyle(Qt::SolidPattern);
18540 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
18562 int n = key.size();
18563 n = qMin(n, value.size());
18565 for (
int i=0; i<n; ++i)
18567 newData.
key = key[i];
18568 newData.value = value[i];
18569 mData->insertMulti(newData.key, newData);
18589 if (bars ==
this)
return;
18592 qDebug() << Q_FUNC_INFO <<
"passed QCPBars* doesn't have same key and value axis as this QCPBars";
18622 if (bars ==
this)
return;
18625 qDebug() << Q_FUNC_INFO <<
"passed QCPBars* doesn't have same key and value axis as this QCPBars";
18645 mData->unite(dataMap);
18654 mData->insertMulti(data.
key, data);
18665 newData.
value = value;
18666 mData->insertMulti(newData.
key, newData);
18675 int n = keys.size();
18676 n = qMin(n, values.size());
18678 for (
int i=0; i<n; ++i)
18680 newData.
key = keys[i];
18681 newData.value = values[i];
18682 mData->insertMulti(newData.key, newData);
18692 QCPBarDataMap::iterator it =
mData->begin();
18693 while (it !=
mData->end() && it.key() < key)
18694 it =
mData->erase(it);
18703 if (
mData->isEmpty())
return;
18704 QCPBarDataMap::iterator it =
mData->upperBound(key);
18705 while (it !=
mData->end())
18706 it =
mData->erase(it);
18718 if (fromKey >= toKey ||
mData->isEmpty())
return;
18719 QCPBarDataMap::iterator it =
mData->upperBound(fromKey);
18720 QCPBarDataMap::iterator itEnd =
mData->upperBound(toKey);
18721 while (it != itEnd)
18722 it =
mData->erase(it);
18735 mData->remove(key);
18753 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
18755 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
18757 QCPBarDataMap::ConstIterator it;
18758 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
18760 if (
getBarPolygon(it.value().key, it.value().value).boundingRect().contains(pos))
18770 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
18771 if (
mData->isEmpty())
return;
18773 QCPBarDataMap::const_iterator it, lower, upperEnd;
18775 for (it = lower; it != upperEnd; ++it)
18778 #ifdef QCUSTOMPLOT_CHECK_DATA 18780 qDebug() << Q_FUNC_INFO <<
"Data point at" << it.key() <<
"of drawn range invalid." <<
"Plottable name:" <<
name();
18782 QPolygonF barPolygon =
getBarPolygon(it.key(), it.value().value);
18787 painter->
setPen(Qt::NoPen);
18789 painter->drawPolygon(barPolygon);
18792 if (
mainPen().style() != Qt::NoPen &&
mainPen().color().alpha() != 0)
18796 painter->setBrush(Qt::NoBrush);
18797 painter->drawPolyline(barPolygon);
18807 painter->setBrush(
mBrush);
18809 QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67);
18810 r.moveCenter(rect.center());
18811 painter->drawRect(r);
18830 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
18831 if (
mData->isEmpty())
18833 lower =
mData->constEnd();
18834 upperEnd =
mData->constEnd();
18840 upperEnd =
mData->upperBound(
mKeyAxis.data()->range().upper);
18841 double lowerPixelBound =
mKeyAxis.data()->coordToPixel(
mKeyAxis.data()->range().lower);
18842 double upperPixelBound =
mKeyAxis.data()->coordToPixel(
mKeyAxis.data()->range().upper);
18843 bool isVisible =
false;
18845 QCPBarDataMap::const_iterator it = lower;
18846 while (it !=
mData->constBegin())
18849 QRectF barBounds =
getBarPolygon(it.value().key, it.value().value).boundingRect();
18850 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
18851 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.right() >= lowerPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.left() <= lowerPixelBound));
18853 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.top() <= lowerPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.bottom() >= lowerPixelBound));
18861 while (it !=
mData->constEnd())
18863 QRectF barBounds =
getBarPolygon(upperEnd.value().key, upperEnd.value().value).boundingRect();
18864 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
18865 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.left() <= upperPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.right() >= upperPixelBound));
18867 isVisible = ((!
mKeyAxis.data()->rangeReversed() && barBounds.bottom() >= upperPixelBound) || (
mKeyAxis.data()->rangeReversed() && barBounds.top() <= upperPixelBound));
18886 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return QPolygonF(); }
18889 double lowerPixelWidth, upperPixelWidth;
18893 double valuePixel = valueAxis->
coordToPixel(base+value);
18899 result << QPointF(keyPixel+lowerPixelWidth, basePixel);
18900 result << QPointF(keyPixel+lowerPixelWidth, valuePixel);
18901 result << QPointF(keyPixel+upperPixelWidth, valuePixel);
18902 result << QPointF(keyPixel+upperPixelWidth, basePixel);
18905 result << QPointF(basePixel, keyPixel+lowerPixelWidth);
18906 result << QPointF(valuePixel, keyPixel+lowerPixelWidth);
18907 result << QPointF(valuePixel, keyPixel+upperPixelWidth);
18908 result << QPointF(basePixel, keyPixel+upperPixelWidth);
18931 qSwap(lower, upper);
18938 if (
mKeyAxis.data()->orientation() == Qt::Horizontal)
18944 qSwap(lower, upper);
18946 qDebug() << Q_FUNC_INFO <<
"No key axis or axis rect defined";
18953 double keyPixel =
mKeyAxis.data()->coordToPixel(key);
18959 qDebug() << Q_FUNC_INFO <<
"No key axis defined";
18980 double epsilon = qAbs(key)*1e-6;
18983 QCPBarDataMap::const_iterator it =
mBarBelow.data()->mData->lowerBound(key-epsilon);
18984 QCPBarDataMap::const_iterator itEnd =
mBarBelow.data()->mData->upperBound(key+epsilon);
18985 while (it != itEnd)
18987 if ((positive && it.value().value >
max) ||
18988 (!positive && it.value().value <
max))
18989 max = it.value().value;
18993 return max +
mBarBelow.data()->getStackedBaseValue(key, positive);
19008 if (!lower && !upper)
return;
19014 upper->
mBarBelow.data()->mBarAbove = 0;
19020 lower->
mBarAbove.data()->mBarBelow = 0;
19026 lower->
mBarAbove.data()->mBarBelow = 0;
19029 upper->
mBarBelow.data()->mBarAbove = 0;
19039 bool haveLower =
false;
19040 bool haveUpper =
false;
19043 QCPBarDataMap::const_iterator it =
mData->constBegin();
19044 while (it !=
mData->constEnd())
19046 current = it.value().key;
19049 if (current < range.
lower || !haveLower)
19051 range.
lower = current;
19054 if (current > range.
upper || !haveUpper)
19056 range.
upper = current;
19065 double lowerPixelWidth, upperPixelWidth, keyPixel;
19067 keyPixel =
mKeyAxis.data()->coordToPixel(range.
lower) + lowerPixelWidth;
19074 double lowerPixelWidth, upperPixelWidth, keyPixel;
19076 keyPixel =
mKeyAxis.data()->coordToPixel(range.
upper) + upperPixelWidth;
19081 foundRange = haveLower && haveUpper;
19091 bool haveLower =
true;
19092 bool haveUpper =
true;
19095 QCPBarDataMap::const_iterator it =
mData->constBegin();
19096 while (it !=
mData->constEnd())
19101 if (current < range.
lower || !haveLower)
19103 range.
lower = current;
19106 if (current > range.
upper || !haveUpper)
19108 range.
upper = current;
19189 setPen(QPen(Qt::black));
19191 setMedianPen(QPen(Qt::black, 3, Qt::SolidLine, Qt::FlatCap));
19192 setWhiskerPen(QPen(Qt::black, 0, Qt::DashLine, Qt::FlatCap));
19371 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
19373 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
19375 double posKey, posValue;
19393 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
19396 #ifdef QCUSTOMPLOT_CHECK_DATA 19400 qDebug() << Q_FUNC_INFO <<
"Data point at" <<
mKey <<
"of drawn range has invalid data." <<
"Plottable name:" <<
name();
19403 qDebug() << Q_FUNC_INFO <<
"Data point outlier at" <<
mKey <<
"of drawn range invalid." <<
"Plottable name:" <<
name();
19406 QRectF quartileBox;
19410 painter->setClipRect(quartileBox, Qt::IntersectClip);
19424 painter->setBrush(
mBrush);
19425 QRectF r = QRectF(0, 0, rect.width()*0.67, rect.height()*0.67);
19426 r.moveCenter(rect.center());
19427 painter->drawRect(r);
19444 painter->drawRect(box);
19446 *quartileBox = box;
19469 QLineF backboneMin, backboneMax, barMin, barMax;
19499 if (inSignDomain ==
sdBoth)
19510 foundRange =
false;
19521 foundRange =
false;
19525 foundRange =
false;
19532 QVector<double> values;
19537 bool haveUpper =
false;
19538 bool haveLower =
false;
19541 for (
int i=0; i<values.size(); ++i)
19543 if ((inSignDomain ==
sdNegative && values.at(i) < 0) ||
19544 (inSignDomain ==
sdPositive && values.at(i) > 0) ||
19545 (inSignDomain ==
sdBoth))
19547 if (values.at(i) > upper || !haveUpper)
19549 upper = values.at(i);
19552 if (values.at(i) < lower || !haveLower)
19554 lower = values.at(i);
19560 if (haveLower && haveUpper)
19566 foundRange =
false;
19624 mKeyRange(keyRange),
19625 mValueRange(valueRange),
19628 mDataModified(true)
19658 if (&other !=
this)
19677 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell <
mValueSize)
19686 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex <
mValueSize)
19715 #ifdef __EXCEPTIONS 19719 #ifdef __EXCEPTIONS 19720 }
catch (...) {
mData = 0; }
19725 qDebug() << Q_FUNC_INFO <<
"out of memory for data dimensions "<<
mKeySize <<
"*" <<
mValueSize;
19824 if (keyCell >= 0 && keyCell < mKeySize && valueCell >= 0 && valueCell <
mValueSize)
19848 if (keyIndex >= 0 && keyIndex < mKeySize && valueIndex >= 0 && valueIndex <
mValueSize)
19876 double minHeight =
mData[0];
19877 double maxHeight =
mData[0];
19879 for (
int i=0; i<dataCount; ++i)
19881 if (
mData[i] > maxHeight)
19882 maxHeight =
mData[i];
19883 if (
mData[i] < minHeight)
19884 minHeight =
mData[i];
19907 for (
int i=0; i<dataCount; ++i)
20069 mDataScaleType(
QCPAxis::stLinear),
20071 mInterpolate(true),
20072 mTightBoundary(false),
20073 mMapImageInvalidated(true)
20093 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
20257 if (recalculateDataBounds)
20285 mLegendIcon = QPixmap::fromImage(
mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode);
20304 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
20306 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
20308 double posKey, posValue;
20333 if (!keyAxis)
return;
20338 int keyOversamplingFactor =
mInterpolate ? 1 : (int)(1.0+100.0/(
double)keySize);
20339 int valueOversamplingFactor =
mInterpolate ? 1 : (int)(1.0+100.0/(
double)valueSize);
20342 if (keyAxis->
orientation() == Qt::Horizontal && (
mMapImage.width() != keySize*keyOversamplingFactor ||
mMapImage.height() != valueSize*valueOversamplingFactor))
20343 mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), QImage::Format_RGB32);
20344 else if (keyAxis->
orientation() == Qt::Vertical && (
mMapImage.width() != valueSize*valueOversamplingFactor ||
mMapImage.height() != keySize*keyOversamplingFactor))
20345 mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), QImage::Format_RGB32);
20348 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1)
20362 const int lineCount = valueSize;
20363 const int rowCount = keySize;
20364 for (
int line=0; line<lineCount; ++line)
20366 QRgb* pixels =
reinterpret_cast<QRgb*
>(localMapImage->scanLine(lineCount-1-line));
20371 const int lineCount = keySize;
20372 const int rowCount = valueSize;
20373 for (
int line=0; line<lineCount; ++line)
20375 QRgb* pixels =
reinterpret_cast<QRgb*
>(localMapImage->scanLine(lineCount-1-line));
20380 if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1)
20383 mMapImage =
mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation);
20385 mMapImage =
mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation);
20404 QRectF mapBufferTarget;
20406 double mapBufferPixelRatio = 3;
20409 mapBufferTarget = painter->clipRegion().boundingRect();
20410 mapBuffer = QPixmap((mapBufferTarget.size()*mapBufferPixelRatio).toSize());
20411 mapBuffer.fill(Qt::transparent);
20413 localPainter->scale(mapBufferPixelRatio, mapBufferPixelRatio);
20414 localPainter->translate(-mapBufferTarget.topLeft());
20420 double halfCellWidth = 0;
20421 double halfCellHeight = 0;
20422 if (
keyAxis()->orientation() == Qt::Horizontal)
20425 halfCellWidth = 0.5*imageRect.width()/(double)(
mMapData->
keySize()-1);
20431 halfCellHeight = 0.5*imageRect.height()/(double)(
mMapData->
keySize()-1);
20435 imageRect.adjust(-halfCellWidth, -halfCellHeight, halfCellWidth, halfCellHeight);
20438 bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform);
20439 localPainter->setRenderHint(QPainter::SmoothPixmapTransform,
mInterpolate);
20440 QRegion clipBackup;
20443 clipBackup = localPainter->clipRegion();
20446 localPainter->setClipRect(tightClipRect, Qt::IntersectClip);
20448 localPainter->drawImage(imageRect,
mMapImage.mirrored(mirrorX, mirrorY));
20450 localPainter->setClipRegion(clipBackup);
20451 localPainter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup);
20455 delete localPainter;
20456 painter->drawPixmap(mapBufferTarget.toRect(), mapBuffer);
20467 QPixmap scaledIcon =
mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation);
20468 QRectF iconRect = QRectF(0, 0, scaledIcon.width(), scaledIcon.height());
20469 iconRect.moveCenter(rect.center());
20470 painter->drawPixmap(iconRect.topLeft(), scaledIcon);
20490 else if (result.
lower <= 0 && result.
upper <= 0)
20491 foundRange =
false;
20496 else if (result.
upper >= 0 && result.
lower >= 0)
20497 foundRange =
false;
20512 else if (result.
lower <= 0 && result.
upper <= 0)
20513 foundRange =
false;
20518 else if (result.
upper >= 0 && result.
lower >= 0)
20519 foundRange =
false;
20628 mChartStyle(csOhlc),
20630 mTwoColored(false),
20631 mBrushPositive(QBrush(QColor(210, 210, 255))),
20632 mBrushNegative(QBrush(QColor(255, 210, 210))),
20633 mPenPositive(QPen(QColor(10, 40, 180))),
20634 mPenNegative(QPen(QColor(180, 40, 10)))
20663 qDebug() << Q_FUNC_INFO <<
"The data pointer is already in (and owned by) this plottable" <<
reinterpret_cast<quintptr
>(
data);
20683 void QCPFinancial::setData(
const QVector<double> &key,
const QVector<double> &open,
const QVector<double> &high,
const QVector<double> &low,
const QVector<double> &close)
20686 int n = key.size();
20687 n = qMin(n, open.size());
20688 n = qMin(n, high.size());
20689 n = qMin(n, low.size());
20690 n = qMin(n, close.size());
20691 for (
int i=0; i<n; ++i)
20795 mData->unite(dataMap);
20809 mData->insertMulti(data.
key, data);
20836 void QCPFinancial::addData(
const QVector<double> &key,
const QVector<double> &open,
const QVector<double> &high,
const QVector<double> &low,
const QVector<double> &close)
20838 int n = key.size();
20839 n = qMin(n, open.size());
20840 n = qMin(n, high.size());
20841 n = qMin(n, low.size());
20842 n = qMin(n, close.size());
20843 for (
int i=0; i<n; ++i)
20856 QCPFinancialDataMap::iterator it =
mData->begin();
20857 while (it !=
mData->end() && it.key() < key)
20858 it =
mData->erase(it);
20868 if (
mData->isEmpty())
return;
20869 QCPFinancialDataMap::iterator it =
mData->upperBound(key);
20870 while (it !=
mData->end())
20871 it =
mData->erase(it);
20883 if (fromKey >= toKey ||
mData->isEmpty())
return;
20884 QCPFinancialDataMap::iterator it =
mData->upperBound(fromKey);
20885 QCPFinancialDataMap::iterator itEnd =
mData->upperBound(toKey);
20886 while (it != itEnd)
20887 it =
mData->erase(it);
20900 mData->remove(key);
20919 if (!
mKeyAxis || !
mValueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
20921 if (
mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()))
20924 QCPFinancialDataMap::const_iterator lower, upper;
20926 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
20956 int count = qMin(time.size(), value.size());
20960 QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first());
20961 int currentBinIndex = qFloor((time.first()-timeBinOffset)/timeBinSize+0.5);
20962 for (
int i=0; i<
count; ++i)
20964 int index = qFloor((time.at(i)-timeBinOffset)/timeBinSize+0.5);
20965 if (currentBinIndex == index)
20967 if (value.at(i) < currentBinData.low) currentBinData.low = value.at(i);
20968 if (value.at(i) > currentBinData.high) currentBinData.high = value.at(i);
20971 currentBinData.close = value.at(i);
20972 currentBinData.key = timeBinOffset+(index)*timeBinSize;
20973 map.insert(currentBinData.key, currentBinData);
20978 currentBinData.close = value.at(i-1);
20979 currentBinData.key = timeBinOffset+(index-1)*timeBinSize;
20980 map.insert(currentBinData.key, currentBinData);
20982 currentBinIndex = index;
20983 currentBinData.open = value.at(i);
20984 currentBinData.high = value.at(i);
20985 currentBinData.low = value.at(i);
20996 QCPFinancialDataMap::const_iterator lower, upper;
20998 if (lower ==
mData->constEnd() || upper ==
mData->constEnd())
21022 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint()));
21023 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21024 painter->
drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
21025 painter->
drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
21029 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint()));
21030 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21031 painter->
drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
21032 painter->
drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
21035 painter->setBrush(
mBrush);
21037 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21038 painter->
drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
21039 painter->
drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
21048 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint()));
21049 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
21050 painter->
drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21051 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
21055 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint()));
21056 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
21057 painter->
drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21058 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
21061 painter->setBrush(
mBrush);
21063 painter->
drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
21064 painter->
drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
21065 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
21074 bool haveLower =
false;
21075 bool haveUpper =
false;
21078 QCPFinancialDataMap::const_iterator it =
mData->constBegin();
21079 while (it !=
mData->constEnd())
21081 current = it.value().key;
21084 if (current < range.
lower || !haveLower)
21086 range.
lower = current;
21089 if (current > range.
upper || !haveUpper)
21091 range.
upper = current;
21102 foundRange = haveLower && haveUpper;
21110 bool haveLower =
false;
21111 bool haveUpper =
false;
21113 QCPFinancialDataMap::const_iterator it =
mData->constBegin();
21114 while (it !=
mData->constEnd())
21117 if (inSignDomain ==
sdBoth || (inSignDomain ==
sdNegative && it.value().high < 0) || (inSignDomain ==
sdPositive && it.value().high > 0))
21119 if (it.value().high < range.
lower || !haveLower)
21121 range.
lower = it.value().high;
21124 if (it.value().high > range.
upper || !haveUpper)
21126 range.
upper = it.value().high;
21131 if (inSignDomain ==
sdBoth || (inSignDomain ==
sdNegative && it.value().low < 0) || (inSignDomain ==
sdPositive && it.value().low > 0))
21133 if (it.value().low < range.
lower || !haveLower)
21135 range.
lower = it.value().low;
21138 if (it.value().low > range.
upper || !haveUpper)
21140 range.
upper = it.value().low;
21147 foundRange = haveLower && haveUpper;
21161 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
21167 for (QCPFinancialDataMap::const_iterator it = begin; it !=
end; ++it)
21175 painter->
setPen(linePen);
21176 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21177 double openPixel = valueAxis->
coordToPixel(it.value().open);
21178 double closePixel = valueAxis->
coordToPixel(it.value().close);
21183 painter->
drawLine(QPointF(keyPixel-keyWidthPixels, openPixel), QPointF(keyPixel, openPixel));
21185 painter->
drawLine(QPointF(keyPixel, closePixel), QPointF(keyPixel+keyWidthPixels, closePixel));
21189 for (QCPFinancialDataMap::const_iterator it = begin; it !=
end; ++it)
21197 painter->
setPen(linePen);
21198 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21199 double openPixel = valueAxis->
coordToPixel(it.value().open);
21200 double closePixel = valueAxis->
coordToPixel(it.value().close);
21205 painter->
drawLine(QPointF(openPixel, keyPixel-keyWidthPixels), QPointF(openPixel, keyPixel));
21207 painter->
drawLine(QPointF(closePixel, keyPixel), QPointF(closePixel, keyPixel+keyWidthPixels));
21222 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return; }
21229 for (QCPFinancialDataMap::const_iterator it = begin; it !=
end; ++it)
21237 if (it.value().close >= it.value().open)
21251 painter->
setPen(linePen);
21252 painter->setBrush(boxBrush);
21253 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21254 double openPixel = valueAxis->
coordToPixel(it.value().open);
21255 double closePixel = valueAxis->
coordToPixel(it.value().close);
21257 painter->
drawLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->
coordToPixel(qMax(it.value().open, it.value().close))));
21259 painter->
drawLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().low)), QPointF(keyPixel, valueAxis->
coordToPixel(qMin(it.value().open, it.value().close))));
21262 painter->drawRect(QRectF(QPointF(keyPixel-keyWidthPixels, closePixel), QPointF(keyPixel+keyWidthPixels, openPixel)));
21266 for (QCPFinancialDataMap::const_iterator it = begin; it !=
end; ++it)
21274 if (it.value().close >= it.value().open)
21288 painter->
setPen(linePen);
21289 painter->setBrush(boxBrush);
21290 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21291 double openPixel = valueAxis->
coordToPixel(it.value().open);
21292 double closePixel = valueAxis->
coordToPixel(it.value().close);
21294 painter->
drawLine(QPointF(valueAxis->
coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->
coordToPixel(qMax(it.value().open, it.value().close)), keyPixel));
21296 painter->
drawLine(QPointF(valueAxis->
coordToPixel(it.value().low), keyPixel), QPointF(valueAxis->
coordToPixel(qMin(it.value().open, it.value().close)), keyPixel));
21299 painter->drawRect(QRectF(QPointF(closePixel, keyPixel-keyWidthPixels), QPointF(openPixel, keyPixel+keyWidthPixels)));
21313 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
21316 QCPFinancialDataMap::const_iterator it;
21319 for (it = begin; it !=
end; ++it)
21321 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21324 if (currentDistSqr < minDistSqr)
21325 minDistSqr = currentDistSqr;
21329 for (it = begin; it !=
end; ++it)
21331 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21334 if (currentDistSqr < minDistSqr)
21335 minDistSqr = currentDistSqr;
21338 return qSqrt(minDistSqr);
21351 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key or value axis";
return -1; }
21354 QCPFinancialDataMap::const_iterator it;
21357 for (it = begin; it !=
end; ++it)
21359 double currentDistSqr;
21362 QCPRange boxValueRange(it.value().close, it.value().open);
21363 double posKey, posValue;
21365 if (boxKeyRange.
contains(posKey) && boxValueRange.contains(posValue))
21371 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21372 double highLineDistSqr =
distSqrToLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().high)), QPointF(keyPixel, valueAxis->
coordToPixel(qMax(it.value().open, it.value().close))), pos);
21373 double lowLineDistSqr =
distSqrToLine(QPointF(keyPixel, valueAxis->
coordToPixel(it.value().low)), QPointF(keyPixel, valueAxis->
coordToPixel(qMin(it.value().open, it.value().close))), pos);
21374 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
21376 if (currentDistSqr < minDistSqr)
21377 minDistSqr = currentDistSqr;
21381 for (it = begin; it !=
end; ++it)
21383 double currentDistSqr;
21386 QCPRange boxValueRange(it.value().close, it.value().open);
21387 double posKey, posValue;
21389 if (boxKeyRange.
contains(posKey) && boxValueRange.contains(posValue))
21395 double keyPixel = keyAxis->
coordToPixel(it.value().key);
21396 double highLineDistSqr =
distSqrToLine(QPointF(valueAxis->
coordToPixel(it.value().high), keyPixel), QPointF(valueAxis->
coordToPixel(qMax(it.value().open, it.value().close)), keyPixel), pos);
21397 double lowLineDistSqr =
distSqrToLine(QPointF(valueAxis->
coordToPixel(it.value().low), keyPixel), QPointF(valueAxis->
coordToPixel(qMin(it.value().open, it.value().close)), keyPixel), pos);
21398 currentDistSqr = qMin(highLineDistSqr, lowLineDistSqr);
21400 if (currentDistSqr < minDistSqr)
21401 minDistSqr = currentDistSqr;
21404 return qSqrt(minDistSqr);
21425 if (!
mKeyAxis) { qDebug() << Q_FUNC_INFO <<
"invalid key axis";
return; }
21426 if (
mData->isEmpty())
21428 lower =
mData->constEnd();
21429 upper =
mData->constEnd();
21434 QCPFinancialDataMap::const_iterator lbound =
mData->lowerBound(
mKeyAxis.data()->range().lower);
21435 QCPFinancialDataMap::const_iterator ubound =
mData->upperBound(
mKeyAxis.data()->range().upper);
21436 bool lowoutlier = lbound !=
mData->constBegin();
21437 bool highoutlier = ubound !=
mData->constEnd();
21439 lower = (lowoutlier ? lbound-1 : lbound);
21440 upper = (highoutlier ? ubound : ubound-1);
21463 point1(createPosition(QLatin1String(
"point1"))),
21464 point2(createPosition(QLatin1String(
"point2")))
21469 setPen(QPen(Qt::black));
21513 double clipPad =
mainPen().widthF();
21516 if (!line.isNull())
21532 return qAbs((base.y()-point.y())*vec.x()-(base.x()-point.x())*vec.y())/vec.length();
21547 if (vec.x() == 0 && vec.y() == 0)
21549 if (qFuzzyIsNull(vec.x()))
21554 gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y();
21555 if (gamma >= 0 && gamma <= rect.width())
21556 result.setLine(bx+gamma, rect.top(), bx+gamma, rect.bottom());
21557 }
else if (qFuzzyIsNull(vec.y()))
21562 gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x();
21563 if (gamma >= 0 && gamma <= rect.height())
21564 result.setLine(rect.left(), by+gamma, rect.right(), by+gamma);
21567 QList<QVector2D> pointVectors;
21571 gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y();
21572 if (gamma >= 0 && gamma <= rect.width())
21573 pointVectors.append(QVector2D(bx+gamma, by));
21576 by = rect.bottom();
21577 gamma = base.x()-bx + (by-base.y())*vec.x()/vec.y();
21578 if (gamma >= 0 && gamma <= rect.width())
21579 pointVectors.append(QVector2D(bx+gamma, by));
21583 gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x();
21584 if (gamma >= 0 && gamma <= rect.height())
21585 pointVectors.append(QVector2D(bx, by+gamma));
21589 gamma = base.y()-by + (bx-base.x())*vec.y()/vec.x();
21590 if (gamma >= 0 && gamma <= rect.height())
21591 pointVectors.append(QVector2D(bx, by+gamma));
21594 if (pointVectors.size() == 2)
21596 result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF());
21597 }
else if (pointVectors.size() > 2)
21600 double distSqrMax = 0;
21601 QVector2D pv1, pv2;
21602 for (
int i=0; i<pointVectors.size()-1; ++i)
21604 for (
int k=i+1; k<pointVectors.size(); ++k)
21606 double distSqr = (pointVectors.at(i)-pointVectors.at(k)).lengthSquared();
21607 if (distSqr > distSqrMax)
21609 pv1 = pointVectors.at(i);
21610 pv2 = pointVectors.at(k);
21611 distSqrMax = distSqr;
21615 result.setPoints(pv1.toPointF(), pv2.toPointF());
21659 setPen(QPen(Qt::black));
21728 if (startVec.toPoint() == endVec.toPoint())
21732 clipPad = qMax(clipPad, (
double)
mainPen().widthF());
21735 if (!line.isNull())
21739 painter->setBrush(Qt::SolidPattern);
21741 mTail.
draw(painter, startVec, startVec-endVec);
21743 mHead.
draw(painter, endVec, endVec-startVec);
21756 bool containsStart = rect.contains(start.x(), start.y());
21757 bool containsEnd = rect.contains(end.x(), end.y());
21758 if (containsStart && containsEnd)
21759 return QLineF(start.toPointF(), end.toPointF());
21761 QVector2D base =
start;
21762 QVector2D vec = end-
start;
21766 QList<QVector2D> pointVectors;
21768 if (!qFuzzyIsNull(vec.y()))
21773 mu = (by-base.y())/vec.y();
21774 if (mu >= 0 && mu <= 1)
21776 gamma = base.x()-bx + mu*vec.x();
21777 if (gamma >= 0 && gamma <= rect.width())
21778 pointVectors.append(QVector2D(bx+gamma, by));
21782 by = rect.bottom();
21783 mu = (by-base.y())/vec.y();
21784 if (mu >= 0 && mu <= 1)
21786 gamma = base.x()-bx + mu*vec.x();
21787 if (gamma >= 0 && gamma <= rect.width())
21788 pointVectors.append(QVector2D(bx+gamma, by));
21791 if (!qFuzzyIsNull(vec.x()))
21796 mu = (bx-base.x())/vec.x();
21797 if (mu >= 0 && mu <= 1)
21799 gamma = base.y()-by + mu*vec.y();
21800 if (gamma >= 0 && gamma <= rect.height())
21801 pointVectors.append(QVector2D(bx, by+gamma));
21806 mu = (bx-base.x())/vec.x();
21807 if (mu >= 0 && mu <= 1)
21809 gamma = base.y()-by + mu*vec.y();
21810 if (gamma >= 0 && gamma <= rect.height())
21811 pointVectors.append(QVector2D(bx, by+gamma));
21816 pointVectors.append(start);
21818 pointVectors.append(end);
21821 if (pointVectors.size() == 2)
21823 result.setPoints(pointVectors.at(0).toPointF(), pointVectors.at(1).toPointF());
21824 }
else if (pointVectors.size() > 2)
21827 double distSqrMax = 0;
21828 QVector2D pv1, pv2;
21829 for (
int i=0; i<pointVectors.size()-1; ++i)
21831 for (
int k=i+1; k<pointVectors.size(); ++k)
21833 double distSqr = (pointVectors.at(i)-pointVectors.at(k)).lengthSquared();
21834 if (distSqr > distSqrMax)
21836 pv1 = pointVectors.at(i);
21837 pv2 = pointVectors.at(k);
21838 distSqrMax = distSqr;
21842 result.setPoints(pv1.toPointF(), pv2.toPointF());
21896 setPen(QPen(Qt::black));
21962 QPainterPath cubicPath(startVec);
21963 cubicPath.cubicTo(startDirVec, endDirVec, endVec);
21965 QPolygonF polygon = cubicPath.toSubpathPolygons().first();
21967 for (
int i=1; i<polygon.size(); ++i)
21969 double distSqr =
distSqrToLine(polygon.at(i-1), polygon.at(i), pos);
21970 if (distSqr < minDistSqr)
21971 minDistSqr = distSqr;
21973 return qSqrt(minDistSqr);
21983 if (QVector2D(endVec-startVec).length() > 1e10f)
21986 QPainterPath cubicPath(startVec);
21987 cubicPath.cubicTo(startDirVec, endDirVec, endVec);
21991 QRect cubicRect = cubicPath.controlPointRect().toRect();
21992 if (cubicRect.isEmpty())
21993 cubicRect.adjust(0, 0, 1, 1);
21994 if (clip.intersects(cubicRect))
21997 painter->drawPath(cubicPath);
21998 painter->setBrush(Qt::SolidPattern);
22000 mTail.
draw(painter, QVector2D(startVec), M_PI-cubicPath.angleAtPercent(0)/180.0*M_PI);
22002 mHead.
draw(painter, QVector2D(endVec), -cubicPath.angleAtPercent(1)/180.0*M_PI);
22039 topRight(
createAnchor(QLatin1String(
"topRight"), aiTopRight)),
22041 bottom(
createAnchor(QLatin1String(
"bottom"), aiBottom)),
22042 bottomLeft(
createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
22048 setPen(QPen(Qt::black));
22108 bool filledRect =
mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0;
22117 if (p1.toPoint() == p2.toPoint())
22119 QRectF rect = QRectF(p1, p2).normalized();
22120 double clipPad =
mainPen().widthF();
22121 QRectF boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
22122 if (boundingRect.intersects(
clipRect()))
22126 painter->drawRect(rect);
22136 case aiTop:
return (rect.topLeft()+rect.topRight())*0.5;
22138 case aiRight:
return (rect.topRight()+rect.bottomRight())*0.5;
22139 case aiBottom:
return (rect.bottomLeft()+rect.bottomRight())*0.5;
22141 case aiLeft:
return (rect.topLeft()+rect.bottomLeft())*0.5;
22144 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
22209 setText(QLatin1String(
"text"));
22367 QTransform inputTransform;
22368 inputTransform.translate(positionPixels.x(), positionPixels.y());
22370 inputTransform.translate(-positionPixels.x(), -positionPixels.y());
22371 QPointF rotatedPos = inputTransform.map(pos);
22372 QFontMetrics fontMetrics(
mFont);
22373 QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|
mTextAlignment,
mText);
22376 textBoxRect.moveTopLeft(textPos.toPoint());
22385 QTransform transform = painter->transform();
22386 transform.translate(pos.x(), pos.y());
22390 QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|
mTextAlignment,
mText);
22393 textRect.moveTopLeft(textPos.toPoint()+QPoint(
mPadding.left(),
mPadding.top()));
22394 textBoxRect.moveTopLeft(textPos.toPoint());
22395 double clipPad =
mainPen().widthF();
22396 QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
22397 if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(
clipRect())))
22399 painter->setTransform(transform);
22405 painter->drawRect(textBoxRect);
22407 painter->setBrush(Qt::NoBrush);
22418 QTransform transform;
22419 transform.translate(pos.x(), pos.y());
22422 QFontMetrics fontMetrics(
mainFont());
22423 QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip|
mTextAlignment,
mText);
22426 textBoxRect.moveTopLeft(textPos.toPoint());
22427 QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect));
22432 case aiTop:
return (rectPoly.at(0)+rectPoly.at(1))*0.5;
22434 case aiRight:
return (rectPoly.at(1)+rectPoly.at(2))*0.5;
22436 case aiBottom:
return (rectPoly.at(2)+rectPoly.at(3))*0.5;
22438 case aiLeft:
return (rectPoly.at(3)+rectPoly.at(0))*0.5;
22441 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
22457 if (positionAlignment == 0 || positionAlignment == (Qt::AlignLeft|Qt::AlignTop))
22460 QPointF result = pos;
22461 if (positionAlignment.testFlag(Qt::AlignHCenter))
22462 result.rx() -= rect.width()/2.0;
22463 else if (positionAlignment.testFlag(Qt::AlignRight))
22464 result.rx() -= rect.width();
22465 if (positionAlignment.testFlag(Qt::AlignVCenter))
22466 result.ry() -= rect.height()/2.0;
22467 else if (positionAlignment.testFlag(Qt::AlignBottom))
22468 result.ry() -= rect.height();
22534 topLeftRim(
createAnchor(QLatin1String(
"topLeftRim"), aiTopLeftRim)),
22536 topRightRim(
createAnchor(QLatin1String(
"topRightRim"), aiTopRightRim)),
22538 bottomRightRim(
createAnchor(QLatin1String(
"bottomRightRim"), aiBottomRightRim)),
22540 bottomLeftRim(
createAnchor(QLatin1String(
"bottomLeftRim"), aiBottomLeftRim)),
22542 center(
createAnchor(QLatin1String(
"center"), aiCenter))
22547 setPen(QPen(Qt::black));
22606 double result = -1;
22609 QPointF
center((p1+p2)/2.0);
22610 double a = qAbs(p1.x()-p2.x())/2.0;
22611 double b = qAbs(p1.y()-p2.y())/2.0;
22612 double x = pos.x()-center.x();
22613 double y = pos.y()-center.y();
22616 double c = 1.0/qSqrt(x*x/(a*a)+y*y/(b*b));
22617 result = qAbs(c-1)*qSqrt(x*x+y*y);
22621 if (x*x/(a*a) + y*y/(b*b) <= 1)
22632 if (p1.toPoint() == p2.toPoint())
22634 QRectF ellipseRect = QRectF(p1, p2).normalized();
22636 if (ellipseRect.intersects(clip))
22640 #ifdef __EXCEPTIONS 22644 painter->drawEllipse(ellipseRect);
22645 #ifdef __EXCEPTIONS 22648 qDebug() << Q_FUNC_INFO <<
"Item too large for memory, setting invisible";
22661 case aiTopLeftRim:
return rect.center()+(rect.topLeft()-rect.center())*1/qSqrt(2);
22662 case aiTop:
return (rect.topLeft()+rect.topRight())*0.5;
22663 case aiTopRightRim:
return rect.center()+(rect.topRight()-rect.center())*1/qSqrt(2);
22664 case aiRight:
return (rect.topRight()+rect.bottomRight())*0.5;
22665 case aiBottomRightRim:
return rect.center()+(rect.bottomRight()-rect.center())*1/qSqrt(2);
22666 case aiBottom:
return (rect.bottomLeft()+rect.bottomRight())*0.5;
22667 case aiBottomLeftRim:
return rect.center()+(rect.bottomLeft()-rect.center())*1/qSqrt(2);
22668 case aiLeft:
return (rect.topLeft()+rect.bottomLeft())*0.5;
22669 case aiCenter:
return (rect.topLeft()+rect.bottomRight())*0.5;
22672 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
22725 topRight(
createAnchor(QLatin1String(
"topRight"), aiTopRight)),
22728 bottomLeft(
createAnchor(QLatin1String(
"bottomLeft"), aiBottomLeft)),
22736 setScaled(
false, Qt::KeepAspectRatio, Qt::SmoothTransformation);
22750 qDebug() << Q_FUNC_INFO <<
"pixmap is null";
22798 bool flipHorz =
false;
22799 bool flipVert =
false;
22801 double clipPad =
mainPen().style() == Qt::NoPen ? 0 :
mainPen().widthF();
22802 QRect boundingRect = rect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
22803 if (boundingRect.intersects(
clipRect()))
22808 if (pen.style() != Qt::NoPen)
22811 painter->setBrush(Qt::NoBrush);
22812 painter->drawRect(rect);
22826 rect.adjust(rect.width(), 0, -rect.width(), 0);
22828 rect.adjust(0, rect.height(), 0, -rect.height());
22832 case aiTop:
return (rect.topLeft()+rect.topRight())*0.5;
22834 case aiRight:
return (rect.topRight()+rect.bottomRight())*0.5;
22835 case aiBottom:
return (rect.bottomLeft()+rect.bottomRight())*0.5;
22837 case aiLeft:
return (rect.topLeft()+rect.bottomLeft())*0.5;;
22840 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
22864 if (finalRect.isNull())
22869 if (flipHorz || flipVert)
22893 bool flipHorz =
false;
22894 bool flipVert =
false;
22898 return QRect(p1, QSize(0, 0));
22901 QSize newSize = QSize(p2.x()-p1.x(), p2.y()-p1.y());
22903 if (newSize.width() < 0)
22906 newSize.rwidth() *= -1;
22907 topLeft.setX(p2.x());
22909 if (newSize.height() < 0)
22912 newSize.rheight() *= -1;
22913 topLeft.setY(p2.y());
22915 QSize scaledSize =
mPixmap.size();
22917 result = QRect(topLeft, scaledSize);
22920 result = QRect(p1,
mPixmap.size());
22923 *flippedHorz = flipHorz;
22925 *flippedVert = flipVert;
22988 setPen(QPen(Qt::black));
23081 qDebug() << Q_FUNC_INFO <<
"graph isn't in same QCustomPlot instance as this item";
23126 double w =
mSize/2.0;
23133 if (
clipRect().intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23134 return qSqrt(qMin(
distSqrToLine(center+QPointF(-w, 0), center+QPointF(w, 0), pos),
23135 distSqrToLine(center+QPointF(0, -w), center+QPointF(0, w), pos)));
23140 return qSqrt(qMin(
distSqrToLine(QPointF(clip.left(), center.y()), QPointF(clip.right(), center.y()), pos),
23141 distSqrToLine(QPointF(center.x(), clip.top()), QPointF(center.x(), clip.bottom()), pos)));
23145 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23148 double centerDist = QVector2D(center-pos).length();
23149 double circleLine = w;
23150 double result = qAbs(centerDist-circleLine);
23154 if (centerDist <= circleLine)
23163 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23165 QRectF rect = QRectF(center-QPointF(w, w), center+QPointF(w, w));
23166 bool filledRect =
mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0;
23185 double w =
mSize/2.0;
23192 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23194 painter->
drawLine(QLineF(center+QPointF(-w, 0), center+QPointF(w, 0)));
23195 painter->
drawLine(QLineF(center+QPointF(0, -w), center+QPointF(0, w)));
23201 if (center.y() > clip.top() && center.y() < clip.bottom())
23202 painter->
drawLine(QLineF(clip.left(), center.y(), clip.right(), center.y()));
23203 if (center.x() > clip.left() && center.x() < clip.right())
23204 painter->
drawLine(QLineF(center.x(), clip.top(), center.x(), clip.bottom()));
23209 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23210 painter->drawEllipse(center, w, w);
23215 if (clip.intersects(QRectF(center-QPointF(w, w), center+QPointF(w, w)).toRect()))
23216 painter->drawRect(QRectF(center-QPointF(w, w), center+QPointF(w, w)));
23242 QCPDataMap::const_iterator first =
mGraph->
data()->constBegin();
23243 QCPDataMap::const_iterator last =
mGraph->
data()->constEnd()-1;
23253 QCPDataMap::const_iterator prevIt = it-1;
23258 if (!qFuzzyCompare((
double)it.key(), (double)prevIt.key()))
23259 slope = (it.value().value-prevIt.value().value)/(it.key()-prevIt.key());
23264 if (
mGraphKey < (prevIt.key()+it.key())*0.5)
23273 QCPDataMap::const_iterator it =
mGraph->
data()->constBegin();
23276 qDebug() << Q_FUNC_INFO <<
"graph has no data";
23278 qDebug() << Q_FUNC_INFO <<
"graph not contained in QCustomPlot instance (anymore)";
23336 center(
createAnchor(QLatin1String(
"center"), aiCenter))
23341 setPen(QPen(Qt::black));
23407 if (leftVec.toPoint() == rightVec.toPoint())
23410 QVector2D widthVec = (rightVec-leftVec)*0.5f;
23411 QVector2D lengthVec(-widthVec.y(), widthVec.x());
23412 lengthVec = lengthVec.normalized()*
mLength;
23413 QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec;
23420 double a =
distSqrToLine((centerVec-widthVec).toPointF(), (centerVec+widthVec).toPointF(), pos);
23421 double b =
distSqrToLine((centerVec-widthVec+lengthVec).toPointF(), (centerVec-widthVec).toPointF(), pos);
23422 double c =
distSqrToLine((centerVec+widthVec+lengthVec).toPointF(), (centerVec+widthVec).toPointF(), pos);
23423 return qSqrt(qMin(qMin(a, b), c));
23428 double a =
distSqrToLine((centerVec-widthVec*0.75f+lengthVec*0.15f).toPointF(), (centerVec+lengthVec*0.3f).toPointF(), pos);
23429 double b =
distSqrToLine((centerVec-widthVec+lengthVec*0.7f).toPointF(), (centerVec-widthVec*0.75f+lengthVec*0.15f).toPointF(), pos);
23430 double c =
distSqrToLine((centerVec+widthVec*0.75f+lengthVec*0.15f).toPointF(), (centerVec+lengthVec*0.3f).toPointF(), pos);
23431 double d =
distSqrToLine((centerVec+widthVec+lengthVec*0.7f).toPointF(), (centerVec+widthVec*0.75f+lengthVec*0.15f).toPointF(), pos);
23432 return qSqrt(qMin(qMin(a, b), qMin(c, d)));
23443 if (leftVec.toPoint() == rightVec.toPoint())
23446 QVector2D widthVec = (rightVec-leftVec)*0.5f;
23447 QVector2D lengthVec(-widthVec.y(), widthVec.x());
23448 lengthVec = lengthVec.normalized()*
mLength;
23449 QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec;
23451 QPolygon boundingPoly;
23452 boundingPoly << leftVec.toPoint() << rightVec.toPoint()
23453 << (rightVec-lengthVec).toPoint() << (leftVec-lengthVec).toPoint();
23455 if (clip.intersects(boundingPoly.boundingRect()))
23462 painter->
drawLine((centerVec+widthVec).toPointF(), (centerVec-widthVec).toPointF());
23463 painter->
drawLine((centerVec+widthVec).toPointF(), (centerVec+widthVec+lengthVec).toPointF());
23464 painter->
drawLine((centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23469 painter->setBrush(Qt::NoBrush);
23471 path.moveTo((centerVec+widthVec+lengthVec).toPointF());
23472 path.cubicTo((centerVec+widthVec).toPointF(), (centerVec+widthVec).toPointF(), centerVec.toPointF());
23473 path.cubicTo((centerVec-widthVec).toPointF(), (centerVec-widthVec).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23474 painter->drawPath(path);
23479 painter->setBrush(Qt::NoBrush);
23481 path.moveTo((centerVec+widthVec+lengthVec).toPointF());
23482 path.cubicTo((centerVec+widthVec-lengthVec*0.8f).toPointF(), (centerVec+0.4f*widthVec+lengthVec).toPointF(), centerVec.toPointF());
23483 path.cubicTo((centerVec-0.4f*widthVec+lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8f).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23484 painter->drawPath(path);
23489 painter->
setPen(Qt::NoPen);
23490 painter->setBrush(QBrush(
mainPen().color()));
23492 path.moveTo((centerVec+widthVec+lengthVec).toPointF());
23494 path.cubicTo((centerVec+widthVec-lengthVec*0.8f).toPointF(), (centerVec+0.4f*widthVec+0.8f*lengthVec).toPointF(), centerVec.toPointF());
23495 path.cubicTo((centerVec-0.4f*widthVec+0.8f*lengthVec).toPointF(), (centerVec-widthVec-lengthVec*0.8f).toPointF(), (centerVec-widthVec+lengthVec).toPointF());
23497 path.cubicTo((centerVec-widthVec-lengthVec*0.5f).toPointF(), (centerVec-0.2f*widthVec+1.2f*lengthVec).toPointF(), (centerVec+lengthVec*0.2f).toPointF());
23498 path.cubicTo((centerVec+0.2f*widthVec+1.2f*lengthVec).toPointF(), (centerVec+widthVec-lengthVec*0.5f).toPointF(), (centerVec+widthVec+lengthVec).toPointF());
23500 painter->drawPath(path);
23512 if (leftVec.toPoint() == rightVec.toPoint())
23513 return leftVec.toPointF();
23515 QVector2D widthVec = (rightVec-leftVec)*0.5f;
23516 QVector2D lengthVec(-widthVec.y(), widthVec.x());
23517 lengthVec = lengthVec.normalized()*
mLength;
23518 QVector2D centerVec = (rightVec+leftVec)*0.5f-lengthVec;
23523 return centerVec.toPointF();
23525 qDebug() << Q_FUNC_INFO <<
"invalid anchorId" << anchorId;
void setOutliers(const QVector< double > &values)
QList< QList< QCPLayoutElement * > > mElements
virtual int elementCount() const
void drawShape(QCPPainter *painter, QPointF pos) const
QCP::AntialiasedElements mNotAADragBackup
void setType(PositionType type)
QCPLayoutElement(QCustomPlot *parentPlot=0)
bool getTraverse(double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom, QPointF &crossA, QPointF &crossB) const
QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale)
virtual QCPLayoutElement * elementAt(int index) const
void itemClick(QCPAbstractItem *item, QMouseEvent *event)
void drawSubGridLines(QCPPainter *painter) const
void addElement(QCPLayoutElement *element, Qt::Alignment alignment)
QCPItemPosition * position(const QString &name) const
void insertRow(int newIndex)
A margin group allows synchronization of margin sides if working with multiple layout elements...
QList< QCPGraph * > mGraphs
QCPGraph * addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0)
virtual ~QCPAxisPainterPrivate()
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setSubTickLengthIn(int inside)
void setMargins(const QMargins &margins)
0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width...
QList< QCPLayoutElement * > elements(QCP::MarginSide side) const
void setWhiskerBarPen(const QPen &pen)
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true)
void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const
Qt::Orientations mRangeDrag
A plus shaped crosshair which spans the complete axis rect.
static const double maxRange
void setPeriodic(bool enabled)
void setLevelCount(int n)
QColor mainTextColor() const
QRgb color(double position, const QCPRange &range, bool logarithmic=false)
Whether to use immediate repaint or queued update depends on whether the plotting hint QCP::phForceRe...
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setInsetPlacement(int index, InsetPlacement placement)
Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts)
bool isInvalidData(double value)
The negative sign domain, i.e. numbers smaller than zero.
virtual void updateMapImage()
virtual void update(UpdatePhase phase)
int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const
QCPColorGradient gradient() const
QCPAxis * rangeZoomAxis(Qt::Orientation orientation)
void setDateTimeFormat(const QString &format)
void setText(const QString &text)
void selectableChanged(bool selectable)
void setLowerEnding(const QCPLineEnding &ending)
Open-High-Low-Close bar representation.
bool clipToAxisRect() const
virtual QRect clipRect() const
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
QCPItemPosition *const end
void updateAxesOffset(QCPAxis::AxisType type)
QCPColorMapData * mMapData
QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable)
virtual void draw(QCPPainter *painter)
int plottableCount() const
QCPLayout * mParentLayout
void setAutoTickLabels(bool on)
double cell(int keyIndex, int valueIndex)
Q_SLOT void setSelected(bool selected)
AdjacencyIterator end(const Adjacency &adj, const Vector< D > &vct, size_t pixel_index)
Returns an iterator to position after the end of elements.
void setMinimumMargins(const QMargins &margins)
QCPAxis(QCPAxisRect *parent, AxisType type)
void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0)
PainterModes modes() const
QCPRange dataRange() const
void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true)
void setKeySize(int keySize)
QMap< double, QCPData > QCPDataMap
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void remove(QCPBars *bars)
void removeDataAfter(double key)
QCP::AntialiasedElements antialiasedElements() const
void setMaximumSize(const QSize &size)
Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the ...
static QCPFinancialDataMap timeSeriesToOhlc(const QVector< double > &time, const QVector< double > &value, double timeBinSize, double timeBinOffset=0)
Holds the data of one single data point for QCPCurve.
void mouseMove(QMouseEvent *event)
QCPRange keyRange() const
No line is drawn between data points (e.g. only scatters)
QCustomPlot(QWidget *parent=0)
virtual int calculateAutoSubTickCount(double tickStep) const
void setParentLayerable(QCPLayerable *parentLayerable)
QCPItemBracket(QCustomPlot *parentPlot)
QCPLineEnding tail() const
void rescaleKeyAxis(bool onlyEnlarge=false) const
bool mNumberBeautifulPowers
QCPItemAnchor *const center
A legend item representing a plottable with an icon and the plottable name.
QHash< QCP::MarginSide, QCPMarginGroup * > mMarginGroups
Bar spacing is given by a fraction of the axis rect size.
bool antialiasing() const
void setType(QCPAxis::AxisType type)
void setIconTextPadding(int padding)
each data point is represented by a line parallel to the value axis, which reaches from the data poin...
QCPItemPosition *const start
void selectionChanged(bool selected)
int numberPrecision() const
virtual QList< QCPLayoutElement * > elements(bool recursive) const
void expandTo(int newRowCount, int newColumnCount)
SelectableParts selectedParts() const
QByteArray mLabelParameterHash
0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fix...
bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const
void setMedianPen(const QPen &pen)
QList< QCPAbstractPlottable * > selectedPlottables() const
void selectionChanged(bool selected)
Q_SLOT bool setLayer(QCPLayer *layer)
QList< QCPGraph * > graphs() const
QCPAbstractPlottable * plottable()
bool contains(double value) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void visibleTickBounds(int &lowIndex, int &highIndex) const
The axis backbone and tick marks.
double realLength() const
virtual void mouseMoveEvent(QMouseEvent *event)
QCPBarDataMap * data() const
QCPLineEnding lowerEnding
EndingStyle style() const
Bar spacing is in key coordinates and thus scales with the key axis range.
virtual void draw(QCPPainter *painter)
QCPItemAnchor * anchor(const QString &name) const
void drawGridLines(QCPPainter *painter) const
void setSpacingType(SpacingType spacingType)
virtual void draw(QCPPainter *painter)
void setSelectedTickLabelFont(const QFont &font)
void setOffset(int offset)
QColor mSelectedTickLabelColor
void setBasePen(const QPen &pen)
bool hasPlottable(QCPAbstractPlottable *plottable) const
void setVisible(bool visible)
The tracer is not visible.
virtual QPointF anchorPixelPoint(int anchorId) const
virtual void drawImpulsePlot(QCPPainter *painter, QVector< QPointF > *lineData) const
void setSelectedBorderPen(const QPen &pen)
void setPixmap(const QPixmap &pixmap)
QColor getTickLabelColor() const
QCPItemPosition *const topLeft
SelectableParts mSelectedParts
custom painter operations are performed per scatter (As QPainterPath, see setCustomPath) ...
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
The abstract base class for all entries in a QCPLegend.
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const
QFont mSelectedTickLabelFont
void setHead(const QCPLineEnding &head)
bool remove(QCPLayoutElement *element)
{ssPeace.png} a circle, with one vertical and two downward diagonal lines
Tick labels (numbers) of this axis (as a whole, not individually)
bool mAntialiasedZeroLine
void setStyle(BracketStyle style)
virtual void draw(QCPPainter *painter)
void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event)
QColor getTextColor() const
void addChild(QCPLayerable *layerable, bool prepend)
void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end)
double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const
void setPenPositive(const QPen &pen)
static AxisType marginSideToAxisType(QCP::MarginSide side)
0x0001 Axis base line and tick marks
QCPItemAnchor * createAnchor(const QString &name, int anchorId)
Q_SLOT void setDataRange(const QCPRange &dataRange)
void setName(const QString &name)
QPainterPath customPath() const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void setRowStretchFactors(const QList< double > &factors)
virtual void draw(QCPPainter *painter)
void setRangeReversed(bool reversed)
QPointF upperFillBasePoint(double upperKey) const
void setSelectedBasePen(const QPen &pen)
Responsible for drawing the grid of a QCPAxis.
Qt::Alignment positionAlignment() const
QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes) ...
QCPItemAnchor * parentAnchor() const
QVector< QString > tickLabels
void addData(const QCPFinancialDataMap &dataMap)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setWhiskerWidth(double width)
void dataRangeChanged(QCPRange newRange)
void setTextAlignment(Qt::Alignment alignment)
const QCPRange range() const
QCPColorGradient mGradient
QList< QCPGraph * > graphs() const
void setSelectedBrush(const QBrush &brush)
void setSelectedSubTickPen(const QPen &pen)
void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
virtual void mouseReleaseEvent(QMouseEvent *event)
QCPColorMapData * data() const
bool noAntialiasingOnDrag() const
QRect axisSelectionBox() const
bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1)
virtual void wheelEvent(QWheelEvent *event)
void setCustomPath(const QPainterPath &customPath)
void removeDataBefore(double key)
QList< QCPItemPosition * > mPositions
void setShape(ScatterShape shape)
QCP::PlottingHints plottingHints() const
QCustomPlot * mParentPlot
QColor mSelectedTextColor
void setBackgroundScaled(bool scaled)
Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white.
void setTickLabels(bool show)
An anchor of an item to which positions can be attached to.
void setSelectedPen(const QPen &pen)
Qt::Orientations mRangeZoom
void setBrush(const QBrush &brush)
virtual int calculateAutoMargin(QCP::MarginSide side)
void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
QCPAxis * keyAxis() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QPointF anchorPixelPoint(int anchorId) const
Phase in which the margins are calculated and set.
Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts)
void setSelectedIconBorderPen(const QPen &pen)
Static positioning in pixels, starting from the top left corner of the viewport/widget.
void setAntialiasedScatters(bool enabled)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
void setRangeZoom(Qt::Orientations orientations)
void setLowerQuartile(double value)
QCPItemRect(QCustomPlot *parentPlot)
QCPItemAnchor * mParentAnchorX
QCache< QString, CachedLabel > mLabelCache
void mouseRelease(QMouseEvent *event)
void setSelectedTextColor(const QColor &color)
A brace with angled edges.
void setSelectedPen(const QPen &pen)
QCPItemPosition *const right
void setWhiskerPen(const QPen &pen)
void setAdaptiveSampling(bool enabled)
void setAutoTickStep(bool on)
int findIndexAboveY(const QVector< QPointF > *data, double y) const
QVector< double > subTickPositions
void setSubTickCount(int count)
void rangeChanged(const QCPRange &newRange)
void setAutoTicks(bool on)
A plus shaped crosshair with limited size.
void rescaleDataRange(bool onlyVisibleMaps)
void mouseDoubleClick(QMouseEvent *event)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
QCPPlotTitle(QCustomPlot *parentPlot)
void setupFullAxesBox(bool connectRanges=false)
void getPreparedData(QVector< QCPData > *lineData, QVector< QCPData > *scatterData) const
QCPItemLine(QCustomPlot *parentPlot)
virtual void mouseReleaseEvent(QMouseEvent *event)
void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical)
QCPFinancialDataMap * mData
Q_SLOT void setSelectableParts(const SelectableParts &selectableParts)
QCPAxis * addAxis(QCPAxis::AxisType type, QCPAxis *axis=0)
double tickLabelRotation() const
QCPLineEnding head() const
static bool validRange(double lower, double upper)
Base class for all drawable objects.
virtual void draw(QCPPainter *painter)
QPixmap mBackgroundPixmap
void setAutoSubTicks(bool on)
void setInterpolating(bool enabled)
virtual void drawWhiskers(QCPPainter *painter) const
void setValueAxis(QCPAxis *axis)
bool mGradientImageInvalidated
void setBackground(const QPixmap &pm)
double getPixelSpacing(const QCPBars *bars, double keyCoord)
void setPadding(int padding)
A plottable representing a bar chart in a plot.
void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const
const QCP::Interactions interactions() const
bool removeGraph(QCPGraph *graph)
QVector< double > mTickVector
void setRange(const QCPRange &keyRange, const QCPRange &valueRange)
0x080 All other objects are selectable (e.g. your own derived layerables, the plot title...
QList< QCPAbstractPlottable * > plottables() const
void setCoords(double key, double value)
void addChild(QCP::MarginSide side, QCPLayoutElement *element)
void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) ...
friend class QCPItemAnchor
Q_SLOT void setSelectable(bool selectable)
void setSelectedPen(const QPen &pen)
void setWidth(double width)
void loadPreset(GradientPreset preset)
void moveAbove(QCPBars *bars)
virtual QCP::Interaction selectionCategory() const
virtual void mousePressEvent(QMouseEvent *event)
void setSize(int keySize, int valueSize)
void moveBelow(QCPBars *bars)
void setScaleLogBase(double base)
void setScatterStyle(const QCPScatterStyle &style)
virtual void mouseMoveEvent(QMouseEvent *event)
void setInteraction(const QCP::Interaction &interaction, bool enabled=true)
void setRangeUpper(double upper)
void setModes(PainterModes modes)
QCPItemTracer(QCustomPlot *parentPlot)
void recalculateDataBounds()
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
void getStepCenterPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
QColor mSelectedTextColor
void titleClick(QMouseEvent *event, QCPPlotTitle *title)
virtual QRect clipRect() const
virtual QCP::Interaction selectionCategory() const
void layerChanged(QCPLayer *newLayer)
virtual bool addToLegend()
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const =0
bool addElement(int row, int column, QCPLayoutElement *element)
void setStyle(EndingStyle style)
QPointer< QCPBars > mBarBelow
void setValueSize(int valueSize)
virtual ~QCPLayoutElement()
QList< QCPLayerable * > children() const
void setTickLabelRotation(double degrees)
QCPScatterStyle mScatterStyle
void setTypeX(PositionType type)
0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixma...
QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual void deselectEvent(bool *selectionStateChanged)
A layout that arranges child elements in a grid.
void setPen(const QPen &pen)
virtual void mousePressEvent(QMouseEvent *event)
void setFont(const QFont &font)
void setColor(const QColor &color)
void selectionChangedByUser()
0x08 Axis is horizontal and on the bottom side of the axis rect
bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0)
QPointer< QCPBars > mBarAbove
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPScatterStyle mOutlierStyle
void setUpperEnding(const QCPLineEnding &ending)
void setPixmap(const QPixmap &pixmap)
Tick coordinate is regarded as a date/time (seconds since 1970-01-01T00:00:00 UTC) and will be displa...
void setWidth(double width)
void getTraverseCornerPoints(int prevRegion, int currentRegion, double rectLeft, double rectTop, double rectRight, double rectBottom, QVector< QPointF > &beforeTraverse, QVector< QPointF > &afterTraverse) const
virtual QSize minimumSizeHint() const
virtual QCP::Interaction selectionCategory() const
QCPItemText(QCustomPlot *parentPlot)
QList< QCPLayer * > mLayers
void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title)
void setRangeDrag(Qt::Orientations orientations)
QCP::AntialiasedElements mNotAntialiasedElements
QCPItemAnchor *const bottom
0x0040 Main lines of items
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void removeChild(QCPLayerable *layerable)
QCPAxisRect * axisRect() const
virtual QCPLayoutElement * takeAt(int index)
QImage mUndersampledMapImage
virtual QCP::Interaction selectionCategory() const
void removeData(double fromKey, double toKey)
no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) ...
void removeDataBefore(double key)
bool begin(QPaintDevice *device)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const
virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize)
void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false)
void getLinePlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
QCPLineEnding upperEnding() const
The abstract base class for all data representing objects in a plot.
QCP::MarginSides mAutoMargins
void setColorScale(QCPColorScale *colorScale)
QCPColorGradient inverted() const
Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion ...
QRectF insetRect(int index) const
QCPRange sanitizedForLogScale() const
void setSelectedBrush(const QBrush &brush)
void setBackground(const QPixmap &pm)
virtual QByteArray generateLabelParameterHash() const
void setAutoTickCount(int approximateCount)
void releaseElement(QCPLayoutElement *el)
void removeChildX(QCPItemPosition *pos)
QCPItemAnchor *const left
QPointer< QCPAxis > mValueAxis
void setSubTickLengthOut(int outside)
void setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis)
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
QList< QCPBars * > bars() const
void removeData(double fromt, double tot)
void setTwoColored(bool twoColored)
Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint)
QPointF lowerFillBasePoint(double lowerKey) const
bool moveToLayer(QCPLayer *layer, bool prepend)
QPointer< QCPAxis > mColorAxis
0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) ...
void setSubGridPen(const QPen &pen)
virtual QSize minimumSizeHint() const
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void removeDataAfter(double t)
QList< QCPAbstractLegendItem * > selectedItems() const
void setAntialiasedSubGrid(bool enabled)
virtual ~QCPItemStraightLine()
Tick labels will be displayed outside the axis rect.
virtual void draw(QCPPainter *painter)
QCPItemAnchor * parentAnchorY() const
Continuous lightness from black over icey colors to white (suited for non-biased data representation)...
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
line is drawn as steps where the step height is the value of the left data point
void selectionChanged(const QCPAxis::SelectableParts &parts)
virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const
QCPItemPosition *const endDir
void setErrorBarSize(double size)
0x02 Axis is vertical and on the right side of the axis rect
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
An approximation of the visible light spectrum (creates banding illusion but allows more precise magn...
void setBackgroundScaled(bool scaled)
void setTickLabelFont(const QFont &font)
QCPItemPosition *const bottomRight
QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange)
int subTickLengthIn() const
QCPColorGradient mGradient
void setTextColor(const QColor &color)
virtual ~QCPItemEllipse()
Bar width is in absolute pixels.
int tickLengthOut() const
void getScatterPlotData(QVector< QCPData > *scatterData) const
Qt::AspectRatioMode aspectRatioMode() const
QList< QCPAxis * > axes() const
QCustomPlot * mParentPlot
bool removeLayer(QCPLayer *layer)
void setSelectedLabelFont(const QFont &font)
void getPixelWidth(double key, double &lower, double &upper) const
QCPColorScale * colorScale() const
A plottable representing a graph in a plot.
void applyFillAntialiasingHint(QCPPainter *painter) const
QCPItemPosition *const start
int iconTextPadding() const
The abstract base class for all items in a plot.
QCPAbstractLegendItem(QCPLegend *parent)
QCPLayoutInset * mInsetLayout
void setData(double key, double value, double z)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const =0
Q_SLOT void setSelectable(bool selectable)
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance.
QRect tickLabelsSelectionBox() const
void setPadding(const QMargins &padding)
Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power...
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
Q_SLOT void setSelectable(bool selectable)
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
QCPLegend * mParentLegend
QPointer< QCPAxis > mKeyAxis
QVector< int > getSectionSizes(QVector< int > maxSizes, QVector< int > minSizes, QVector< double > stretchFactors, int totalSize) const
void getVisibleDataBounds(QCPFinancialDataMap::const_iterator &lower, QCPFinancialDataMap::const_iterator &upper) const
virtual QSize maximumSizeHint() const
QRect mTickLabelsSelectionBox
void setRangeLower(double lower)
void setBrush(const QBrush &brush)
QCPItemCurve(QCustomPlot *parentPlot)
QCPColorScale(QCustomPlot *parentPlot)
QPointer< QCPAxis > mRangeZoomHorzAxis
QCPItemAnchor *const right
bool mNoAntialiasingOnDrag
The central class of the library. This is the QWidget which displays the plot and interacts with the ...
virtual void wheelEvent(QWheelEvent *event)
void setMedian(double value)
void setAntialiasing(bool enabled)
void setPen(const QPen &pen)
virtual QSize minimumSizeHint() const
0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see QCPAbstractItem) ...
virtual void draw(QCPPainter *painter)
Candlestick representation.
void setMinimum(double value)
void setWidth(double width)
void getMinimumRowColSizes(QVector< int > *minColWidths, QVector< int > *minRowHeights) const
void setBrushNegative(const QBrush &brush)
Manages a single axis inside a QCustomPlot.
QCPLineEnding tail() const
QCPAxis::AxisType type() const
double upperQuartile() const
QCPBarsGroup * barsGroup() const
Q_SLOT void setSelectable(bool selectable)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
double lowerQuartile() const
void drawLine(const QLineF &line)
QList< QCPAbstractItem * > selectedItems() const
Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allo...
void draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const
void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical)
int commonMargin(QCP::MarginSide side) const
void setTickPen(const QPen &pen)
void setMaximum(double value)
void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const
QCPColorScale * mParentColorScale
void setPen(const QPen &pen)
void setColorStops(const QMap< double, QColor > &colorStops)
virtual int elementCount() const
QCPLayer * layer(const QString &name) const
A filled arrow head with a straight/flat back (a triangle)
void getImpulsePlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
PositionType type() const
int findIndexAboveX(const QVector< QPointF > *data, double x) const
Represents the visual appearance of scatter points.
virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const
double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const
void setOutlierStyle(const QCPScatterStyle &style)
Manages a legend inside a QCustomPlot.
bool mAntialiasedErrorBars
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QList< QCPLayerable * > mChildren
QSet< QCPItemPosition * > mChildrenY
void insert(int i, QCPBars *bars)
QCPLineEnding lowerEnding() const
void setCell(int keyIndex, int valueIndex, double z)
bool addItem(QCPAbstractItem *item)
PositionType mPositionTypeY
QCPLayerable * parentLayerable() const
QVector< QPointF > getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const
virtual QSize maximumSizeHint() const
virtual void drawLinePlot(QCPPainter *painter, QVector< QPointF > *lineData) const
QPointer< QCPColorScaleAxisRectPrivate > mAxisRect
void setInsetRect(int index, const QRectF &rect)
line is drawn as steps where the step is in between two data points
void setTextColor(const QColor &color)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual bool take(QCPLayoutElement *element)=0
void getStepLeftPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
bool addPlottable(QCPAbstractPlottable *plottable)
Qt::AspectRatioMode mBackgroundScaledMode
double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const
void setBrush(const QBrush &brush)
0x0200 Borders of fills (e.g. under or between graphs)
bool abbreviateDecimalPowers
0x004 The user can select multiple objects by holding the modifier set by QCustomPlot::setMultiSelect...
QCPAbstractPlottable * plottable()
void removeData(double fromKey, double toKey)
QCPItemAnchor *const bottomRight
void setBackgroundScaledMode(Qt::AspectRatioMode mode)
void setSpacing(double spacing)
QPointer< QCPAxis > mValueAxis
Bar width is in key coordinates and thus scales with the key axis range.
void addData(const QCPCurveDataMap &dataMap)
void setRowSpacing(int pixels)
QCPRange valueRange() const
QCPItemPosition * createPosition(const QString &name)
void setMinimumSize(const QSize &size)
QCPRange mDragStartVertRange
QVector< double > mSubTickVector
void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end)
QPen getSubTickPen() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setKeyAxis(QCPAxis *axis)
QLineF getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const
QPolygonF getBarPolygon(double key, double value) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
AdjacencyIterator begin(const Adjacency &adj, const Vector< D > &vct, size_t pixel_index)
returns an iterator to first valid adjacent element.
A layer that may contain objects, to control the rendering order.
Qt::Orientation orientation() const
Continuous lightness from black over firey colors to white (suited for non-biased data representation...
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void setPen(const QPen &pen)
QCPItemPosition *const position
void rescaleDataRange(bool recalculateDataBounds=false)
void setInverted(bool inverted)
LabelSide tickLabelSide() const
void setAutoMargins(QCP::MarginSides sides)
virtual void axisRemoved(QCPAxis *axis)
0x00 Default mode for painting on screen devices
void setTickVector(const QVector< double > &vec)
QFont getLabelFont() const
Error bars for both key and value dimensions of the data point are shown.
SpacingType spacingType() const
The abstract base class for all objects that form the layout system.
QCPBarsGroup(QCustomPlot *parentPlot)
QColor getLabelColor() const
void setGraph(QCPGraph *graph)
void mousePress(QMouseEvent *event)
Continuous lightness from black to white (suited for non-biased data representation) ...
virtual void update(UpdatePhase phase)
void setFont(const QFont &font)
virtual void draw(QCPPainter *painter)
int findIndexBelowX(const QVector< QPointF > *data, double x) const
QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis)
void plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event)
QCPRange expanded(const QCPRange &otherRange) const
QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name)
Q_SLOT void setGradient(const QCPColorGradient &gradient)
void applyScattersAntialiasingHint(QCPPainter *painter) const
QCPAxis * keyAxis() const
void setOuterRect(const QRect &rect)
void setPen(const QPen &pen)
bool mayTraverse(int prevRegion, int currentRegion) const
QCPLayer(QCustomPlot *parentPlot, const QString &layerName)
void setLineStyle(LineStyle ls)
void setDataBothError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError, const QVector< double > &valueError)
QCPColorGradient gradient() const
void setPen(const QPen &pen)
virtual QPointF anchorPixelPoint(int anchorId) const
void setUpperQuartile(double value)
void updateLayerIndices() const
QCPLineEnding upperEnding
void selectableChanged(bool selectable)
void setTextColor(const QColor &color)
Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts)
void getMaximumRowColSizes(QVector< int > *maxColWidths, QVector< int > *maxRowHeights) const
void insertColumn(int newIndex)
void setColumnSpacing(int pixels)
QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const
Qt::AspectRatioMode mAspectRatioMode
QCPItemStraightLine(QCustomPlot *parentPlot)
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false)
QPen selectedIconBorderPen() const
virtual void draw(QCPPainter *painter)=0
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QCPItemAnchor * parentAnchorX() const
int findIndexBelowY(const QVector< QPointF > *data, double y) const
virtual QList< QCPLayoutElement * > elements(bool recursive) const
virtual ~QCPAbstractItem()
virtual bool removeFromLegend() const
QCPBarsGroup * mBarsGroup
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType)
QMap< double, QCPBarData > QCPBarDataMap
QCPItemAnchor *const left
void removeData(double fromKey, double toKey)
virtual void draw(QCPPainter *painter)
virtual void drawOutliers(QCPPainter *painter) const
double getStackedBaseValue(double key, bool positive) const
virtual void updateLayout()
void setTightBoundary(bool enabled)
bool operator==(const QCPColorGradient &other) const
QList< QCPAxis * > addAxes(QCPAxis::AxisTypes types)
bool autoSubTicks() const
void setWidthType(WidthType widthType)
virtual QPointF pixelPoint() const
A brace with round edges.
A layout that places child elements aligned to the border or arbitrarily positioned.
void setData(QCPColorMapData *data, bool copy=false)
virtual void deselectEvent(bool *selectionStateChanged)
QPen getIconBorderPen() const
void setViewport(const QRect &rect)
0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) ...
virtual void drawMedian(QCPPainter *painter) const
void setStyle(TracerStyle style)
void setNoAntialiasingOnDrag(bool enabled)
double scaleLogBase() const
Handles the different ending decorations for line-like items.
A color scale for use with color coding data such as QCPColorMap.
QCPDataMap * data() const
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void removeFillBasePoints(QVector< QPointF > *lineData) const
virtual void update(UpdatePhase phase)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCP::Interaction selectionCategory() const
QCP::PlottingHints mPlottingHints
Holds the data of one single data point for QCPGraph.
QCPAxis * valueAxis() const
QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const
Error bars for the key dimension of the data point are shown.
virtual QSize minimumSizeHint() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual QCPItemPosition * toQCPItemPosition()
QPointer< QCPAxisRect > mClipAxisRect
void applyDefaultAntialiasingHint(QCPPainter *painter) const
bool mAntialiasedScatters
QVector< QString > mTickVectorLabels
int getMarginValue(const QMargins &margins, QCP::MarginSide side)
The positive sign domain, i.e. numbers greater than zero.
void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
void setPixelPoint(const QPointF &pixelPoint)
QList< QCPAbstractPlottable * > mPlottables
QCustomPlot * parentPlot() const
void applyTo(QCPPainter *painter, const QPen &defaultPen) const
QPainter subclass used internally.
void append(QCPBars *bars)
Qt::TransformationMode transformationMode() const
void setTickLength(int inside, int outside=0)
QCPCurveDataMap * data() const
void setAntialiasedErrorBars(bool enabled)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Q_SLOT void setSelected(bool selected)
virtual QPointF anchorPixelPoint(int anchorId) const
QSet< QCPItemPosition * > mChildrenX
Qt::TimeSpec mDateTimeSpec
WidthType widthType() const
QCPItemEllipse(QCustomPlot *parentPlot)
{ssCrossCircle.png} a circle with a cross inside
void setPlottingHints(const QCP::PlottingHints &hints)
void coordsToPixels(double key, double value, double &x, double &y) const
void setErrorBarSkipSymbol(bool enabled)
void drawBackground(QCPPainter *painter)
double data(double key, double value)
double boundingDistance() const
QCPItemAnchor *const bottom
QCPGrid(QCPAxis *parentAxis)
virtual bool take(QCPLayoutElement *element)
Q_SLOT void setSelected(bool selected)
void setColorInterpolation(ColorInterpolation interpolation)
QCPLineEnding head() const
{ssDot.png} a single pixel (use ssDisc or ssCircle if you want a round shape with a certain radius) ...
virtual void drawFill(QCPPainter *painter, QVector< QPointF > *lineData) const
double pointDistance(const QPointF &pixelPoint) const
void setChartStyle(ChartStyle style)
void setBarsGroup(QCPBarsGroup *barsGroup)
virtual void mouseMoveEvent(QMouseEvent *event)
void setDateTimeSpec(const Qt::TimeSpec &timeSpec)
QVector< QRgb > mColorBuffer
void registerBars(QCPBars *bars)
QCPAxisRect * axisRect() const
QCPAbstractItem * mParentItem
{ssPlusSquare.png} a square with a plus inside
A filled diamond (45° rotated square)
void setIconBorderPen(const QPen &pen)
void removeChildY(QCPItemPosition *pos)
Colors suitable to represent different elevations on geographical maps.
int selectionTolerance() const
void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const
void setSelectedFont(const QFont &font)
virtual QCP::Interaction selectionCategory() const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void setNumberPrecision(int precision)
QRect labelSelectionBox() const
static const double minRange
void removeDataBefore(double t)
QList< QCPAbstractItem * > items() const
void setSelectedPen(const QPen &pen)
QCPLayer * currentLayer() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const =0
QVector< double > mOutliers
Tick coordinate is regarded as normal number and will be displayed as such. (see setNumberFormat) ...
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
QPointer< QCPAxis > mRangeZoomVertAxis
void setKeyRange(const QCPRange &keyRange)
{ssTriangle.png} an equilateral triangle, standing on baseline
{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) ...
void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
void rescaleAxes(bool onlyEnlarge=false) const
0x0020 Main lines of plottables (excluding error bars, see element aeErrorBars)
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
bool autoTickStep() const
LabelType tickLabelType() const
void setData(QCPBarDataMap *data, bool copy=false)
static void connectBars(QCPBars *lower, QCPBars *upper)
QCPBars * barBelow() const
bool rangeReversed() const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
void setBrush(const QBrush &brush)
virtual void deselectEvent(bool *selectionStateChanged)
void setTickVectorLabels(const QVector< QString > &vec)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
A bar perpendicular to the line.
Q_SLOT void setSelectedParts(const SelectableParts &selectedParts)
void dataRangeChanged(QCPRange newRange)
void setRangeDrag(bool enabled)
data points are connected by a straight line
Final phase in which the layout system places the rects of the elements.
0x01 Axis is vertical and on the left side of the axis rect
void setLabelColor(const QColor &color)
void setAntialiasedFill(bool enabled)
QCP::AntialiasedElements mAntialiasedElements
void selectableChanged(bool selectable)
int getRegion(double x, double y, double rectLeft, double rectTop, double rectRight, double rectBottom) const
QLineF getRectClippedStraightLine(const QVector2D &point1, const QVector2D &vec, const QRect &rect) const
QCPItemPosition *const topLeft
QMap< double, QCPFinancialData > QCPFinancialDataMap
void setHead(const QCPLineEnding &head)
void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements)
QCPItemAnchor *const bottom
bool mAutoAddPlottableToLegend
void setAntialiased(bool enabled)
void setSelectedBrush(const QBrush &brush)
QCustomPlot * parentPlot() const
virtual QPointF anchorPixelPoint(int anchorId) const
void scaleRange(double factor, double center)
void getCurveData(QVector< QPointF > *lineData) const
void setData(QCPCurveDataMap *data, bool copy=false)
double baseLog(double value) const
QCPItemPixmap(QCustomPlot *parentPlot)
QCPLayout * layout() const
QCPAxis * rangeDragAxis(Qt::Orientation orientation)
bool savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0, const QString &pdfCreator=QString(), const QString &pdfTitle=QString())
QCPAxisRect * axisRect(int index=0) const
QCPColorGradient(GradientPreset preset=gpCold)
void rescaleValueAxis(bool onlyEnlarge=false) const
void setRowStretchFactor(int row, double factor)
bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1)
QCPAbstractPlottable * plottableAt(const QPointF &pos, bool onlySelectable=false) const
void setBarWidth(int width)
QList< double > mColumnStretchFactors
bool mMapImageInvalidated
BracketStyle style() const
QList< QCPGraph * > selectedGraphs() const
bool removeItem(QCPAbstractItem *item)
void drawBackground(QCPPainter *painter)
A layout element displaying a plot title text.
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual bool take(QCPLayoutElement *element)
Bar width is given by a fraction of the axis rect size.
void setInterpolate(bool enabled)
SelectableParts selectedParts() const
void setPen(const QPen &pen)
Q_SLOT void deselectAll()
QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis)
QPointer< QCPColorScale > mColorScale
void setTickLabelSide(LabelSide side)
QCPLayoutInset * insetLayout() const
QPointer< QCPAxis > mRangeDragVertAxis
The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot...
virtual ~QCPItemBracket()
void removeChild(QCP::MarginSide side, QCPLayoutElement *element)
void setBrush(const QBrush &brush)
virtual QCPLayoutElement * takeAt(int index)
void setSelectionTolerance(int pixels)
void setSelectedPen(const QPen &pen)
void setDataKeyError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError)
QPointer< QCPAxis > mRangeDragHorzAxis
void setPen(const QPen &pen)
static AxisType opposite(AxisType type)
virtual void draw(QCPPainter *painter)
double pixelToCoord(double value) const
QMap< double, QColor > mColorStops
{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
QStack< bool > mAntialiasingStack
void addData(const QCPBarDataMap &dataMap)
void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Phase used for any type of preparation that needs to be done before margin calculation and layout...
virtual void draw(QCPPainter *painter)
void setTickStep(double step)
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove)
void selectableChanged(bool selectable)
void setTickLabelType(LabelType type)
double mRangeZoomFactorHorz
Q_SLOT void setDataRange(const QCPRange &dataRange)
virtual int calculateAutoMargin(QCP::MarginSide side)
void setSelectedTextColor(const QColor &color)
double mScaleLogBaseLogInv
void setTickLengthOut(int outside)
double rangeZoomFactor(Qt::Orientation orientation)
QCPItemPosition *const point1
void setMultiSelectModifier(Qt::KeyboardModifier modifier)
QPen getBorderPen() const
void removeDataAfter(double key)
QList< QCPColorMap * > colorMaps() const
bool hasItem(QCPAbstractLegendItem *item) const
virtual void legendRemoved(QCPLegend *legend)
virtual void deselectEvent(bool *selectionStateChanged)
void unregisterBars(QCPBars *bars)
virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const =0
virtual void drawScatterPlot(QCPPainter *painter, QVector< QCPData > *scatterData) const
void setSelectedTickPen(const QPen &pen)
QCPAxis::ScaleType mDataScaleType
void setSelectedFont(const QFont &font)
void moveRange(double diff)
void setLabelFont(const QFont &font)
A bar perpendicular to the line, pointing out to only one side (to which side can be changed with set...
virtual void mousePressEvent(QMouseEvent *event)
0x002 Legend items individually (see selectedItems)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
QCPAxis::ScaleType mDataScaleType
QList< QCPLegend * > selectedLegends() const
double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const
QCPAbstractItem * item() const
virtual void updateLayout()
void addChildY(QCPItemPosition *pos)
{ssPlusCircle.png} a circle with a plus inside
void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum)
virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const
void setRotation(double degrees)
void setSubTickPen(const QPen &pen)
{ssCrossSquare.png} a square with a cross inside
QHash< QCPAxis::AxisType, QList< QCPAxis * > > mAxes
QCPItemAnchor *const right
void setLength(double length)
Data points are connected with a straight line.
void removeDataBefore(double key)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const =0
Dynamic positioning at a plot coordinate defined by two axes (see setAxes).
void addFillBasePoints(QVector< QPointF > *lineData) const
void setNumberFormat(const QString &formatCode)
SelectableParts mSelectableParts
void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const
QCPItemPosition *const startDir
virtual void draw(QCPPainter *painter)
ErrorType errorType() const
QCPRange sanitizedForLinScale() const
void setLineStyle(LineStyle style)
virtual QRect clipRect() const
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle ...
void scaleTypeChanged(QCPAxis::ScaleType scaleType)
QCPLayoutElement * element(int row, int column) const
QCPAxisPainterPrivate(QCustomPlot *parentPlot)
Qt::Alignment insetAlignment(int index) const
void getPlotData(QVector< QPointF > *lineData, QVector< QCPData > *scatterData) const
virtual QPointF pixelPoint() const
double basePow(double value) const
SelectablePart getPartAt(const QPointF &pos) const
virtual void draw(QCPPainter *painter)
void setTail(const QCPLineEnding &tail)
Holds the two-dimensional data of a QCPColorMap plottable.
bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
virtual void update(UpdatePhase phase)
void setSelectedFont(const QFont &font)
QList< QCPAbstractItem * > mItems
int autoTickCount() const
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom, QCPAxisRect::setRangeZoomAxes)
QCPAbstractLegendItem * item(int index) const
virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=0) const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
QString numberFormat() const
void setTickLengthIn(int inside)
double mRangeZoomFactorVert
void setSelectedColor(const QColor &color)
void setSelectedPen(const QPen &pen)
void setErrorType(ErrorType errorType)
void setRangeZoomFactor(double horizontalFactor, double verticalFactor)
void setSelectedBrush(const QBrush &brush)
Q_SLOT void setScaleType(QCPAxis::ScaleType type)
void setClipToAxisRect(bool clip)
TracerStyle style() const
void plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event)
void setColumnStretchFactors(const QList< double > &factors)
a custom pixmap specified by setPixmap, centered on the data point coordinates
void mouseWheel(QWheelEvent *event)
bool addItem(QCPAbstractLegendItem *item)
Continuous lightness from black over weak blueish colors to white (suited for non-biased data represe...
void setMarginValue(QMargins &margins, QCP::MarginSide side, int value)
void setPen(const QPen &pen)
QFont getTickLabelFont() const
QCPAxisPainterPrivate * mAxisPainter
virtual void updateLayout()
void setMode(PainterMode mode, bool enabled=true)
The abstract base class for layouts.
void setSubGridVisible(bool visible)
void setDataValueError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &valueError)
Holds the data of one single data point for QCPFinancial.
void setTickLabelPadding(int padding)
virtual void drawScatterPlot(QCPPainter *painter, const QVector< QPointF > *pointData) const
virtual void resizeEvent(QResizeEvent *event)
double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const
void setSelectedLabelColor(const QColor &color)
QCPItemPosition *const bottomRight
None of the selectable parts.
void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group)
QCPLayoutElement * layoutElementAt(const QPointF &pos) const
void setInteractions(const QCP::Interactions &interactions)
void setBrush(const QBrush &brush)
void selectionChanged(bool selected)
0x04 Axis is horizontal and on the top side of the axis rect
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
bool realVisibility() const
QCPItemAnchor *const left
QCPAbstractPlottable * mPlottable
QCPAbstractPlottable * plottable(int index)
ColorInterpolation mColorInterpolation
QCPPlottableLegendItem * itemWithPlottable(const QCPAbstractPlottable *plottable) const
QCPItemAnchor *const bottomLeft
QCPAxis * axis(QCPAxis::AxisType type, int index=0) const
{ssTriangleInverted.png} an equilateral triangle, standing on corner
virtual void draw(QCPPainter *painter)
void setLength(double length)
A plottable representing a two-dimensional color map in a plot.
Layer is inserted above other layer.
void rescale(bool onlyVisiblePlottables=false)
QHash< QCP::MarginSide, QList< QCPLayoutElement * > > mChildren
void setPlottingHint(QCP::PlottingHint hint, bool enabled=true)
QCPAxis * valueAxis() const
QPointer< QCPAxis > mKeyAxis
Both sign domains, including zero, i.e. all (rational) numbers.
InsetPlacement insetPlacement(int index) const
QString dateTimeFormat() const
void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation)
void setColumnStretchFactor(int column, double factor)
void setSelectedPen(const QPen &pen)
bool setCurrentLayer(const QString &name)
QCPItemPosition *const position
void setAxisRect(QCPAxisRect *axisRect)
int tickLabelPadding() const
void addChildX(QCPItemPosition *pos)
QCPAxis::LabelSide tickLabelSide
void getStepRightPlotData(QVector< QPointF > *linePixelData, QVector< QCPData > *scatterData) const
QPointer< QCPLayerable > mParentLayerable
QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis)
int subTickLengthOut() const
QList< QCPAbstractPlottable * > plottables() const
QCPItemAnchor *const topLeft
Queues the refresh such that it is performed at a slightly delayed point in time after the replot...
Color channels red, green and blue are linearly interpolated.
virtual void draw(QCPPainter *painter)
const QPolygonF getChannelFillPolygon(const QVector< QPointF > *lineData) const
QCPItemAnchor *const right
Tick labels will be displayed inside the axis rect and clipped to the inner axis rect.
void setSelectedFont(const QFont &font)
QList< double > mRowStretchFactors
void setInsetAlignment(int index, Qt::Alignment alignment)
double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const
void setPen(const QPen &pen)
QPixmap mScaledBackgroundPixmap
QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis)
bool removeAxis(QCPAxis *axis)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
Qt::TimeSpec dateTimeSpec() const
void setRangeZoom(bool enabled)
QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId=-1)
void setAutoAddPlottableToLegend(bool on)
QPointer< QCPAxisRect > mAxisRect
void setClipAxisRect(QCPAxisRect *rect)
Qt::TransformationMode mTransformationMode
virtual int calculateMargin()
void setText(const QString &text)
void setPen(const QPen &pen)
QVector< double > tickPositions
QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true)
void selectionChanged(bool selected)
void setSelectedTextColor(const QColor &color)
virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const
void removeDataAfter(double key)
void expand(const QCPRange &otherRange)
QCPAbstractItem * itemAt(const QPointF &pos, bool onlySelectable=false) const
QCPRange dataBounds() const
QCPLayerable * layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const
A non-filled arrow head with open back.
void setSelectedPen(const QPen &pen)
void setBorderPen(const QPen &pen)
SelectableParts selectableParts() const
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
void setZeroLinePen(const QPen &pen)
QCPItemPosition *const point2
bool hasAnchor(const QString &name) const
Bar spacing is in absolute pixels.
void gradientChanged(QCPColorGradient newGradient)
void selectableChanged(const QCPAxis::SelectableParts &parts)
virtual void draw(QCPPainter *painter)
void setIconSize(const QSize &size)
virtual void mouseReleaseEvent(QMouseEvent *event)
void setBaseValue(double baseValue)
QCPItemAnchor * mParentAnchorY
virtual QSize maximumSizeHint() const
0x0400 Zero-lines, see QCPGrid::setZeroLinePen
virtual QRect clipRect() const
void setData(QCPDataMap *data, bool copy=false)
bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove)
void setSelectedPen(const QPen &pen)
double coordToPixel(double value) const
void applyErrorBarsAntialiasingHint(QCPPainter *painter) const
void setScatterStyle(const QCPScatterStyle &style)
QList< QCPAxis * > axes(QCPAxis::AxisTypes types) const
virtual ~QCPItemPosition()
Manages the position of an item.
void adoptElement(QCPLayoutElement *el)
void setValueRange(const QCPRange &valueRange)
bool hasItem(QCPAbstractItem *item) const
QPen iconBorderPen() const
QCPItemPosition *const end
A curly brace with varying stroke width giving a calligraphic impression.
QList< QCPAbstractItem * > items() const
void setSize(double size)
QPixmap mBackgroundPixmap
void setGraphKey(double key)
Defines a color gradient for use with e.g. QCPColorMap.
QCPMarginGroup(QCustomPlot *parentPlot)
void setErrorPen(const QPen &pen)
virtual QSize sizeHint() const
void setTypeY(PositionType type)
QCPMarginGroup * marginGroup(QCP::MarginSide side) const
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType)
QPixmap mScaledBackgroundPixmap
QCPAbstractItem(QCustomPlot *parentPlot)
void setSubTickLength(int inside, int outside=0)
void setBrushPositive(const QBrush &brush)
QMap< double, QColor > colorStops() const
A bar that is skewed (skew controllable via setLength)
virtual void parentPlotInitialized(QCustomPlot *parentPlot)
Represents the range an axis is encompassing.
QCPRange dataRange() const
QCPLayoutGrid * mPlotLayout
void setAntialiasedZeroLine(bool enabled)
virtual void draw(QCPPainter *painter)
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
void getVisibleDataBounds(QCPBarDataMap::const_iterator &lower, QCPBarDataMap::const_iterator &upperEnd) const
virtual QPointF anchorPixelPoint(int anchorId) const
void setPositionAlignment(Qt::Alignment alignment)
void setData(QCPFinancialDataMap *data, bool copy=false)
QList< QCPItemAnchor * > mAnchors
QCPRange mDragStartHorzRange
QCPScatterStyle mScatterStyle
Groups multiple QCPBars together so they appear side by side.
virtual void deselectEvent(bool *selectionStateChanged)
0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts)
void initializeParentPlot(QCustomPlot *parentPlot)
void setSelectedBrush(const QBrush &brush)
void setSelectedTickLabelColor(const QColor &color)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
virtual void generateAutoTicks()
bool removePlottable(QCPAbstractPlottable *plottable)
void setTail(const QCPLineEnding &tail)
void setTickLabelColor(const QColor &color)
void setSize(double size)
void setBrush(const QBrush &brush)
ScaleType scaleType() const
Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and pha...
void pixelsToCoords(double x, double y, double &key, double &value) const
void setSelectedPen(const QPen &pen)
QCPItemPosition *const topLeft
bool removeItem(int index)
SelectableParts selectableParts() const
virtual void draw(QCPPainter *painter)
virtual void deselectEvent(bool *selectionStateChanged)
virtual void draw(QCPPainter *painter)
virtual QCPLayoutElement * elementAt(int index) const
friend class QCPPlottableLegendItem
QCPFinancialDataMap * data() const
virtual void setupTickVectors()
PositionType mPositionTypeX
void addData(const QCPDataMap &dataMap)
Qt::Alignment mPositionAlignment
QList< QCPAxisRect * > axisRects() const
Holds multiple axes and arranges them in a rectangular shape.
void setPen(const QPen &pen)
virtual ~QCPLayoutInset()
virtual void paintEvent(QPaintEvent *event)
{ssDiamond.png} a diamond
QCPAxisRect * clipAxisRect() const
QCP::AntialiasedElements mAADragBackup
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const
QCPColorMapData & operator=(const QCPColorMapData &other)
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const
bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false)
void toPainter(QCPPainter *painter, int width=0, int height=0)
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const
QPixmap toPixmap(int width=0, int height=0, double scale=1.0)
virtual QSize minimumSizeHint() const
Qt::KeyboardModifier mMultiSelectModifier
void setPenNegative(const QPen &pen)
void setLabel(const QString &str)
QPointer< QCPLayoutElement > mMouseEventElement
virtual void draw(QCPPainter *painter)
QCP::AntialiasedElements notAntialiasedElements() const
void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements)
QMap< double, QCPCurveData > QCPCurveDataMap
Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18))
Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts)
void sizeConstraintsChanged() const
Q_SLOT void setRange(const QCPRange &range)
QList< QCPAxis * > selectedAxes() const
A filled arrow head with an indented back.
line is drawn as steps where the step height is the value of the right data point ...
virtual void deselectEvent(bool *selectionStateChanged)
QCP::Interactions mInteractions
QCPItemAnchor *const topRight
void gradientChanged(QCPColorGradient newGradient)
Qt::Alignment mTextAlignment
void setLabel(const QString &str)
QLatin1Char mNumberFormatChar
int axisCount(QCPAxis::AxisType type) const
QCPItemPosition *const left
bool mColorBufferInvalidated
int axisRectCount() const
QCustomPlot * mParentPlot
QPointer< QCPGraph > mChannelFillGraph
virtual void draw(QCPPainter *painter)
void updateGradientImage()
AxisType axisType() const
void setChannelFillGraph(QCPGraph *targetGraph)
void setWidth(double width)
double keyPixelOffset(const QCPBars *bars, double keyCoord)
void setFont(const QFont &font)
bool hasElement(int row, int column)
virtual QList< QCPLayoutElement * > elements(bool recursive) const
QCustomPlot * mParentPlot
ScatterShape shape() const
void setSelectedBrush(const QBrush &brush)
void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const
void setPen(const QPen &pen)
QCPItemPosition *const bottomRight
Error bars for the value dimension of the data point are shown.
Qt::AspectRatioMode mBackgroundScaledMode
virtual void wheelEvent(QWheelEvent *event)
static big_t count(int syms, int len, int left)
Q_SLOT void setSelected(bool selected)
QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0)
virtual void draw(QCPPainter *painter)
double pointDistance(const QPointF &pixelPoint) const
virtual void draw(QCPPainter *painter)
QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis)
Holds the data of one single data point (one bar) for QCPBars.
QColor mSelectedLabelColor
void setFont(const QFont &font)
void setColorStopAt(double position, const QColor &color)
void setLabelPadding(int padding)