260 mPen.setColor(Qt::blue);
261 mPen.setStyle(Qt::SolidLine);
263 mBrush.setColor(Qt::blue);
264 mBrush.setStyle(Qt::NoBrush);
317 n = qMin(n, value.size());
319 for (
int i=0; i<n; ++i)
321 newData.
key = key[i];
322 newData.value = value[i];
323 mData->insertMulti(newData.key, newData);
338 n = qMin(n, value.size());
339 n = qMin(n, valueError.size());
341 for (
int i=0; i<n; ++i)
343 newData.
key = key[i];
344 newData.value = value[i];
345 newData.valueErrorMinus = valueError[i];
346 newData.valueErrorPlus = valueError[i];
347 mData->insertMulti(key[i], newData);
360 void QCPGraph::setDataValueError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &valueErrorMinus,
const QVector<double> &valueErrorPlus)
364 n = qMin(n, value.size());
365 n = qMin(n, valueErrorMinus.size());
366 n = qMin(n, valueErrorPlus.size());
368 for (
int i=0; i<n; ++i)
370 newData.
key = key[i];
371 newData.value = value[i];
372 newData.valueErrorMinus = valueErrorMinus[i];
373 newData.valueErrorPlus = valueErrorPlus[i];
374 mData->insertMulti(key[i], newData);
389 n = qMin(n, value.size());
390 n = qMin(n, keyError.size());
392 for (
int i=0; i<n; ++i)
394 newData.
key = key[i];
395 newData.value = value[i];
396 newData.keyErrorMinus = keyError[i];
397 newData.keyErrorPlus = keyError[i];
398 mData->insertMulti(key[i], newData);
411 void QCPGraph::setDataKeyError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyErrorMinus,
const QVector<double> &keyErrorPlus)
415 n = qMin(n, value.size());
416 n = qMin(n, keyErrorMinus.size());
417 n = qMin(n, keyErrorPlus.size());
419 for (
int i=0; i<n; ++i)
421 newData.
key = key[i];
422 newData.value = value[i];
423 newData.keyErrorMinus = keyErrorMinus[i];
424 newData.keyErrorPlus = keyErrorPlus[i];
425 mData->insertMulti(key[i], newData);
436 void QCPGraph::setDataBothError(
const QVector<double> &key,
const QVector<double> &value,
const QVector<double> &keyError,
const QVector<double> &valueError)
440 n = qMin(n, value.size());
441 n = qMin(n, valueError.size());
442 n = qMin(n, keyError.size());
444 for (
int i=0; i<n; ++i)
446 newData.
key = key[i];
447 newData.value = value[i];
448 newData.keyErrorMinus = keyError[i];
449 newData.keyErrorPlus = keyError[i];
450 newData.valueErrorMinus = valueError[i];
451 newData.valueErrorPlus = valueError[i];
452 mData->insertMulti(key[i], newData);
465 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)
469 n = qMin(n, value.size());
470 n = qMin(n, valueErrorMinus.size());
471 n = qMin(n, valueErrorPlus.size());
472 n = qMin(n, keyErrorMinus.size());
473 n = qMin(n, keyErrorPlus.size());
475 for (
int i=0; i<n; ++i)
477 newData.
key = key[i];
478 newData.value = value[i];
479 newData.keyErrorMinus = keyErrorMinus[i];
480 newData.keyErrorPlus = keyErrorPlus[i];
481 newData.valueErrorMinus = valueErrorMinus[i];
482 newData.valueErrorPlus = valueErrorPlus[i];
483 mData->insertMulti(key[i], newData);
581 if (targetGraph ==
this)
583 qDebug() <<
FUNCNAME <<
"targetGraph is self";
590 qDebug() <<
FUNCNAME <<
"targetGraph not in same plot";
604 mData->unite(dataMap);
624 newData.
value = value;
625 mData->insertMulti(newData.
key, newData);
634 int n = qMin(keys.size(), values.size());
636 for (
int i=0; i<n; ++i)
638 newData.
key = keys[i];
639 newData.value = values[i];
640 mData->insertMulti(newData.key, newData);
650 QCPDataMap::iterator it =
mData->begin();
651 while (it !=
mData->end() && it.key() < key)
652 it =
mData->erase(it);
661 if (
mData->isEmpty())
return;
662 QCPDataMap::iterator it =
mData->upperBound(key);
663 while (it !=
mData->end())
664 it =
mData->erase(it);
676 if (fromKey >= toKey ||
mData->isEmpty())
return;
677 QCPDataMap::iterator it =
mData->upperBound(fromKey);
678 QCPDataMap::iterator itEnd =
mData->upperBound(toKey);
680 it =
mData->erase(it);
725 if (
mData->isEmpty())
return;
756 if (
mData->isEmpty())
return;
783 if (
mData->isEmpty())
return;
788 QVector<QPointF> *lineData =
new QVector<QPointF>;
789 QVector<QCPData> *pointData = 0;
791 pointData =
new QVector<QCPData>;
819 if (
mBrush.style() != Qt::NoBrush)
822 painter->fillRect(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0,
mBrush);
828 painter->setPen(
mPen);
829 painter->drawLine(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0);
839 newSize.scale(rect.size(), Qt::KeepAspectRatio);
841 targetRect.setSize(newSize);
842 targetRect.moveCenter(rect.center());
843 bool smoothBackup = painter->testRenderHint(QPainter::SmoothPixmapTransform);
844 painter->setRenderHint(QPainter::SmoothPixmapTransform,
true);
846 painter->setRenderHint(QPainter::SmoothPixmapTransform, smoothBackup);
849 painter->setPen(
mPen);
893 if (!pointData)
return;
896 QCPDataMap::const_iterator lower, upper;
901 pointData->resize(dataCount);
904 QCPDataMap::const_iterator it = lower;
905 QCPDataMap::const_iterator upperEnd = upper+1;
909 while (it != upperEnd)
911 (*pointData)[i] = it.value();
917 while (it != upperEnd)
919 (*pointData)[i] = it.value();
939 QCPDataMap::const_iterator lower, upper;
946 lineData->reserve(dataCount+2);
947 lineData->resize(dataCount);
950 pointData->resize(dataCount);
953 QCPDataMap::const_iterator it = lower;
954 QCPDataMap::const_iterator upperEnd = upper+1;
958 while (it != upperEnd)
961 (*pointData)[i] = it.value();
969 while (it != upperEnd)
972 (*pointData)[i] = it.value();
994 QCPDataMap::const_iterator lower, upper;
1002 lineData->reserve(dataCount*2+2);
1003 lineData->resize(dataCount*2);
1006 pointData->resize(dataCount);
1009 QCPDataMap::const_iterator it = lower;
1010 QCPDataMap::const_iterator upperEnd = upper+1;
1017 while (it != upperEnd)
1021 (*pointData)[ipoint] = it.value();
1025 (*lineData)[i].setX(lastValue);
1026 (*lineData)[i].setY(key);
1029 (*lineData)[i].setX(lastValue);
1030 (*lineData)[i].setY(key);
1038 while (it != upperEnd)
1042 (*pointData)[ipoint] = it.value();
1046 (*lineData)[i].setX(key);
1047 (*lineData)[i].setY(lastValue);
1050 (*lineData)[i].setX(key);
1051 (*lineData)[i].setY(lastValue);
1071 QCPDataMap::const_iterator lower, upper;
1079 lineData->reserve(dataCount*2+2);
1080 lineData->resize(dataCount*2);
1083 pointData->resize(dataCount);
1086 QCPDataMap::const_iterator it = lower;
1087 QCPDataMap::const_iterator upperEnd = upper+1;
1094 while (it != upperEnd)
1098 (*pointData)[ipoint] = it.value();
1102 (*lineData)[i].setX(value);
1103 (*lineData)[i].setY(lastKey);
1106 (*lineData)[i].setX(value);
1107 (*lineData)[i].setY(lastKey);
1115 while (it != upperEnd)
1119 (*pointData)[ipoint] = it.value();
1123 (*lineData)[i].setX(lastKey);
1124 (*lineData)[i].setY(value);
1127 (*lineData)[i].setX(lastKey);
1128 (*lineData)[i].setY(value);
1148 QCPDataMap::const_iterator lower, upper;
1156 lineData->reserve(dataCount*2+2);
1157 lineData->resize(dataCount*2);
1160 pointData->resize(dataCount);
1163 QCPDataMap::const_iterator it = lower;
1164 QCPDataMap::const_iterator upperEnd = upper+1;
1174 (*pointData)[ipoint] = it.value();
1177 (*lineData)[i].setX(lastValue);
1178 (*lineData)[i].setY(lastKey);
1181 while (it != upperEnd)
1185 (*pointData)[ipoint] = it.value();
1189 (*lineData)[i].setX(lastValue);
1190 (*lineData)[i].setY(key);
1194 (*lineData)[i].setX(lastValue);
1195 (*lineData)[i].setY(key);
1199 (*lineData)[i].setX(lastValue);
1200 (*lineData)[i].setY(lastKey);
1208 (*pointData)[ipoint] = it.value();
1211 (*lineData)[i].setX(lastKey);
1212 (*lineData)[i].setY(lastValue);
1215 while (it != upperEnd)
1219 (*pointData)[ipoint] = it.value();
1223 (*lineData)[i].setX(key);
1224 (*lineData)[i].setY(lastValue);
1228 (*lineData)[i].setX(key);
1229 (*lineData)[i].setY(lastValue);
1233 (*lineData)[i].setX(lastKey);
1234 (*lineData)[i].setY(lastValue);
1251 QCPDataMap::const_iterator lower, upper;
1258 lineData->resize(dataCount*2);
1261 pointData->resize(dataCount);
1264 QCPDataMap::const_iterator it = lower;
1265 QCPDataMap::const_iterator upperEnd = upper+1;
1272 while (it != upperEnd)
1276 (*pointData)[ipoint] = it.value();
1280 (*lineData)[i].setX(zeroPointX);
1281 (*lineData)[i].setY(key);
1284 (*lineData)[i].setY(key);
1292 while (it != upperEnd)
1296 (*pointData)[ipoint] = it.value();
1300 (*lineData)[i].setX(key);
1301 (*lineData)[i].setY(zeroPointY);
1303 (*lineData)[i].setX(key);
1325 if (
mBrush.style() == Qt::NoBrush ||
mBrush.color().alpha() == 0)
return;
1332 painter->setPen(Qt::NoPen);
1333 painter->setBrush(
mBrush);
1334 painter->drawPolygon(QPolygonF(*lineData));
1339 painter->setPen(Qt::NoPen);
1340 painter->setBrush(
mBrush);
1361 for (
int i=0; i<pointData->size(); ++i)
1365 for (
int i=0; i<pointData->size(); ++i)
1372 painter->setPen(
mPen);
1373 painter->setBrush(
mBrush);
1376 for (
int i=0; i<pointData->size(); ++i)
1380 for (
int i=0; i<pointData->size(); ++i)
1396 if (
mPen.style() != Qt::NoPen &&
mPen.color().alpha() != 0)
1399 painter->setPen(
mPen);
1400 painter->setBrush(Qt::NoBrush);
1401 painter->drawPolyline(QPolygonF(*lineData));
1414 if (
mPen.style() != Qt::NoPen &&
mPen.color().alpha() != 0)
1417 painter->setPen(
mPen);
1418 painter->setBrush(Qt::NoBrush);
1419 painter->drawLines(*lineData);
1446 painter->drawPoint(QPointF(x, y));
1451 painter->drawLine(QLineF(x-w, y-w, x+w, y+w));
1452 painter->drawLine(QLineF(x-w, y+w, x+w, y-w));
1457 painter->drawLine(QLineF(x-w, y, x+w, y));
1458 painter->drawLine(QLineF(x, y+w, x, y-w));
1463 painter->setBrush(Qt::NoBrush);
1469 painter->setBrush(QBrush(painter->pen().color()));
1470 painter->drawEllipse(QPointF(x,y), w, w);
1475 painter->setBrush(Qt::NoBrush);
1481 painter->drawLine(QLineF(x-w, y, x+w, y));
1482 painter->drawLine(QLineF(x, y+w, x, y-w));
1483 painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.707, y+w*0.707));
1484 painter->drawLine(QLineF(x-w*0.707, y+w*0.707, x+w*0.707, y-w*0.707));
1489 painter->drawLine(QLineF(x-w, y+0.755*w, x+w, y+0.755*w));
1490 painter->drawLine(QLineF(x+w, y+0.755*w, x, y-0.977*w));
1491 painter->drawLine(QLineF(x, y-0.977*w, x-w, y+0.755*w));
1496 painter->drawLine(QLineF(x-w, y-0.755*w, x+w, y-0.755*w));
1497 painter->drawLine(QLineF(x+w, y-0.755*w, x, y+0.977*w));
1498 painter->drawLine(QLineF(x, y+0.977*w, x-w, y-0.755*w));
1503 painter->setBrush(Qt::NoBrush);
1504 painter->drawLine(QLineF(x-w, y-w, x+w*0.95, y+w*0.95));
1505 painter->drawLine(QLineF(x-w, y+w*0.95, x+w*0.95, y-w));
1511 painter->setBrush(Qt::NoBrush);
1512 painter->drawLine(QLineF(x-w, y, x+w*0.95, y));
1513 painter->drawLine(QLineF(x, y+w, x, y-w));
1519 painter->setBrush(Qt::NoBrush);
1520 painter->drawLine(QLineF(x-w*0.707, y-w*0.707, x+w*0.67, y+w*0.67));
1521 painter->drawLine(QLineF(x-w*0.707, y+w*0.67, x+w*0.67, y-w*0.707));
1527 painter->setBrush(Qt::NoBrush);
1528 painter->drawLine(QLineF(x-w, y, x+w, y));
1529 painter->drawLine(QLineF(x, y+w, x, y-w));
1535 painter->setBrush(Qt::NoBrush);
1536 painter->drawLine(QLineF(x, y-w, x, y+w));
1537 painter->drawLine(QLineF(x, y, x-w*0.707, y+w*0.707));
1538 painter->drawLine(QLineF(x, y, x+w*0.707, y+w*0.707));
1583 if (a-y > skipSymbolMargin)
1584 painter->drawLine(QLineF(x, a, x, y+skipSymbolMargin));
1585 if (y-b > skipSymbolMargin)
1586 painter->drawLine(QLineF(x, y-skipSymbolMargin, x, b));
1588 painter->drawLine(QLineF(x, a, x, b));
1590 painter->drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a));
1591 painter->drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b));
1602 if (x-a > skipSymbolMargin)
1603 painter->drawLine(QLineF(a, y, x-skipSymbolMargin, y));
1604 if (b-x > skipSymbolMargin)
1605 painter->drawLine(QLineF(x+skipSymbolMargin, y, b, y));
1607 painter->drawLine(QLineF(a, y, b, y));
1609 painter->drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf));
1610 painter->drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf));
1624 if (x-a > skipSymbolMargin)
1625 painter->drawLine(QLineF(a, y, x-skipSymbolMargin, y));
1626 if (b-x > skipSymbolMargin)
1627 painter->drawLine(QLineF(x+skipSymbolMargin, y, b, y));
1629 painter->drawLine(QLineF(a, y, b, y));
1631 painter->drawLine(QLineF(a, y-barWidthHalf, a, y+barWidthHalf));
1632 painter->drawLine(QLineF(b, y-barWidthHalf, b, y+barWidthHalf));
1643 if (a-y > skipSymbolMargin)
1644 painter->drawLine(QLineF(x, a, x, y+skipSymbolMargin));
1645 if (y-b > skipSymbolMargin)
1646 painter->drawLine(QLineF(x, y-skipSymbolMargin, x, b));
1648 painter->drawLine(QLineF(x, a, x, b));
1650 painter->drawLine(QLineF(x-barWidthHalf, a, x+barWidthHalf, a));
1651 painter->drawLine(QLineF(x-barWidthHalf, b, x+barWidthHalf, b));
1674 bool lowoutlier = lbound !=
mData->constBegin();
1675 bool highoutlier = ubound+1 !=
mData->constEnd();
1676 lower = (lowoutlier ? lbound-1 : lbound);
1677 upper = (highoutlier ? ubound+1 : ubound);
1680 QCPDataMap::const_iterator it = lower;
1724 lineData->remove(lineData->size()-2, 2);
1748 point.setY(lowerKey);
1752 point.setY(lowerKey);
1755 point.setX(lowerKey);
1759 point.setX(lowerKey);
1773 point.setY(lowerKey);
1776 point.setX(lowerKey);
1808 point.setY(upperKey);
1812 point.setY(upperKey);
1815 point.setX(upperKey);
1819 point.setX(upperKey);
1833 point.setY(upperKey);
1836 point.setX(upperKey);
1861 if (lineData->isEmpty())
return QPolygonF();
1862 QVector<QPointF> otherData;
1864 if (otherData.isEmpty())
return QPolygonF();
1865 QVector<QPointF> thisData;
1866 thisData.reserve(lineData->size()+otherData.size());
1867 for (
int i=0; i<lineData->size(); ++i)
1868 thisData << lineData->at(i);
1871 QVector<QPointF> *staticData = &thisData;
1872 QVector<QPointF> *croppedData = &otherData;
1879 if (staticData->first().x() > staticData->last().x())
1881 int size = staticData->size();
1882 for (
int i=0; i<size/2; ++i)
1883 qSwap((*staticData)[i], (*staticData)[size-1-i]);
1885 if (croppedData->first().x() > croppedData->last().x())
1887 int size = croppedData->size();
1888 for (
int i=0; i<size/2; ++i)
1889 qSwap((*croppedData)[i], (*croppedData)[size-1-i]);
1892 if (staticData->first().x() < croppedData->first().x())
1893 qSwap(staticData, croppedData);
1895 if (lowBound == -1)
return QPolygonF();
1896 croppedData->remove(0, lowBound);
1899 if (croppedData->size() < 2)
return QPolygonF();
1901 if (croppedData->at(1).x()-croppedData->at(0).x() != 0)
1902 slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x());
1905 (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x()));
1906 (*croppedData)[0].setX(staticData->first().x());
1909 if (staticData->last().x() > croppedData->last().x())
1910 qSwap(staticData, croppedData);
1912 if (highBound == -1)
return QPolygonF();
1913 croppedData->remove(highBound+1, croppedData->size()-(highBound+1));
1916 if (croppedData->size() < 2)
return QPolygonF();
1917 int li = croppedData->size()-1;
1918 if (croppedData->at(li).x()-croppedData->at(li-1).x() != 0)
1919 slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x());
1922 (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x()));
1923 (*croppedData)[li].setX(staticData->last().x());
1930 if (staticData->first().y() < staticData->last().y())
1932 int size = staticData->size();
1933 for (
int i=0; i<size/2; ++i)
1934 qSwap((*staticData)[i], (*staticData)[size-1-i]);
1936 if (croppedData->first().y() < croppedData->last().y())
1938 int size = croppedData->size();
1939 for (
int i=0; i<size/2; ++i)
1940 qSwap((*croppedData)[i], (*croppedData)[size-1-i]);
1943 if (staticData->first().y() > croppedData->first().y())
1944 qSwap(staticData, croppedData);
1946 if (lowBound == -1)
return QPolygonF();
1947 croppedData->remove(0, lowBound);
1950 if (croppedData->size() < 2)
return QPolygonF();
1952 if (croppedData->at(1).y()-croppedData->at(0).y() != 0)
1953 slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y());
1956 (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y()));
1957 (*croppedData)[0].setY(staticData->first().y());
1960 if (staticData->last().y() < croppedData->last().y())
1961 qSwap(staticData, croppedData);
1963 if (highBound == -1)
return QPolygonF();
1964 croppedData->remove(highBound+1, croppedData->size()-(highBound+1));
1967 if (croppedData->size() < 2)
return QPolygonF();
1968 int li = croppedData->size()-1;
1969 if (croppedData->at(li).y()-croppedData->at(li-1).y() != 0)
1970 slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y());
1973 (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y()));
1974 (*croppedData)[li].setY(staticData->last().y());
1978 for (
int i=otherData.size()-1; i>=0; --i)
1979 thisData << otherData.at(i);
1980 return QPolygonF(thisData);
1992 for (
int i=data->size()-1; i>=0; --i)
1994 if (data->at(i).x() < x)
1996 if (i<data->size()-1)
1999 return data->size()-1;
2014 for (
int i=0; i<data->size(); ++i)
2016 if (data->at(i).x() > x)
2036 for (
int i=0; i<data->size(); ++i)
2038 if (data->at(i).y() < y)
2058 for (
int i=data->size()-1; i>=0; --i)
2060 if (data->at(i).y() > y)
2062 if (i<data->size()-1)
2065 return data->size()-1;
2076 return getKeyRange(validRange, inSignDomain,
true);
2095 bool haveLower =
false;
2096 bool haveUpper =
false;
2098 double current, currentErrorMinus, currentErrorPlus;
2100 if (inSignDomain ==
SDBoth)
2102 QCPDataMap::const_iterator it =
mData->constBegin();
2103 while (it !=
mData->constEnd())
2105 current = it.value().key;
2106 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
2107 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
2108 if (current-currentErrorMinus < range.
lower || !haveLower)
2110 range.
lower = current-currentErrorMinus;
2113 if (current+currentErrorPlus > range.
upper || !haveUpper)
2115 range.
upper = current+currentErrorPlus;
2122 QCPDataMap::const_iterator it =
mData->constBegin();
2123 while (it !=
mData->constEnd())
2125 current = it.value().key;
2126 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
2127 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
2128 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus < 0)
2130 range.
lower = current-currentErrorMinus;
2133 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus < 0)
2135 range.
upper = current+currentErrorPlus;
2140 if ((current < range.
lower || !haveLower) && current < 0)
2142 range.
lower = current;
2145 if ((current > range.
upper || !haveUpper) && current < 0)
2147 range.
upper = current;
2155 QCPDataMap::const_iterator it =
mData->constBegin();
2156 while (it !=
mData->constEnd())
2158 current = it.value().key;
2159 currentErrorMinus = (includeErrors ? it.value().keyErrorMinus : 0);
2160 currentErrorPlus = (includeErrors ? it.value().keyErrorPlus : 0);
2161 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus > 0)
2163 range.
lower = current-currentErrorMinus;
2166 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus > 0)
2168 range.
upper = current+currentErrorPlus;
2173 if ((current < range.
lower || !haveLower) && current > 0)
2175 range.
lower = current;
2178 if ((current > range.
upper || !haveUpper) && current > 0)
2180 range.
upper = current;
2188 validRange = haveLower && haveUpper;
2200 bool haveLower =
false;
2201 bool haveUpper =
false;
2203 double current, currentErrorMinus, currentErrorPlus;
2205 if (inSignDomain ==
SDBoth)
2207 QCPDataMap::const_iterator it =
mData->constBegin();
2208 while (it !=
mData->constEnd())
2210 current = it.value().value;
2211 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
2212 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
2213 if (current-currentErrorMinus < range.
lower || !haveLower)
2215 range.
lower = current-currentErrorMinus;
2218 if (current+currentErrorPlus > range.
upper || !haveUpper)
2220 range.
upper = current+currentErrorPlus;
2227 QCPDataMap::const_iterator it =
mData->constBegin();
2228 while (it !=
mData->constEnd())
2230 current = it.value().value;
2231 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
2232 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
2233 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus < 0)
2235 range.
lower = current-currentErrorMinus;
2238 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus < 0)
2240 range.
upper = current+currentErrorPlus;
2245 if ((current < range.
lower || !haveLower) && current < 0)
2247 range.
lower = current;
2250 if ((current > range.
upper || !haveUpper) && current < 0)
2252 range.
upper = current;
2260 QCPDataMap::const_iterator it =
mData->constBegin();
2261 while (it !=
mData->constEnd())
2263 current = it.value().value;
2264 currentErrorMinus = (includeErrors ? it.value().valueErrorMinus : 0);
2265 currentErrorPlus = (includeErrors ? it.value().valueErrorPlus : 0);
2266 if ((current-currentErrorMinus < range.
lower || !haveLower) && current-currentErrorMinus > 0)
2268 range.
lower = current-currentErrorMinus;
2271 if ((current+currentErrorPlus > range.
upper || !haveUpper) && current+currentErrorPlus > 0)
2273 range.
upper = current+currentErrorPlus;
2278 if ((current < range.
lower || !haveLower) && current > 0)
2280 range.
lower = current;
2283 if ((current > range.
upper || !haveUpper) && current > 0)
2285 range.
upper = current;
2293 validRange = haveLower && haveUpper;
2342 this->lower =
lower;
2343 this->upper =
upper;
2386 double rangeFac = 1e-3;
2391 if (sanitizedRange.
lower == 0.0 && sanitizedRange.
upper != 0.0)
2394 if (rangeFac < sanitizedRange.
upper*rangeFac)
2395 sanitizedRange.
lower = rangeFac;
2397 sanitizedRange.
lower = sanitizedRange.
upper*rangeFac;
2399 else if (sanitizedRange.
lower != 0.0 && sanitizedRange.
upper == 0.0)
2402 if (-rangeFac > sanitizedRange.
lower*rangeFac)
2403 sanitizedRange.
upper = -rangeFac;
2405 sanitizedRange.
upper = sanitizedRange.
lower*rangeFac;
2406 }
else if (sanitizedRange.
lower < 0 && sanitizedRange.
upper > 0)
2409 if (-sanitizedRange.
lower > sanitizedRange.
upper)
2412 if (-rangeFac > sanitizedRange.
lower*rangeFac)
2413 sanitizedRange.
upper = -rangeFac;
2415 sanitizedRange.
upper = sanitizedRange.
lower*rangeFac;
2419 if (rangeFac < sanitizedRange.
upper*rangeFac)
2420 sanitizedRange.
lower = rangeFac;
2422 sanitizedRange.
lower = sanitizedRange.
upper*rangeFac;
2426 return sanitizedRange;
2437 return sanitizedRange;
2555 for (
int i=0; i<
mItems.size(); ++i)
2612 mSize = QSize(width, height);
2807 if (index >= 0 && index <
mItems.size())
2821 for (
int i=0; i<
mItems.size(); ++i)
2825 if (lip->plottable() == plottable)
2846 return mItems.contains(item);
2869 if (!
mItems.contains(item))
2886 if (index >= 0 && index <
mItems.size())
2939 painter->setBrush(
mBrush);
2944 painter->setClipRect(QRect(
mPosition,
mSize).adjusted(1, 1, 0, 0));
2945 painter->setPen(QPen());
2946 painter->setBrush(Qt::NoBrush);
2948 for (
int i=0; i<
mItems.size(); ++i)
2950 QSize itemSize =
mItems.at(i)->size(QSize(
mSize.width(), 0));
2965 for (
int i=0; i<
mItems.size(); ++i)
2967 QSize itemSize =
mItems.at(i)->size(QSize(
mSize.width(), 0));
2970 if (point->x() >= itemPosTopLeft.x() &&
2971 point->x() <= itemPosTopLeft.x()+itemSize.width() &&
2972 point->y() >= itemPosTopLeft.y() &&
2973 point->y() <= itemPosTopLeft.y()+itemSize.height())
2994 int repeatCount = 0;
2995 while (repeat && repeatCount < 3)
2999 for (
int i=0; i<
mItems.size(); ++i)
3001 QSize s =
mItems.at(i)->size(QSize(width, 0));
3002 currentTop += s.height();
3005 if (width < s.width())
3014 qDebug() <<
FUNCNAME <<
"hit repeat limit for iterative width calculation";
3018 mSize.setWidth(width);
3020 mSize.setHeight(currentTop);
3077 mTickVector =
new QVector<double>;
3078 mSubTickVector =
new QVector<double>;
3079 mTickVectorLabels =
new QVector<QString>;
3081 setAxisRect(parentPlot->
axisRect());
3082 setScaleType(STLinear);
3083 setScaleLogBase(10);
3087 setRangeReversed(
false);
3091 setAutoTickCount(6);
3093 setAutoTickLabels(
true);
3094 setAutoTickStep(
true);
3095 setTickLabelFont(parentPlot->font());
3097 setTickPen(QPen(Qt::black));
3098 setTickLabels(
true);
3099 setTickLabelType(LTNumber);
3100 setTickLabelRotation(0);
3101 setDateTimeFormat(
"hh:mm:ss\ndd.MM.yy");
3102 setNumberFormat(
"gbd");
3103 setNumberPrecision(6);
3105 setLabelFont(parentPlot->font());
3107 setAutoSubTicks(
true);
3109 setSubTickLength(2);
3110 setSubTickPen(QPen(Qt::black));
3113 gPen.setColor(QColor(200,200,200));
3114 gPen.setStyle(Qt::DotLine);
3118 subgPen.setColor(QColor(220,220,220));
3119 subgPen.setStyle(Qt::DotLine);
3120 setSubGridPen(subgPen);
3123 zlinePen.setColor(QColor(200,200,200));
3124 setZeroLinePen(zlinePen);
3125 setBasePen(QPen(Qt::black));
3130 setTickLabelPadding(3);
3132 }
else if (type == ATRight)
3134 setTickLabelPadding(7);
3135 setLabelPadding(12);
3136 }
else if (type == ATBottom)
3138 setTickLabelPadding(3);
3140 }
else if (type == ATLeft)
3142 setTickLabelPadding(5);
3143 setLabelPadding(10);
3150 delete mTickVectorLabels;
3151 delete mSubTickVector;
3161 result.append(mNumberFormatChar);
3162 if (mNumberBeautifulPowers)
3165 if (mNumberMultiplyCross)
3180 mOrientation = (type == ATBottom || type == ATTop) ? Qt::Horizontal : Qt::Vertical;
3211 if (mScaleType == STLogarithmic)
3212 mRange = mRange.sanitizedForLogScale();
3226 mScaleLogBase = base;
3227 mScaleLogBaseLogInv = 1.0/log(mScaleLogBase);
3229 qDebug() <<
FUNCNAME <<
"Invalid logarithmic scale base (must be greater 1):" << base;
3243 if (mScaleType == STLogarithmic)
3250 emit rangeChanged(mRange);
3262 mRange.lower = lower;
3263 mRange.upper = upper;
3264 if (mScaleType == STLogarithmic)
3266 mRange = mRange.sanitizedForLogScale();
3269 mRange = mRange.sanitizedForLinScale();
3271 emit rangeChanged(mRange);
3289 if (alignment == Qt::AlignLeft)
3290 setRange(position, position+size);
3291 else if (alignment == Qt::AlignRight)
3292 setRange(position-size, position);
3294 setRange(position-size/2.0, position+size/2.0);
3303 mRange.lower = lower;
3304 if (mScaleType == STLogarithmic)
3306 mRange = mRange.sanitizedForLogScale();
3309 mRange = mRange.sanitizedForLinScale();
3311 emit rangeChanged(mRange);
3320 mRange.upper = upper;
3321 if (mScaleType == STLogarithmic)
3323 mRange = mRange.sanitizedForLogScale();
3326 mRange = mRange.sanitizedForLinScale();
3328 emit rangeChanged(mRange);
3340 mRangeReversed = reversed;
3391 mAutoTickCount = approximateCount;
3404 mAutoTickLabels = on;
3456 mTickLabelPadding = padding;
3471 mTickLabelType = type;
3479 mTickLabelFont =
font;
3489 mTickLabelRotation = qBound(-90.0, degrees, 90.0);
3499 mDateTimeFormat = format;
3540 if (formatCode.length() < 1)
return;
3543 QString allowedFormatChars =
"eEfgG";
3544 if (allowedFormatChars.contains(formatCode.at(0)))
3546 mNumberFormatChar = formatCode.at(0).toAscii();
3549 qDebug() <<
FUNCNAME <<
"Invalid number format code (first char not in 'eEfgG'):" << formatCode;
3552 if (formatCode.length() < 2)
3554 mNumberBeautifulPowers =
false;
3555 mNumberMultiplyCross =
false;
3560 if (formatCode.at(1) ==
'b' && (mNumberFormatChar ==
'e' || mNumberFormatChar ==
'g'))
3562 mNumberBeautifulPowers =
true;
3565 qDebug() <<
FUNCNAME <<
"Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode;
3568 if (formatCode.length() < 3)
3570 mNumberMultiplyCross =
false;
3575 if (formatCode.at(2) ==
'c')
3577 mNumberMultiplyCross =
true;
3578 }
else if (formatCode.at(2) ==
'd')
3580 mNumberMultiplyCross =
false;
3583 qDebug() <<
FUNCNAME <<
"Invalid number format code (third char neither 'c' nor 'd'):" << formatCode;
3601 mNumberPrecision = precision;
3632 *mTickVector = *vec;
3659 *mTickVectorLabels = *vec;
3662 delete mTickVectorLabels;
3663 mTickVectorLabels = vec;
3676 mTickLengthIn = inside;
3677 mTickLengthOut = outside;
3691 mSubTickCount = count;
3703 mSubTickLengthIn = inside;
3704 mSubTickLengthOut = outside;
3786 mLabelPadding = padding;
3815 if (mScaleType == STLinear)
3817 mRange.lower += diff;
3818 mRange.upper += diff;
3821 mRange.lower *= diff;
3822 mRange.upper *= diff;
3824 emit rangeChanged(mRange);
3836 if (mScaleType == STLinear)
3839 newRange.
lower = (mRange.lower-center)*factor + center;
3840 newRange.
upper = (mRange.upper-center)*factor + center;
3845 if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0))
3848 newRange.
lower = pow(mRange.lower/center, factor)*center;
3849 newRange.
upper = pow(mRange.upper/center, factor)*center;
3853 qDebug() <<
FUNCNAME <<
"center of scaling operation doesn't lie in same logarithmic sign domain as range:" << center;
3855 emit rangeChanged(mRange);
3868 int otherPixelSize, ownPixelSize;
3871 otherPixelSize = otherAxis->
mAxisRect.width();
3873 otherPixelSize = otherAxis->
mAxisRect.height();
3875 if (orientation() == Qt::Horizontal)
3876 ownPixelSize = mAxisRect.width();
3878 ownPixelSize = mAxisRect.height();
3880 double newRangeSize = ratio*otherAxis->
mRange.
size()*ownPixelSize/(double)otherPixelSize;
3881 setRange(range().center(), newRangeSize, Qt::AlignCenter);
3890 if (orientation() == Qt::Horizontal)
3892 if (mScaleType == STLinear)
3895 return -(value-mAxisRect.left())/(
double)mAxisRect.width()*mRange.size()+mRange.upper;
3897 return (value-mAxisRect.left())/(
double)mAxisRect.width()*mRange.size()+mRange.lower;
3901 return pow(mRange.upper/mRange.lower, (mAxisRect.left()-value)/(
double)mAxisRect.width())*mRange.upper;
3903 return pow(mRange.upper/mRange.lower, (value-mAxisRect.left())/(
double)mAxisRect.width())*mRange.lower;
3907 if (mScaleType == STLinear)
3910 return -(mAxisRect.bottom()-value)/(
double)mAxisRect.height()*mRange.size()+mRange.upper;
3912 return (mAxisRect.bottom()-value)/(
double)mAxisRect.height()*mRange.size()+mRange.lower;
3916 return pow(mRange.upper/mRange.lower, (value-mAxisRect.bottom())/(
double)mAxisRect.height())*mRange.upper;
3918 return pow(mRange.upper/mRange.lower, (mAxisRect.bottom()-value)/(
double)mAxisRect.height())*mRange.lower;
3929 if (orientation() == Qt::Horizontal)
3931 if (mScaleType == STLinear)
3934 return (mRange.upper-value)/mRange.size()*mAxisRect.width()+mAxisRect.left();
3936 return (value-mRange.lower)/mRange.size()*mAxisRect.width()+mAxisRect.left();
3939 if (value >= 0 && mRange.upper < 0)
3940 return mRangeReversed ? mAxisRect.left()-200 : mAxisRect.right()+200;
3941 else if (value <= 0 && mRange.upper > 0)
3942 return mRangeReversed ? mAxisRect.right()+200 : mAxisRect.left()-200;
3946 return baseLog(mRange.upper/value)/baseLog(mRange.upper/mRange.lower)*mAxisRect.width()+mAxisRect.left();
3948 return baseLog(value/mRange.lower)/baseLog(mRange.upper/mRange.lower)*mAxisRect.width()+mAxisRect.left();
3953 if (mScaleType == STLinear)
3956 return mAxisRect.bottom()-(mRange.upper-value)/mRange.size()*mAxisRect.height();
3958 return mAxisRect.bottom()-(value-mRange.lower)/mRange.size()*mAxisRect.height();
3961 if (value >= 0 && mRange.upper < 0)
3962 return mRangeReversed ? mAxisRect.bottom()+200 : mAxisRect.top()-200;
3963 else if (value <= 0 && mRange.upper > 0)
3964 return mRangeReversed ? mAxisRect.top()-200 : mAxisRect.bottom()+200;
3968 return mAxisRect.bottom()-baseLog(mRange.upper/value)/baseLog(mRange.upper/mRange.lower)*mAxisRect.height();
3970 return mAxisRect.bottom()-baseLog(value/mRange.lower)/baseLog(mRange.upper/mRange.lower)*mAxisRect.height();
3986 if ((!mTicks && !mTickLabels && !mGrid) || mRange.size() <= 0)
return;
3991 generateAutoTicks();
3994 emit ticksRequest();
3997 if (mTickVector->isEmpty())
3999 mSubTickVector->clear();
4004 mSubTickVector->resize((mTickVector->size()-1)*mSubTickCount);
4005 if (mSubTickCount > 0)
4007 double subTickStep = 0;
4008 double subTickPosition = 0;
4009 int subTickIndex = 0;
4011 for (
int i=1; i<mTickVector->size(); ++i)
4013 subTickStep = (mTickVector->at(i)-mTickVector->at(i-1))/(
double)(mSubTickCount+1);
4014 for (
int k=1; k<=mSubTickCount; ++k)
4016 subTickPosition = mTickVector->at(i-1) + k*subTickStep;
4017 if (subTickPosition < mRange.lower)
4019 if (subTickPosition > mRange.upper)
4024 (*mSubTickVector)[subTickIndex] = subTickPosition;
4029 mSubTickVector->resize(subTickIndex);
4033 mExponentialChar =
mParentPlot->locale().exponential();
4034 mPositiveSignChar =
mParentPlot->locale().positiveSign();
4035 if (mAutoTickLabels)
4037 int vecsize = mTickVector->size();
4038 mTickVectorLabels->resize(vecsize);
4039 if (mTickLabelType == LTNumber)
4041 for (
int i=0; i<vecsize; ++i)
4042 (*mTickVectorLabels)[i] =
mParentPlot->locale().toString(mTickVector->at(i), mNumberFormatChar, mNumberPrecision);
4043 }
else if (mTickLabelType == LTDateTime)
4045 for (
int i=0; i<vecsize; ++i)
4046 (*mTickVectorLabels)[i] =
mParentPlot->locale().toString(QDateTime::fromTime_t(mTickVector->at(i)), mDateTimeFormat);
4052 emit ticksRequest();
4055 if (mTickVectorLabels->size() < mTickVector->size())
4056 mTickVectorLabels->resize(mTickVector->size());
4071 if (mScaleType == STLinear)
4076 mTickStep = mRange.size()/(double)mAutoTickCount;
4077 double magnitudeFactor = pow(10, (
int)floor(log10(mTickStep)));
4078 double tickStepMantissa = mTickStep/magnitudeFactor;
4079 if (tickStepMantissa < 5)
4082 mTickStep = (int)(tickStepMantissa*2)/2.0*magnitudeFactor;
4086 mTickStep = (int)((tickStepMantissa/10.0)*5)/5.0*10*magnitudeFactor;
4090 mSubTickCount = calculateAutoSubTickCount(mTickStep);
4092 int firstStep = floor(mRange.lower/mTickStep);
4093 int lastStep = ceil(mRange.upper/mTickStep);
4094 int tickcount = lastStep-firstStep+1;
4095 if (tickcount < 0) tickcount = 0;
4096 mTickVector->resize(tickcount);
4097 for (
int i=0; i<tickcount; ++i)
4099 (*mTickVector)[i] = (firstStep+i)*mTickStep;
4104 if (mRange.lower > 0 && mRange.upper > 0)
4106 double lowerMag = basePow((
int)floor(baseLog(mRange.lower)));
4107 double currentMag = lowerMag;
4108 mTickVector->clear();
4109 mTickVector->append(currentMag);
4110 while (currentMag < mRange.upper && currentMag > 0)
4112 currentMag *= mScaleLogBase;
4113 mTickVector->append(currentMag);
4115 }
else if (mRange.lower < 0 && mRange.upper < 0)
4117 double lowerMag = -basePow((
int)ceil(baseLog(-mRange.lower)));
4118 double currentMag = lowerMag;
4119 mTickVector->clear();
4120 mTickVector->append(currentMag);
4121 while (currentMag < mRange.upper && currentMag < 0)
4123 currentMag /= mScaleLogBase;
4124 mTickVector->append(currentMag);
4128 mTickVector->clear();
4129 qDebug() <<
FUNCNAME <<
"Invalid range for logarithmic plot: " << mRange.lower <<
"-" << mRange.upper;
4149 int result = mSubTickCount;
4152 double magnitudeFactor = pow(10, (
int)floor(log10(tickStep)));
4153 double tickStepMantissa = tickStep/magnitudeFactor;
4156 double epsilon = 0.01;
4159 double fracPart = modf(tickStepMantissa, &intPartf);
4163 if (fracPart < epsilon || 1.0-fracPart < epsilon)
4165 if (1.0-fracPart < epsilon)
4169 case 1: result = 4;
break;
4170 case 2: result = 3;
break;
4171 case 3: result = 2;
break;
4172 case 4: result = 3;
break;
4173 case 5: result = 4;
break;
4174 case 6: result = 2;
break;
4175 case 7: result = 6;
break;
4176 case 8: result = 3;
break;
4177 case 9: result = 2;
break;
4182 if (qAbs(fracPart-0.5) < epsilon)
4186 case 1: result = 2;
break;
4187 case 2: result = 4;
break;
4188 case 3: result = 4;
break;
4189 case 4: result = 2;
break;
4190 case 5: result = 4;
break;
4191 case 6: result = 4;
break;
4192 case 7: result = 2;
break;
4193 case 8: result = 4;
break;
4194 case 9: result = 4;
break;
4211 if (!
mVisible || (!mGrid && mZeroLinePen.style() == Qt::NoPen))
return;
4213 int lowTick, highTick;
4214 visibleTickBounds(lowTick, highTick);
4216 if (orientation() == Qt::Horizontal)
4219 int zeroLineIndex = -1;
4220 if (mZeroLinePen.style() != Qt::NoPen && mRange.lower < 0 && mRange.upper > 0)
4223 painter->setPen(mZeroLinePen);
4224 double epsilon = mRange.size()*1E-6;
4225 for (
int i=lowTick; i <= highTick; ++i)
4227 if (fabs(mTickVector->at(i)) < epsilon)
4230 t = coordToPixel(mTickVector->at(i));
4231 painter->drawLine(t, mAxisRect.bottom(), t, mAxisRect.top());
4240 painter->setPen(mGridPen);
4241 for (
int i=lowTick; i <= highTick; ++i)
4243 if (i == zeroLineIndex)
continue;
4244 t = coordToPixel(mTickVector->at(i));
4245 painter->drawLine(t, mAxisRect.bottom(), t, mAxisRect.top());
4251 int zeroLineIndex = -1;
4252 if (mZeroLinePen.style() != Qt::NoPen && mRange.lower < 0 && mRange.upper > 0)
4255 painter->setPen(mZeroLinePen);
4256 double epsilon = mRange.size()*1E-6;
4257 for (
int i=lowTick; i <= highTick; ++i)
4259 if (fabs(mTickVector->at(i)) < epsilon)
4262 t = coordToPixel(mTickVector->at(i));
4263 painter->drawLine(mAxisRect.left(), t, mAxisRect.right(), t);
4272 painter->setPen(mGridPen);
4273 for (
int i=lowTick; i <= highTick; ++i)
4275 if (i == zeroLineIndex)
continue;
4276 t = coordToPixel(mTickVector->at(i));
4277 painter->drawLine(mAxisRect.left(), t, mAxisRect.right(), t);
4291 if (!
mVisible || !mSubGrid || !mGrid)
return;
4296 painter->setPen(mSubGridPen);
4297 if (orientation() == Qt::Horizontal)
4299 for (
int i=0; i<mSubTickVector->size(); ++i)
4301 t = coordToPixel(mSubTickVector->at(i));
4302 painter->drawLine(t, mAxisRect.bottom(), t, mAxisRect.top());
4306 for (
int i=0; i<mSubTickVector->size(); ++i)
4308 t = coordToPixel(mSubTickVector->at(i));
4309 painter->drawLine(mAxisRect.left(), t, mAxisRect.right(), t);
4326 if (mAxisType == ATLeft)
4327 origin = mAxisRect.bottomLeft();
4328 else if (mAxisType == ATRight)
4329 origin = mAxisRect.bottomRight();
4330 else if (mAxisType == ATTop)
4331 origin = mAxisRect.topLeft();
4332 else if (mAxisType == ATBottom)
4333 origin = mAxisRect.bottomLeft();
4335 int xCor = 0, yCor = 0;
4336 if (mAxisType == ATTop)
4338 else if (mAxisType == ATRight)
4342 int lowTick, highTick;
4343 visibleTickBounds(lowTick, highTick);
4348 painter->setPen(mBasePen);
4349 if (orientation() == Qt::Horizontal)
4350 painter->drawLine(origin+QPoint(xCor, yCor), origin+QPoint(mAxisRect.width()+xCor, yCor));
4352 painter->drawLine(origin+QPoint(xCor, yCor), origin+QPoint(xCor, -mAxisRect.height()+yCor));
4357 painter->setPen(mTickPen);
4359 int tickDir = (mAxisType == ATBottom || mAxisType == ATRight) ? -1 : 1;
4360 if (orientation() == Qt::Horizontal)
4362 for (
int i=lowTick; i <= highTick; ++i)
4364 t = coordToPixel(mTickVector->at(i));
4365 painter->drawLine(t+xCor, origin.y()-mTickLengthOut*tickDir+yCor, t+xCor, origin.y()+mTickLengthIn*tickDir+yCor);
4369 for (
int i=lowTick; i <= highTick; ++i)
4371 t = coordToPixel(mTickVector->at(i));
4372 painter->drawLine(origin.x()-mTickLengthOut*tickDir+xCor, t+yCor, origin.x()+mTickLengthIn*tickDir+xCor, t+yCor);
4378 if (mTicks && mSubTickCount > 0)
4380 painter->setPen(mSubTickPen);
4382 int tickDir = (mAxisType == ATBottom || mAxisType == ATRight) ? -1 : 1;
4383 if (orientation() == Qt::Horizontal)
4385 for (
int i=0; i<mSubTickVector->size(); ++i)
4387 t = coordToPixel(mSubTickVector->at(i));
4388 painter->drawLine(t+xCor, origin.y()-mSubTickLengthOut*tickDir+yCor, t+xCor, origin.y()+mSubTickLengthIn*tickDir+yCor);
4392 for (
int i=0; i<mSubTickVector->size(); ++i)
4394 t = coordToPixel(mSubTickVector->at(i));
4395 painter->drawLine(origin.x()-mSubTickLengthOut*tickDir+xCor, t+yCor, origin.x()+mSubTickLengthIn*tickDir+xCor, t+yCor);
4399 margin += qMax(0, qMax(mTickLengthOut, mSubTickLengthOut));
4402 QSize tickLabelsSize;
4405 margin += mTickLabelPadding;
4406 painter->setFont(mTickLabelFont);
4407 for (
int i=lowTick; i <= highTick; ++i)
4409 t = coordToPixel(mTickVector->at(i));
4410 drawTickLabel(painter, t, margin, mTickVectorLabels->at(i), &tickLabelsSize);
4413 if (orientation() == Qt::Horizontal)
4414 margin += tickLabelsSize.height();
4416 margin += tickLabelsSize.width();
4419 if (!mLabel.isEmpty())
4421 margin += mLabelPadding;
4422 painter->setFont(mLabelFont);
4424 bounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, mLabel);
4425 if (mAxisType == ATLeft)
4427 QTransform oldTransform = painter->transform();
4428 painter->translate((origin.x()-margin-bounds.height()), origin.y());
4429 painter->rotate(-90);
4430 painter->drawText(0, 0, mAxisRect.height(), bounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel);
4431 painter->setTransform(oldTransform);
4433 else if (mAxisType == ATRight)
4435 QTransform oldTransform = painter->transform();
4436 painter->translate((origin.x()+margin+bounds.height()), origin.y()-mAxisRect.height());
4437 painter->rotate(90);
4438 painter->drawText(0, 0, mAxisRect.height(), bounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel);
4439 painter->setTransform(oldTransform);
4441 else if (mAxisType == ATTop)
4442 painter->drawText(origin.x(), origin.y()-margin-bounds.height(), mAxisRect.width(), bounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel);
4443 else if (mAxisType == ATBottom)
4444 painter->drawText(origin.x(), origin.y()+margin, mAxisRect.width(), bounds.height(), Qt::TextDontClip | Qt::AlignCenter, mLabel);
4473 bool useBeautifulPowers =
false;
4475 if (mAutoTickLabels && mNumberBeautifulPowers && mTickLabelType == LTNumber)
4477 ePos = text.indexOf(
'e');
4479 useBeautifulPowers =
true;
4483 QRect bounds, baseBounds, expBounds;
4484 QString basePart, expPart;
4486 if (useBeautifulPowers)
4489 basePart = text.left(ePos);
4491 if (mScaleType == STLogarithmic && basePart ==
"1")
4494 basePart += (mNumberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) +
"10";
4495 expPart = text.mid(ePos+1);
4497 while (expPart.at(1) ==
'0' && expPart.length() > 2)
4498 expPart.remove(1, 1);
4499 if (expPart.at(0) == mPositiveSignChar)
4500 expPart.remove(0, 1);
4502 expFont = painter->font();
4503 expFont.setPointSize(expFont.pointSize()*0.75);
4505 baseBounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, basePart);
4506 QFontMetrics expFontMetrics(expFont);
4507 expBounds = expFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, expPart);
4508 bounds = baseBounds.adjusted(0, 0, expBounds.width(), 0);
4511 bounds = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, text);
4515 QRect rotatedBounds = bounds;
4516 if (!qFuzzyCompare(mTickLabelRotation+1.0, 1.0))
4518 QTransform transform;
4519 transform.rotate(mTickLabelRotation);
4520 rotatedBounds = transform.mapRect(bounds);
4523 if (rotatedBounds.width() > tickLabelsSize->width())
4524 tickLabelsSize->setWidth(rotatedBounds.width());
4525 if (rotatedBounds.height() > tickLabelsSize->height())
4526 tickLabelsSize->setHeight(rotatedBounds.height());
4534 bool doRotation = !qFuzzyCompare(mTickLabelRotation+1.0, 1.0);
4535 double angle = mTickLabelRotation/180.0*M_PI;
4537 if (mAxisType == ATLeft)
4541 if (mTickLabelRotation > 0)
4543 x = mAxisRect.left()-cos(angle)*bounds.width()-distanceToAxis;
4544 y = position-sin(angle)*bounds.width()-cos(angle)*bounds.height()/2.0;
4547 x = mAxisRect.left()-cos(-angle)*bounds.width()-sin(-angle)*bounds.height()-distanceToAxis;
4548 y = position+sin(-angle)*bounds.width()-cos(-angle)*bounds.height()/2.0;
4552 x = mAxisRect.left()-bounds.width()-distanceToAxis;
4553 y = position-bounds.height()/2.0;
4555 }
else if (mAxisType == ATRight)
4559 if (mTickLabelRotation > 0)
4561 x = mAxisRect.right()+sin(angle)*bounds.height()+distanceToAxis;
4562 y = position-cos(angle)*bounds.height()/2.0;
4565 x = mAxisRect.right()+distanceToAxis;
4566 y = position-cos(-angle)*bounds.height()/2.0;
4570 x = mAxisRect.right()+distanceToAxis;
4571 y = position-bounds.height()/2.0;
4573 }
else if (mAxisType == ATTop)
4577 if (mTickLabelRotation > 0)
4579 x = position-cos(angle)*bounds.width()+sin(angle)*bounds.height()/2.0;
4580 y = mAxisRect.top()-sin(angle)*bounds.width()-cos(angle)*bounds.height()-distanceToAxis;
4583 x = position-sin(-angle)*bounds.height()/2.0;
4584 y = mAxisRect.top()-cos(-angle)*bounds.height()-distanceToAxis;
4588 x = position-bounds.width()/2.0;
4589 y = mAxisRect.top()-bounds.height()-distanceToAxis;
4591 }
else if (mAxisType == ATBottom)
4595 if (mTickLabelRotation > 0)
4597 x = position+sin(angle)*bounds.height()/2.0;
4598 y = mAxisRect.bottom()+distanceToAxis;
4601 x = position-cos(-angle)*bounds.width()-sin(-angle)*bounds.height()/2.0;
4602 y = mAxisRect.bottom()+sin(-angle)*bounds.width()+distanceToAxis;
4606 x = position-bounds.width()/2.0;
4607 y = mAxisRect.bottom()+distanceToAxis;
4612 if (orientation() == Qt::Horizontal)
4625 QTransform oldTransform = painter->transform();
4626 painter->translate(x, y);
4628 painter->rotate(mTickLabelRotation);
4630 if (useBeautifulPowers)
4633 painter->drawText(0, 0, 0, 0, Qt::TextDontClip, basePart);
4635 painter->setFont(expFont);
4636 painter->drawText(baseBounds.width()+1, 0, expBounds.width(), expBounds.height(), Qt::TextDontClip, expPart);
4637 painter->setFont(mTickLabelFont);
4640 painter->drawText(0, 0, bounds.width(), bounds.height(), Qt::TextDontClip | Qt::AlignHCenter, text);
4644 painter->setTransform(oldTransform);
4661 bool useBeautifulPowers =
false;
4663 if (mAutoTickLabels && mNumberBeautifulPowers && mTickLabelType == LTNumber)
4665 ePos = text.indexOf(mExponentialChar);
4667 useBeautifulPowers =
true;
4671 QRect bounds, baseBounds, expBounds;
4672 QString basePart, expPart;
4674 if (useBeautifulPowers)
4677 basePart = text.left(ePos);
4679 if (mScaleType == STLogarithmic && basePart ==
"1")
4682 basePart += (mNumberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) +
"10";
4683 expPart = text.mid(ePos+1);
4685 while (expPart.at(1) ==
'0' && expPart.length() > 2)
4686 expPart.remove(1, 1);
4687 if (expPart.at(0) == mPositiveSignChar)
4688 expPart.remove(0, 1);
4691 expFont.setPointSize(expFont.pointSize()*0.75);
4693 QFontMetrics baseFontMetrics(font);
4694 baseBounds = baseFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, basePart);
4695 QFontMetrics expFontMetrics(expFont);
4696 expBounds = expFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, expPart);
4697 bounds = baseBounds.adjusted(0, 0, expBounds.width(), 0);
4700 QFontMetrics fontMetrics(font);
4701 bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, text);
4705 QRect rotatedBounds = bounds;
4706 if (!qFuzzyCompare(mTickLabelRotation+1.0, 1.0))
4708 QTransform transform;
4709 transform.rotate(mTickLabelRotation);
4710 rotatedBounds = transform.mapRect(bounds);
4713 if (rotatedBounds.width() > tickLabelsSize->width())
4714 tickLabelsSize->setWidth(rotatedBounds.width());
4715 if (rotatedBounds.height() > tickLabelsSize->height())
4716 tickLabelsSize->setHeight(rotatedBounds.height());
4733 for (
int i=0; i < mTickVector->size(); ++i)
4736 if (mTickVector->at(i) >= mRange.lower)
break;
4738 for (
int i=mTickVector->size()-1; i >= 0; --i)
4741 if (mTickVector->at(i) <= mRange.upper)
break;
4754 return log(value)*mScaleLogBaseLogInv;
4765 return pow(mScaleLogBase, value);
4788 int lowTick, highTick;
4789 visibleTickBounds(lowTick, highTick);
4792 margin += qMax(0, qMax(mTickLengthOut, mSubTickLengthOut));
4794 QSize tickLabelsSize(0, 0);
4797 for (
int i=lowTick; i <= highTick; ++i)
4799 getMaxTickLabelSize(mTickLabelFont, mTickVectorLabels->at(i), &tickLabelsSize);
4801 if (orientation() == Qt::Horizontal)
4802 margin += tickLabelsSize.height() + mTickLabelPadding;
4804 margin += tickLabelsSize.width() + mTickLabelPadding;
4808 if (!mLabel.isEmpty())
4810 QFontMetrics fontMetrics(mLabelFont);
4812 bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, mLabel);
4813 margin += bounds.height() + mLabelPadding;
4842 QCustomPlot::QCustomPlot(QWidget *parent) :
4845 setMouseTracking(
true);
4846 QLocale currentLocale = locale();
4847 currentLocale.setNumberOptions(QLocale::OmitGroupSeparator);
4848 setLocale(currentLocale);
4850 buffer = QPixmap(
size());
4854 titleFont.setPointSize(14);
4855 titleFont.setBold(
true);
4856 setTitleFont(titleFont);
4858 setColor(Qt::white);
4859 setAntialiasedElements(AEGraphs | AEScatters | AEFills);
4861 legend->setVisible(
false);
4862 setAutoAddPlottableToLegend(
true);
4867 xAxis2->setGrid(
false);
4868 yAxis2->setGrid(
false);
4869 xAxis2->setZeroLinePen(Qt::NoPen);
4870 yAxis2->setZeroLinePen(Qt::NoPen);
4871 xAxis2->setVisible(
false);
4872 yAxis2->setVisible(
false);
4873 setAxisBackground(QPixmap());
4874 setAxisBackgroundScaled(
true);
4875 setAxisBackgroundScaledMode(Qt::KeepAspectRatioByExpanding);
4877 setRangeDragAxes(xAxis, yAxis);
4878 setRangeZoomAxes(xAxis, yAxis);
4881 setRangeZoomFactor(0.85);
4884 setAutoMargin(
true);
4888 QCustomPlot::~QCustomPlot()
4904 return (orientation == Qt::Horizontal ? mRangeDragHorzAxis : mRangeDragVertAxis);
4913 return (orientation == Qt::Horizontal ? mRangeZoomHorzAxis : mRangeZoomVertAxis);
4922 return (orientation == Qt::Horizontal ? mRangeZoomFactorHorz : mRangeZoomFactorVert);
5028 mAutoMargin = enabled;
5050 mRangeDrag = orientations;
5064 mRangeZoom = orientations;
5074 mRangeDragHorzAxis = horizontal;
5076 mRangeDragVertAxis = vertical;
5087 mRangeZoomHorzAxis = horizontal;
5089 mRangeZoomVertAxis = vertical;
5102 mRangeZoomFactorHorz = horizontalFactor;
5103 mRangeZoomFactorVert = verticalFactor;
5115 mRangeZoomFactorHorz = factor;
5116 mRangeZoomFactorVert = factor;
5124 mAntialiasedElements = antialiasedElements;
5132 if (!enabled && mAntialiasedElements.testFlag(antialiasedElement))
5133 mAntialiasedElements &= ~antialiasedElement;
5134 else if (enabled && !mAntialiasedElements.testFlag(antialiasedElement))
5135 mAntialiasedElements |= antialiasedElement;
5146 mAutoAddPlottableToLegend = on;
5159 mAxisBackground = pm;
5160 mScaledAxisBackground = QPixmap();
5170 mAxisBackground = pm;
5171 mScaledAxisBackground = QPixmap();
5172 mAxisBackgroundScaled = scaled;
5173 mAxisBackgroundScaledMode = mode;
5189 mAxisBackgroundScaled = scaled;
5199 mAxisBackgroundScaledMode = mode;
5212 if (index >= 0 && index < mPlottables.size())
5214 return mPlottables.at(index);
5217 qDebug() <<
FUNCNAME <<
"index out of bounds:" << index;
5231 if (!mPlottables.isEmpty())
5233 return mPlottables.last();
5250 if (!mPlottables.contains(plottable) && plottable->
parentPlot() ==
this)
5252 mPlottables.append(plottable);
5254 if (mAutoAddPlottableToLegend)
5257 if (
QCPGraph *graph = dynamic_cast<QCPGraph*>(plottable))
5258 mGraphs.append(graph);
5262 qDebug() <<
FUNCNAME <<
"plottable either already in list or not created with this QCustomPlot as parent:" << plottable;
5276 if (mPlottables.contains(plottable))
5281 if (
QCPGraph *graph = dynamic_cast<QCPGraph*>(plottable))
5282 mGraphs.removeOne(graph);
5285 mPlottables.removeOne(plottable);
5289 qDebug() <<
FUNCNAME <<
"plottable not in list:" << plottable;
5300 if (index >= 0 && index < mPlottables.size())
5301 return removePlottable(mPlottables[index]);
5305 qDebug() <<
FUNCNAME <<
"index out of bounds:" << index;
5319 int c = mPlottables.size();
5320 for (
int i=c-1; i >= 0; --i)
5321 removePlottable(mPlottables[i]);
5332 return mPlottables.size();
5345 if (index >= 0 && index < mGraphs.size())
5347 return mGraphs.at(index);
5350 qDebug() <<
FUNCNAME <<
"index out of bounds:" << index;
5364 if (!mGraphs.isEmpty())
5366 return mGraphs.last();
5385 if (!keyAxis) keyAxis = xAxis;
5386 if (!valueAxis) valueAxis = yAxis;
5388 if (addPlottable(newGraph))
5390 newGraph->
setName(
"Graph "+QString::number(mGraphs.size()));
5410 return removePlottable(graph);
5419 if (index >= 0 && index < mGraphs.size())
5420 return removeGraph(mGraphs[index]);
5432 int c = mGraphs.size();
5433 for (
int i=c-1; i >= 0; --i)
5434 removeGraph(mGraphs[i]);
5445 return mGraphs.size();
5454 QPainter painter(&buffer);
5455 if (!painter.isActive())
5457 qDebug() <<
FUNCNAME <<
"Couldn't activate painter on buffer";
5460 painter.fillRect(rect(), mColor);
5487 xAxis2->setVisible(
true);
5488 yAxis2->setVisible(
true);
5490 xAxis2->setTickLabels(
false);
5491 yAxis2->setTickLabels(
false);
5493 xAxis2->setAutoSubTicks(xAxis->autoSubTicks());
5494 yAxis2->setAutoSubTicks(yAxis->autoSubTicks());
5496 xAxis2->setAutoTickCount(xAxis->autoTickCount());
5497 yAxis2->setAutoTickCount(yAxis->autoTickCount());
5499 xAxis2->setAutoTickStep(xAxis->autoTickStep());
5500 yAxis2->setAutoTickStep(yAxis->autoTickStep());
5502 xAxis2->setScaleType(xAxis->scaleType());
5503 yAxis2->setScaleType(yAxis->scaleType());
5505 xAxis2->setScaleLogBase(xAxis->scaleLogBase());
5506 yAxis2->setScaleLogBase(yAxis->scaleLogBase());
5508 xAxis2->setTicks(xAxis->ticks());
5509 yAxis2->setTicks(yAxis->ticks());
5511 xAxis2->setSubTickCount(xAxis->subTickCount());
5512 yAxis2->setSubTickCount(yAxis->subTickCount());
5514 xAxis2->setTickStep(xAxis->tickStep());
5515 yAxis2->setTickStep(yAxis->tickStep());
5517 xAxis2->setRange(xAxis->range());
5518 yAxis2->setRange(yAxis->range());
5520 xAxis2->setRangeReversed(xAxis->rangeReversed());
5521 yAxis2->setRangeReversed(yAxis->rangeReversed());
5532 if (mPlottables.isEmpty())
return;
5534 mPlottables.at(0)->rescaleAxes(
false);
5535 for (
int i=1; i<mPlottables.size(); ++i)
5536 mPlottables.at(i)->rescaleAxes(
true);
5566 int newWidth, newHeight;
5567 if (width == 0 || height == 0)
5569 newWidth = this->width();
5570 newHeight = this->height();
5577 QPrinter printer(QPrinter::ScreenResolution);
5578 printer.setOutputFileName(fileName);
5579 printer.setFullPage(
true);
5580 QRect oldViewport = mViewport;
5581 mViewport = QRect(0, 0, newWidth, newHeight);
5583 printer.setPaperSize(mViewport.size(), QPrinter::DevicePixel);
5584 QPainter printpainter(&printer);
5585 printpainter.setWindow(mViewport);
5586 printpainter.setRenderHint(QPainter::NonCosmeticDefaultPen, noCosmeticPen);
5587 draw(&printpainter);
5588 mViewport = oldViewport;
5627 int newWidth, newHeight;
5628 if (width == 0 || height == 0)
5630 newWidth = this->width();
5631 newHeight = this->height();
5638 QPixmap pngBuffer(newWidth, newHeight);
5639 QPainter painter(&pngBuffer);
5640 painter.fillRect(pngBuffer.rect(), mColor);
5641 QRect oldViewport = mViewport;
5642 mViewport = QRect(0, 0, newWidth, newHeight);
5645 mViewport = oldViewport;
5647 pngBuffer.save(fileName);
5674 int newWidth, newHeight;
5675 if (width == 0 || height == 0)
5677 newWidth = this->width();
5678 newHeight = this->height();
5685 int scaledWidth = scale*newWidth;
5686 int scaledHeight = scale*newHeight;
5688 QPixmap pngBuffer(scaledWidth, scaledHeight);
5689 QPainter painter(&pngBuffer);
5690 painter.setRenderHint(QPainter::NonCosmeticDefaultPen);
5691 painter.fillRect(pngBuffer.rect(), mColor);
5692 QRect oldViewport = mViewport;
5693 mViewport = QRect(0, 0, newWidth, newHeight);
5695 painter.scale(scale, scale);
5697 mViewport = oldViewport;
5699 pngBuffer.save(fileName);
5711 QPainter painter(
this);
5712 painter.drawPixmap(0, 0, buffer);
5725 buffer = QPixmap(event->size());
5737 emit mouseDoubleClick(event);
5752 if (event->buttons() & Qt::LeftButton)
5755 mDragStart =
event->pos();
5756 mDragStartHorzRange = mRangeDragHorzAxis->range();
5757 mDragStartVertRange = mRangeDragVertAxis->range();
5764 int itemIdx = legend->getItemIndex(&event->pos());
5768 emit mousePressOnLegendItem(event, QVariant(itemIdx));
5771 emit mousePressOnPlotArea(event);
5774 emit mousePress(event);
5786 emit mouseMove(event);
5789 if (mRangeDrag.testFlag(Qt::Horizontal))
5793 double diff = mRangeDragHorzAxis->pixelToCoord(mDragStart.x()) - mRangeDragHorzAxis->pixelToCoord(event->pos().x());
5794 mRangeDragHorzAxis->setRange(mDragStartHorzRange.lower+diff, mDragStartHorzRange.upper+diff);
5797 double diff = mRangeDragHorzAxis->pixelToCoord(mDragStart.x()) / mRangeDragHorzAxis->pixelToCoord(event->pos().x());
5798 mRangeDragHorzAxis->setRange(mDragStartHorzRange.lower*diff, mDragStartHorzRange.upper*diff);
5801 if (mRangeDrag.testFlag(Qt::Vertical))
5805 double diff = mRangeDragVertAxis->pixelToCoord(mDragStart.y()) - mRangeDragVertAxis->pixelToCoord(event->pos().y());
5806 mRangeDragVertAxis->setRange(mDragStartVertRange.lower+diff, mDragStartVertRange.upper+diff);
5809 double diff = mRangeDragVertAxis->pixelToCoord(mDragStart.y()) / mRangeDragVertAxis->pixelToCoord(event->pos().y());
5810 mRangeDragVertAxis->setRange(mDragStartVertRange.lower*diff, mDragStartVertRange.upper*diff);
5813 if (mRangeDrag != 0)
5829 emit mouseRelease(event);
5850 emit mouseWheel(event);
5851 if (mRangeZoom != 0)
5854 double wheelSteps =
event->delta()/120.0;
5855 if (mRangeZoom.testFlag(Qt::Horizontal))
5857 factor = pow(mRangeZoomFactorHorz, wheelSteps);
5858 mRangeZoomHorzAxis->scaleRange(factor, mRangeZoomHorzAxis->pixelToCoord(event->pos().x()));
5860 if (mRangeZoom.testFlag(Qt::Vertical))
5862 factor = pow(mRangeZoomFactorVert, wheelSteps);
5863 mRangeZoomVertAxis->scaleRange(factor, mRangeZoomVertAxis->pixelToCoord(event->pos().y()));
5880 if (!mTitle.isEmpty())
5882 painter->setFont(mTitleFont);
5883 titleBounds = painter->fontMetrics().boundingRect(0, 0, titleBounds.width(), titleBounds.height(), Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, mTitle);
5884 painter->drawText(mViewport.left(), mViewport.top(), mViewport.width(), titleBounds.height(), Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, mTitle);
5888 xAxis->generateTickVectors();
5889 yAxis->generateTickVectors();
5890 xAxis2->generateTickVectors();
5891 yAxis2->generateTickVectors();
5897 yAxis2->calculateMargin(),
5898 xAxis2->calculateMargin()+titleBounds.height(),
5899 xAxis->calculateMargin());
5903 drawAxisBackground(painter);
5906 xAxis->drawSubGrid(painter);
5907 yAxis->drawSubGrid(painter);
5908 xAxis2->drawSubGrid(painter);
5909 yAxis2->drawSubGrid(painter);
5910 xAxis->drawGrid(painter);
5911 yAxis->drawGrid(painter);
5912 xAxis2->drawGrid(painter);
5913 yAxis2->drawGrid(painter);
5916 for (
int i=0; i < mPlottables.size(); ++i)
5919 mPlottables.at(i)->draw(painter);
5924 xAxis->drawAxis(painter);
5925 yAxis->drawAxis(painter);
5926 xAxis2->drawAxis(painter);
5927 yAxis2->drawAxis(painter);
5930 legend->reArrange();
5931 legend->draw(painter);
5948 if (!mAxisBackground.isNull())
5950 if (mAxisBackgroundScaled)
5953 QSize scaledSize(mAxisBackground.size());
5954 scaledSize.scale(mAxisRect.size(), mAxisBackgroundScaledMode);
5955 if (mScaledAxisBackground.size() != scaledSize)
5956 mScaledAxisBackground = mAxisBackground.scaled(mAxisRect.size(), mAxisBackgroundScaledMode, Qt::SmoothTransformation);
5957 painter->drawPixmap(mAxisRect.topLeft(), mScaledAxisBackground, QRect(0, 0, mAxisRect.width(), mAxisRect.height()) & mScaledAxisBackground.rect());
5960 painter->drawPixmap(mAxisRect.topLeft(), mAxisBackground, QRect(0, 0, mAxisRect.width(), mAxisRect.height()));
5975 xAxis->setAxisRect(mAxisRect);
5976 yAxis->setAxisRect(mAxisRect);
5977 xAxis2->setAxisRect(mAxisRect);
5978 yAxis2->setAxisRect(mAxisRect);
6099 mValueAxis(valueAxis)
6102 qDebug() <<
FUNCNAME <<
"Parent plot of keyAxis is not the same as that of valueAxis.";
6104 qDebug() <<
FUNCNAME <<
"keyAxis and valueAxis must be orthogonal to each other.";
6369 mParentLegend(parent),
6370 mFont(parent->font())
6420 mPlottable(plottable)
6454 painter->setFont(
mFont);
6456 QRect iconRect(rect.topLeft(),
mIconSize);
6461 if (textRect.height() <
mIconSize.height())
6471 textRect = painter->fontMetrics().boundingRect(0, 0, 0, rect.height(), Qt::TextDontClip,
mPlottable->
name());
6472 if (textRect.height() <
mIconSize.height())
6482 painter->setClipRect(iconRect, Qt::IntersectClip);
6489 painter->setBrush(Qt::NoBrush);
6490 painter->drawRect(iconRect);
6510 QFontMetrics fontMetrics(
mFont);
6521 result.setHeight(qMax(textRect.height(),
mIconSize.height()));
6564 mPen.setColor(Qt::blue);
6565 mPen.setStyle(Qt::SolidLine);
6566 mBrush.setColor(Qt::blue);
6567 mBrush.setStyle(Qt::NoBrush);
6600 void QCPCurve::setData(
const QVector<double> &t,
const QVector<double> &key,
const QVector<double> &value)
6604 n = qMin(n, key.size());
6605 n = qMin(n, value.size());
6607 for (
int i=0; i<n; ++i)
6610 newData.key = key[i];
6611 newData.value = value[i];
6612 mData->insertMulti(newData.t, newData);
6625 n = qMin(n, value.size());
6627 for (
int i=0; i<n; ++i)
6630 newData.key = key[i];
6631 newData.value = value[i];
6632 mData->insertMulti(newData.t, newData);
6642 mData->unite(dataMap);
6651 mData->insertMulti(data.
t, data);
6663 newData.
value = value;
6664 mData->insertMulti(newData.
t, newData);
6678 if (!
mData->isEmpty())
6679 newData.
t = (
mData->constEnd()-1).key()+1;
6683 newData.
value = value;
6684 mData->insertMulti(newData.
t, newData);
6691 void QCPCurve::addData(
const QVector<double> &ts,
const QVector<double> &keys,
const QVector<double> &values)
6694 n = qMin(n, keys.size());
6695 n = qMin(n, values.size());
6697 for (
int i=0; i<n; ++i)
6700 newData.key = keys[i];
6701 newData.value = values[i];
6702 mData->insertMulti(newData.t, newData);
6712 QCPCurveDataMap::iterator it =
mData->begin();
6713 while (it !=
mData->end() && it.key() < t)
6714 it =
mData->erase(it);
6723 if (
mData->isEmpty())
return;
6724 QCPCurveDataMap::iterator it =
mData->upperBound(t);
6725 while (it !=
mData->end())
6726 it =
mData->erase(it);
6738 if (fromt >= tot ||
mData->isEmpty())
return;
6739 QCPCurveDataMap::iterator it =
mData->upperBound(fromt);
6740 QCPCurveDataMap::iterator itEnd =
mData->upperBound(tot);
6742 it =
mData->erase(it);
6772 if (
mData->isEmpty())
return;
6776 QVector<QPointF> *lineData =
new QVector<QPointF>;
6780 if (
mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0)
6783 painter->setPen(Qt::NoPen);
6784 painter->setBrush(
mBrush);
6785 painter->drawPolygon(QPolygonF(*lineData));
6788 if (
mPen.style() != Qt::NoPen &&
mPen.color().alpha() != 0)
6791 painter->setPen(
mPen);
6792 painter->setBrush(Qt::NoBrush);
6793 painter->drawPolyline(QPolygonF(*lineData));
6803 if (
mBrush.style() != Qt::NoBrush)
6806 painter->fillRect(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0,
mBrush);
6810 painter->setPen(
mPen);
6811 painter->drawLine(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0);
6828 lineData->reserve(
mData->size());
6829 QCPCurveDataMap::const_iterator it;
6831 int currentRegion = 5;
6837 bool addedLastAlready =
true;
6838 bool firstPoint =
true;
6839 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
6842 y = it.value().value;
6848 else if (y < RBottom)
6852 }
else if (x > RRight)
6856 else if (y < RBottom)
6864 else if (y < RBottom)
6877 if (currentRegion == 5 || (firstPoint &&
mBrush.style() != Qt::NoBrush))
6879 if (!addedLastAlready)
6880 lineData->append(
coordsToPixels((it-1).value().key, (it-1).value().value));
6881 else if (lastRegion != 5)
6884 lineData->replace(lineData->size()-1,
coordsToPixels((it-1).value().key, (it-1).value().value));
6886 lineData->append(
coordsToPixels(it.value().key, it.value().value));
6887 addedLastAlready =
true;
6888 }
else if (currentRegion != lastRegion)
6893 if (lastRegion == 5 ||
6894 ((lastRegion==2 && currentRegion==4) || (lastRegion==4 && currentRegion==2)) ||
6895 ((lastRegion==4 && currentRegion==8) || (lastRegion==8 && currentRegion==4)) ||
6896 ((lastRegion==8 && currentRegion==6) || (lastRegion==6 && currentRegion==8)) ||
6897 ((lastRegion==6 && currentRegion==2) || (lastRegion==2 && currentRegion==6))
6901 if (!addedLastAlready)
6902 lineData->append(
coordsToPixels((it-1).value().key, (it-1).value().value));
6904 lineData->append(
coordsToPixels(it.value().key, it.value().value));
6908 if (!addedLastAlready)
6913 addedLastAlready =
true;
6916 addedLastAlready =
false;
6918 lastRegion = currentRegion;
6922 if (lastRegion != 5 &&
mBrush.style() != Qt::NoBrush && !
mData->isEmpty())
6943 case 2: result.setX(axisRect.left()-margin);
break;
6944 case 8: result.setX(axisRect.right()+margin);
break;
6945 case 4: result.setY(axisRect.top()-margin);
break;
6946 case 6: result.setY(axisRect.bottom()+margin);
break;
6947 case 1: result.setX(axisRect.left()-margin);
6948 result.setY(axisRect.top()-margin);
break;
6949 case 7: result.setX(axisRect.right()+margin);
6950 result.setY(axisRect.top()-margin);
break;
6951 case 9: result.setX(axisRect.right()+margin);
6952 result.setY(axisRect.bottom()+margin);
break;
6953 case 3: result.setX(axisRect.left()-margin);
6954 result.setY(axisRect.bottom()+margin);
break;
6963 bool haveLower =
false;
6964 bool haveUpper =
false;
6968 QCPCurveDataMap::const_iterator it =
mData->constBegin();
6969 while (it !=
mData->constEnd())
6971 current = it.value().key;
6974 if (current < range.
lower || !haveLower)
6976 range.
lower = current;
6979 if (current > range.
upper || !haveUpper)
6981 range.
upper = current;
6988 validRange = haveLower && haveUpper;
6996 bool haveLower =
false;
6997 bool haveUpper =
false;
7001 QCPCurveDataMap::const_iterator it =
mData->constBegin();
7002 while (it !=
mData->constEnd())
7004 current = it.value().value;
7007 if (current < range.
lower || !haveLower)
7009 range.
lower = current;
7012 if (current > range.
upper || !haveUpper)
7014 range.
upper = current;
7021 validRange = haveLower && haveUpper;
7087 mPen.setColor(Qt::blue);
7088 mPen.setStyle(Qt::SolidLine);
7089 mBrush.setColor(QColor(40, 50, 255, 30));
7090 mBrush.setStyle(Qt::SolidPattern);
7138 n = qMin(n, value.size());
7140 for (
int i=0; i<n; ++i)
7142 newData.
key = key[i];
7143 newData.value = value[i];
7144 mData->insertMulti(newData.key, newData);
7164 if (bars ==
this)
return;
7167 qDebug() <<
FUNCNAME <<
"passed QCPBars* doesn't have same key and value axis as this QCPBars";
7197 if (bars ==
this)
return;
7200 qDebug() <<
FUNCNAME <<
"passed QCPBars* doesn't have same key and value axis as this QCPBars";
7220 mData->unite(dataMap);
7229 mData->insertMulti(data.
key, data);
7240 newData.
value = value;
7241 mData->insertMulti(newData.
key, newData);
7250 int n = keys.size();
7251 n = qMin(n, values.size());
7253 for (
int i=0; i<n; ++i)
7255 newData.
key = keys[i];
7256 newData.value = values[i];
7257 mData->insertMulti(newData.key, newData);
7267 QCPBarDataMap::iterator it =
mData->begin();
7268 while (it !=
mData->end() && it.key() < key)
7269 it =
mData->erase(it);
7278 if (
mData->isEmpty())
return;
7279 QCPBarDataMap::iterator it =
mData->upperBound(key);
7280 while (it !=
mData->end())
7281 it =
mData->erase(it);
7293 if (fromKey >= toKey ||
mData->isEmpty())
return;
7294 QCPBarDataMap::iterator it =
mData->upperBound(fromKey);
7295 QCPBarDataMap::iterator itEnd =
mData->upperBound(toKey);
7297 it =
mData->erase(it);
7328 QCPBarDataMap::const_iterator it;
7329 for (it =
mData->constBegin(); it !=
mData->constEnd(); ++it)
7333 QPolygonF barPolygon =
getBarPolygon(it.key(), it.value().value);
7335 if (
mBrush.style() != Qt::NoBrush &&
mBrush.color().alpha() != 0)
7338 painter->setPen(Qt::NoPen);
7339 painter->setBrush(
mBrush);
7340 painter->drawPolygon(barPolygon);
7343 if (
mPen.style() != Qt::NoPen &&
mPen.color().alpha() != 0)
7346 painter->setPen(
mPen);
7347 painter->setBrush(Qt::NoBrush);
7348 painter->drawPolyline(barPolygon);
7357 painter->setBrush(
mBrush);
7358 painter->setPen(
mPen);
7360 QRect r = QRect(0, 0, rect.width()*0.67, rect.height()*0.67);
7361 r.moveCenter(rect.center());
7362 painter->drawRect(r);
7400 if ((positive && it.value().value > max) ||
7401 (!positive && it.value().value < max))
7402 max = it.value().value;
7421 if (!lower && !upper)
return;
7452 bool haveLower =
false;
7453 bool haveUpper =
false;
7456 double barWidthHalf =
mWidth*0.5;
7457 QCPBarDataMap::const_iterator it =
mData->constBegin();
7458 while (it !=
mData->constEnd())
7460 current = it.value().key;
7461 if (inSignDomain ==
SDBoth || (inSignDomain ==
SDNegative && current+barWidthHalf < 0) || (inSignDomain ==
SDPositive && current-barWidthHalf > 0))
7463 if (current-barWidthHalf < range.
lower || !haveLower)
7465 range.
lower = current-barWidthHalf;
7468 if (current+barWidthHalf > range.
upper || !haveUpper)
7470 range.
upper = current+barWidthHalf;
7477 validRange = haveLower && haveUpper;
7485 bool haveLower =
true;
7486 bool haveUpper =
true;
7490 QCPBarDataMap::const_iterator it =
mData->constBegin();
7491 while (it !=
mData->constEnd())
7493 current = it.value().value +
getBaseValue(it.value().key, it.value().value >= 0);
7496 if (current < range.
lower || !haveLower)
7498 range.
lower = current;
7501 if (current > range.
upper || !haveUpper)
7503 range.
upper = current;
7510 validRange = !qFuzzyCompare(range.
lower+1.0, range.
upper+1.0);
7587 whiskerPen.setStyle(Qt::DashLine);
7588 whiskerPen.setCapStyle(Qt::FlatCap);
7593 medianPen.setWidthF(3);
7594 medianPen.setCapStyle(Qt::FlatCap);
7601 outlierPen.setColor(Qt::blue);
7819 painter->setPen(
mPen);
7820 painter->setBrush(
mBrush);
7821 QRect r = QRect(0, 0, rect.width()*0.67, rect.height()*0.67);
7822 r.moveCenter(rect.center());
7823 painter->drawRect(r);
7835 painter->setPen(
mPen);
7836 painter->setBrush(
mBrush);
7837 painter->drawRect(box);
7850 painter->drawLine(medianLine);
7859 QLineF backboneMin, backboneMax, barMin, barMax;
7865 painter->drawLine(backboneMin);
7866 painter->drawLine(backboneMax);
7868 painter->drawLine(barMin);
7869 painter->drawLine(barMax);
7888 if (inSignDomain ==
SDBoth)
7921 if (inSignDomain ==
SDBoth)
7932 validRange = upper > lower;
7936 QVector<double> values;
7941 bool haveUpper =
false;
7942 bool haveLower =
false;
7945 for (
int i=0; i<values.size(); ++i)
7947 if ((inSignDomain ==
SDNegative && values.at(i) < 0) ||
7948 (inSignDomain ==
SDPositive && values.at(i) > 0))
7950 if (values.at(i) > upper || !haveUpper)
7952 upper = values.at(i);
7955 if (values.at(i) < lower || !haveLower)
7957 lower = values.at(i);
7963 if (haveLower && haveUpper && !qFuzzyCompare(upper+1.0, lower+1.0))
a square which is not filled, with a plus inside
void setOutliers(const QVector< double > &values)
Error bars for the key dimension of the data point are shown.
QCPGraph * addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0)
virtual void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const
QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setWhiskerBarPen(const QPen &pen)
Legend is positioned in the bottom right corner of the axis rect with distance to the border correspo...
virtual void draw(QPainter *painter) const
static const double maxRange
Axis is vertical and on the right side of the axis rect of the parent QCustomPlot.
void setLineStyle(int ls)
double pixelToCoord(double value) const
line is drawn as steps where the step height is the value of the right data point ...
void setDateTimeFormat(const QString &format)
virtual void drawLegendIcon(QPainter *painter, const QRect &rect) const
QCPGraph * graph(int index) const
void setAutoTickLabels(bool on)
QPointF upperFillBasePoint(double upperKey) const
Legend is horizontally centered at the top of the axis rect with distance to the border corresponding...
void setRangeZoomFactor(double horizontalFactor, double verticalFactor)
void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0)
QMap< double, QCPData > QCPDataMap
line is drawn as steps where the step is in between two data points
QCPAxis(QCustomPlot *parentPlot, AxisType type)
virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
QCPPlottableLegendItem * itemWithPlottable(const QCPAbstractPlottable *plottable) const
virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
A class holding the data of one single data point for QCPCurve.
virtual void draw(QPainter *painter) const
void setAutoMargin(bool enabled)
A legend item representing a plottable with an icon and the plottable name.
QCPGraph * mChannelFillGraph
void setIconTextPadding(int padding)
virtual bool removeFromLegend() const
a square which is not filled, with a cross inside
void setMedianPen(const QPen &pen)
virtual void mouseMoveEvent(QMouseEvent *event)
a circle which is filled with the color of the graph's pen (not the brush!)
virtual void drawQuartileBox(QPainter *painter) const
void setBasePen(const QPen &pen)
void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical)
The abstract base class for all items in a QCPLegend.
double upperQuartile() const
void setPositionStyle(PositionStyle legendPositionStyle)
void setMarginBottom(int margin)
void setName(const QString &name)
void setPaddingRight(int padding)
void setRangeReversed(bool reversed)
void setAxisRect(const QRect &arect)
void setWhiskerWidth(double width)
virtual void wheelEvent(QWheelEvent *event)
void removeDataBefore(double key)
virtual void generateTickVectors()
void getStepRightPlotData(QVector< QPointF > *lineData, QVector< QCPData > *pointData) const
void setTickLabels(bool show)
void getPlotData(QVector< QPointF > *lineData, QVector< QCPData > *pointData) const
void setBrush(const QBrush &brush)
void setRange(double lower, double upper)
void setLowerQuartile(double value)
const QCPDataMap * data() const
void setRangeDrag(Qt::Orientations orientations)
int findIndexBelowY(const QVector< QPointF > *data, double y) const
void getLinePlotData(QVector< QPointF > *lineData, QVector< QCPData > *pointData) const
void setWhiskerPen(const QPen &pen)
void setAutoTickStep(bool on)
void setSubTickCount(int count)
void setAutoTicks(bool on)
int findIndexAboveX(const QVector< QPointF > *data, double x) const
void setMarginLeft(int margin)
void setPosition(const QPoint &pixelPosition)
static bool validRange(double lower, double upper)
void setAutoSubTicks(bool on)
void setValueAxis(QCPAxis *axis)
void setPadding(int padding)
A plottable representing a bar chart in a plot.
bool removeGraph(QCPGraph *graph)
QCustomPlot * mParentPlot
void setAxisRect(const QRect &rect)
void setWidth(double width)
void moveAbove(QCPBars *bars)
virtual void mousePressEvent(QMouseEvent *event)
void moveBelow(QCPBars *bars)
void rescaleAxes(bool onlyEnlarge=false) const
void setScaleLogBase(double base)
void removeFillBasePoints(QVector< QPointF > *lineData) const
void setRangeUpper(double upper)
int getItemIndex(const QPoint *point)
void setMarginBottom(int margin)
virtual void draw(QPainter *painter)
void setTickLabelRotation(double degrees)
QCustomPlot * parentPlot() const
QPen iconBorderPen() const
virtual ~QCPStatisticalBox()
QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis)
void setRangeZoom(Qt::Orientations orientations)
void setZeroLinePen(const QPen &pen)
void setSize(const QSize &size)
void setFont(const QFont &font)
Legend is positioned in the top left corner of the axis rect with distance to the border correspondin...
void setWidth(double width)
virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const
void setGridPen(const QPen &pen)
void rescaleKeyAxis(bool onlyEnlarge=false) const
void removeDataBefore(double key)
const QPolygonF getChannelFillPolygon(const QVector< QPointF > *lineData) const
The abstract base class for all data representing objects in a plot.
QCPRange sanitizedForLogScale() const
void savePngScaled(const QString &fileName, double scale, int width=0, int height=0)
Both sign domains, including zero, i.e. all (rational) numbers.
an equilateral triangle which is not filled, standing on corner
void setAutoTickCount(int approximateCount)
QCustomPlot * parentPlot() const
void removeData(double fromt, double tot)
virtual void drawLegendIcon(QPainter *painter, const QRect &rect) const
void removeDataAfter(double t)
void setErrorBarSize(double size)
void setTickLabelFont(const QFont &font)
virtual int calculateMargin() const
void setMarginRight(int margin)
PositionStyle mPositionStyle
virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
A plottable representing a graph in a plot.
AxisType axisType() const
QCPAbstractLegendItem(QCPLegend *parent)
QCPAbstractLegendItem * item(int index) const
double basePow(double value) const
void setRangeLower(double lower)
QCPAxis * keyAxis() const
QCPRange sanitizedForLinScale() const
The central class which is also the QWidget which displays the plot and interacts with the user...
void setMedian(double value)
void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper, int &count) const
void setMinimum(double value)
Manages a single axis inside a QCustomPlot.
void setTickPen(const QPen &pen)
void setMaximum(double value)
Legend is positioned in the top right corner of the axis rect with distance to the border correspondi...
Manages a legend inside a QCustomPlot.
void getCurveData(QVector< QPointF > *lineData) const
void addFillBasePoints(QVector< QPointF > *lineData) const
a circle which is not filled, with one vertical and two downward diagonal lines
ErrorType errorType() const
bool addPlottable(QCPAbstractPlottable *plottable)
double lowerQuartile() const
QCPAbstractPlottable * plottable()
void removeData(double fromKey, double toKey)
void setAxisType(AxisType type)
virtual void calculateAutoPosition()
void addData(const QCPCurveDataMap &dataMap)
bool rangeReversed() const
void setKeyAxis(QCPAxis *axis)
void savePng(const QString &fileName, int width=0, int height=0)
a circle which is not filled
ScatterStyle mScatterStyle
void setFont(const QFont &font)
Legend is horizontally centered at the bottom of the axis rect with distance to the border correspond...
QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis)
an equilateral triangle which is not filled, standing on baseline
void setDataBothError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError, const QVector< double > &valueError)
void setPen(const QPen &pen)
void setUpperQuartile(double value)
virtual void drawLegendIcon(QPainter *painter, const QRect &rect) const
int plottableCount() const
void setOutlierBrush(const QBrush &brush)
QMap< double, QCPBarData > QCPBarDataMap
void removeData(double fromKey, double toKey)
a square which is not filled
void getImpulsePlotData(QVector< QPointF > *lineData, QVector< QCPData > *pointData) const
Axis is horizontal and on the bottom side of the axis rect of the parent QCustomPlot.
virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=SDBoth) const =0
Legend is vertically centered at the left of the axis rect with distance to the border corresponding ...
A class holding the data of one single data point for QCPGraph.
QCPPlottableLegendItem(QCPLegend *parent, const QCPAbstractPlottable *plottable)
virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=SDBoth) const =0
void setSubGridPen(const QPen &pen)
QCPAxis * rangeDragAxis(Qt::Orientation orientation)
virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
void setTickLength(int inside, int outside=0)
line is drawn as steps where the step height is the value of the left data point
Legend is vertically centered at the right of the axis rect with distance to the border corresponding...
int findIndexAboveY(const QVector< QPointF > *data, double y) const
void setScatterSize(double size)
void setErrorBarSkipSymbol(bool enabled)
Qt::Orientation orientation() const
QPointF lowerFillBasePoint(double lowerKey) const
void setTextWrap(bool wrap)
double getBaseValue(double key, bool positive) const
virtual int calculateAutoSubTickCount(double tickStep) const
void setTitleFont(const QFont &font)
Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power...
virtual void drawMedian(QPainter *painter) const
data points are represented by a straight line parallel to the value axis, which ranges down/up to th...
void setScatterPixmap(const QPixmap &pixmap)
void setIconBorderPen(const QPen &pen)
virtual void drawSubGrid(QPainter *painter)
void setAutoSize(bool on)
void setScaleType(ScaleType type)
void setNumberPrecision(int precision)
static const double minRange
void removeDataBefore(double t)
virtual void drawLegendIcon(QPainter *painter, const QRect &rect) const =0
QVector< double > mOutliers
void setTickVectorLabels(QVector< QString > *vec, bool copy=false)
void drawScatterPlot(QPainter *painter, QVector< QCPData > *pointData) const
void setData(QCPBarDataMap *data, bool copy=false)
static void connectBars(QCPBars *lower, QCPBars *upper)
virtual void draw(QPainter *painter) const
const AntialiasedElements antialiasedElements() const
const QCPCurveDataMap * data() const
void setPaddingBottom(int padding)
virtual void draw(QPainter *painter, const QRect &rect) const
void drawError(QPainter *painter, double x, double y, const QCPData &data) const
The negative sign domain, i.e. numbers smaller than zero.
void scaleRange(double factor, double center)
void setData(QCPCurveDataMap *data, bool copy=false)
double coordToPixel(double value) const
QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis)
void visibleTickBounds(int &lowIndex, int &highIndex) const
int iconTextPadding() const
virtual void drawLegendIcon(QPainter *painter, const QRect &rect) const
void setDataKeyError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &keyError)
void setPaddingTop(int padding)
Axis is horizontal and on the top side of the axis rect of the parent QCustomPlot.
Error bars for both key and value dimensions of the data point are shown.
void addData(const QCPBarDataMap &dataMap)
void setColor(const QColor &color)
void setTickStep(double step)
void setTickLabelType(LabelType type)
ScaleType scaleType() const
QString numberFormat() const
void removeDataAfter(double key)
Error bars for the value dimension of the data point are shown.
void moveRange(double diff)
void setLabelFont(const QFont &font)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
virtual bool addToLegend() const
virtual void drawWhiskers(QPainter *painter) const
void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum)
void setSubTickPen(const QPen &pen)
void setTickVector(QVector< double > *vec, bool copy=false)
void setNumberFormat(const QString &formatCode)
void setMargin(int left, int right, int top, int bottom)
void setItemSpacing(int spacing)
void setMarginTop(int margin)
double rangeZoomFactor(Qt::Orientation orientation)
void setMarginTop(int margin)
QCustomPlot * mParentPlot
virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
QCPAxis * valueAxis() const
void setErrorType(ErrorType errorType)
a circle which is not filled, with a plus inside
void rescaleValueAxis(bool onlyEnlarge=false) const
bool addItem(QCPAbstractLegendItem *item)
virtual void draw(QPainter *painter) const
void setVisible(bool visible)
void drawImpulsePlot(QPainter *painter, QVector< QPointF > *lineData) const
void getScatterPlotData(QVector< QCPData > *pointData) const
void setDataValueError(const QVector< double > &key, const QVector< double > &value, const QVector< double > &valueError)
void setTickLabelPadding(int padding)
virtual void resizeEvent(QResizeEvent *event)
void setBrush(const QBrush &brush)
virtual void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const
void setOutlierPen(const QPen &pen)
void setTitle(const QString &title)
virtual void drawGrid(QPainter *painter)
void drawLinePlot(QPainter *painter, QVector< QPointF > *lineData) const
QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis)
bool hasItem(QCPAbstractLegendItem *item) const
void setAutoAddPlottableToLegend(bool on)
void setAntialiasedElements(const AntialiasedElements &antialiasedElements)
double baseLog(double value) const
void setAntialiasedElement(AntialiasedElement antialiasedElement, bool enabled)
void setAxisBackgroundScaledMode(Qt::AspectRatioMode mode)
void removeDataAfter(double key)
void setMargin(int left, int right, int top, int bottom)
void setPadding(int left, int right, int top, int bottom)
The positive sign domain, i.e. numbers greater than zero.
void setBorderPen(const QPen &pen)
virtual void drawOutliers(QPainter *painter) const
void savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0)
void setIconSize(const QSize &size)
virtual void mouseReleaseEvent(QMouseEvent *event)
void setData(QCPDataMap *data, bool copy=false)
QPolygonF getBarPolygon(double key, double value) const
bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const
void drawFill(QPainter *painter, QVector< QPointF > *lineData) const
virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
void setPaddingLeft(int padding)
virtual void drawAxisBackground(QPainter *painter)
void drawScatter(QPainter *painter, double x, double y, ScatterStyle style) const
void setAxisBackground(const QPixmap &pm)
void setAxisBackgroundScaled(bool scaled)
void setErrorPen(const QPen &pen)
void setSubTickLength(int inside, int outside=0)
void setMinimumSize(const QSize &size)
Represents the range an axis is encompassing.
virtual void calculateAutoSize()
QPointF outsideCoordsToPixels(double key, double value, int region) const
virtual void drawAxis(QPainter *painter)
const QCPAbstractPlottable * mPlottable
void coordsToPixels(double key, double value, double &x, double &y) const
no scatter symbols are drawn (e.g. data only represented with lines, see setLineStyle) ...
virtual QCPRange getKeyRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
virtual void generateAutoTicks()
bool removePlottable(QCPAbstractPlottable *plottable)
void setOutlierSize(double pixels)
bool removeItem(int index)
friend class QCPPlottableLegendItem
void addData(const QCPDataMap &dataMap)
virtual void draw(QPainter *painter)
a star with eight arms, i.e. a combination of cross and plus
virtual void paintEvent(QPaintEvent *event)
const QCPRange range() const
QList< QCPAbstractLegendItem * > mItems
virtual QCPRange getValueRange(bool &validRange, SignDomain inSignDomain=SDBoth) const
void setLabel(const QString &str)
QMap< double, QCPCurveData > QCPCurveDataMap
void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical)
int findIndexBelowX(const QVector< QPointF > *data, double x) const
void setMarginLeft(int margin)
data points are connected by a straight line
void setMarginRight(int margin)
virtual void drawTickLabel(QPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize)
Axis is vertical and on the left side of the axis rect of the parent QCustomPlot. ...
QCPLegend(QCustomPlot *parentPlot)
void getStepLeftPlotData(QVector< QPointF > *lineData, QVector< QCPData > *pointData) const
const QCPBarDataMap * data() const
QCPGraph * channelFillGraph() const
a single pixel, setScatterSize has no influence on its size.
a circle which is not filled, with a cross inside
void setChannelFillGraph(QCPGraph *targetGraph)
void setSubGrid(bool show)
void setScatterStyle(int ss)
QCPAxis * rangeZoomAxis(Qt::Orientation orientation)
Legend is positioned in the bottom left corner of the axis rect with distance to the border correspon...
virtual QSize size(const QSize &targetSize) const
virtual void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const
void getStepCenterPlotData(QVector< QPointF > *lineData, QVector< QCPData > *pointData) const
a custom pixmap specified by setScatterPixmap, centered on the data point coordinates. setScatterSize has no influence on its size.
A class holding the data of one single data point (one bar) for QCPBars.
void setLabelPadding(int padding)