@@ -42,6 +42,9 | |||||
42 |
|
42 | |||
43 | #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) |
|
43 | #if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) | |
44 | #define QCP_DEVICEPIXELRATIO_SUPPORTED |
|
44 | #define QCP_DEVICEPIXELRATIO_SUPPORTED | |
|
45 | #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) | |||
|
46 | #define QCP_DEVICEPIXELRATIO_FLOAT | |||
|
47 | #endif | |||
45 | #endif |
|
48 | #endif | |
46 |
|
49 | |||
47 | #include <QtCore/QCache> |
|
50 | #include <QtCore/QCache> | |
@@ -109,8 +112,8 class QCPColorMap; | |||||
109 | class QCPColorScale; |
|
112 | class QCPColorScale; | |
110 | class QCPBars; |
|
113 | class QCPBars; | |
111 |
|
114 | |||
112 |
/* including file 'src/global.h', size 16 |
|
115 | /* including file 'src/global.h', size 16225 */ | |
113 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
116 | /* commit e7c6a5540d344a96d107dce53f9d4414a09a7320 2017-07-25 00:52:29 +0200 */ | |
114 |
|
117 | |||
115 | // decl definitions for shared library compilation/usage: |
|
118 | // decl definitions for shared library compilation/usage: | |
116 | #if defined(QCUSTOMPLOT_COMPILE_LIBRARY) |
|
119 | #if defined(QCUSTOMPLOT_COMPILE_LIBRARY) | |
@@ -1794,8 +1797,8 protected: | |||||
1794 | /* end of 'src/axis/axistickerdatetime.h' */ |
|
1797 | /* end of 'src/axis/axistickerdatetime.h' */ | |
1795 |
|
1798 | |||
1796 |
|
1799 | |||
1797 |
/* including file 'src/axis/axistickertime.h', size 32 |
|
1800 | /* including file 'src/axis/axistickertime.h', size 3542 */ | |
1798 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
1801 | /* commit c38adb94d83c6a752597a5d43d45c0561fbe1d4d 2017-08-13 17:37:53 +0200 */ | |
1799 |
|
1802 | |||
1800 | class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker { |
|
1803 | class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker { | |
1801 | Q_GADGET |
|
1804 | Q_GADGET | |
@@ -1805,7 +1808,17 public: | |||||
1805 |
|
1808 | |||
1806 | \see setFieldWidth, setTimeFormat |
|
1809 | \see setFieldWidth, setTimeFormat | |
1807 | */ |
|
1810 | */ | |
1808 | enum TimeUnit { tuMilliseconds, tuSeconds, tuMinutes, tuHours, tuDays }; |
|
1811 | enum TimeUnit { | |
|
1812 | tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) | |||
|
1813 | , | |||
|
1814 | tuSeconds ///< Seconds (%%s in \ref setTimeFormat) | |||
|
1815 | , | |||
|
1816 | tuMinutes ///< Minutes (%%m in \ref setTimeFormat) | |||
|
1817 | , | |||
|
1818 | tuHours ///< Hours (%%h in \ref setTimeFormat) | |||
|
1819 | , | |||
|
1820 | tuDays ///< Days (%%d in \ref setTimeFormat) | |||
|
1821 | }; | |||
1809 | Q_ENUMS(TimeUnit) |
|
1822 | Q_ENUMS(TimeUnit) | |
1810 |
|
1823 | |||
1811 | QCPAxisTickerTime(); |
|
1824 | QCPAxisTickerTime(); | |
@@ -2026,8 +2039,8 protected: | |||||
2026 | /* end of 'src/axis/axistickerlog.h' */ |
|
2039 | /* end of 'src/axis/axistickerlog.h' */ | |
2027 |
|
2040 | |||
2028 |
|
2041 | |||
2029 |
/* including file 'src/axis/axis.h', size 20 |
|
2042 | /* including file 'src/axis/axis.h', size 20634 */ | |
2030 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
2043 | /* commit 0cc4d9f61f7bf45321a88fec89d909b020ffa26f 2017-08-14 00:43:29 +0200 */ | |
2031 |
|
2044 | |||
2032 | class QCP_LIB_DECL QCPGrid : public QCPLayerable { |
|
2045 | class QCP_LIB_DECL QCPGrid : public QCPLayerable { | |
2033 | Q_OBJECT |
|
2046 | Q_OBJECT | |
@@ -2364,6 +2377,9 protected: | |||||
2364 | QVector<double> mSubTickVector; |
|
2377 | QVector<double> mSubTickVector; | |
2365 | bool mCachedMarginValid; |
|
2378 | bool mCachedMarginValid; | |
2366 | int mCachedMargin; |
|
2379 | int mCachedMargin; | |
|
2380 | bool mDragging; | |||
|
2381 | QCPRange mDragStartRange; | |||
|
2382 | QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; | |||
2367 |
|
2383 | |||
2368 | // introduced virtual methods: |
|
2384 | // introduced virtual methods: | |
2369 | virtual int calculateMargin(); |
|
2385 | virtual int calculateMargin(); | |
@@ -2376,6 +2392,11 protected: | |||||
2376 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, |
|
2392 | virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | |
2377 | bool *selectionStateChanged) Q_DECL_OVERRIDE; |
|
2393 | bool *selectionStateChanged) Q_DECL_OVERRIDE; | |
2378 | virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; |
|
2394 | virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; | |
|
2395 | // mouse events: | |||
|
2396 | virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); | |||
|
2397 | virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); | |||
|
2398 | virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); | |||
|
2399 | virtual void wheelEvent(QWheelEvent *event); | |||
2379 |
|
2400 | |||
2380 | // non-virtual methods: |
|
2401 | // non-virtual methods: | |
2381 | void setupTickVectors(); |
|
2402 | void setupTickVectors(); | |
@@ -2612,8 +2633,8 Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) | |||||
2612 | /* end of 'src/scatterstyle.h' */ |
|
2633 | /* end of 'src/scatterstyle.h' */ | |
2613 |
|
2634 | |||
2614 |
|
2635 | |||
2615 |
/* including file 'src/datacontainer.h', size 45 |
|
2636 | /* including file 'src/datacontainer.h', size 4596 */ | |
2616 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
2637 | /* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */ | |
2617 |
|
2638 | |||
2618 | /*! \relates QCPDataContainer |
|
2639 | /*! \relates QCPDataContainer | |
2619 | Returns whether the sort key of \a a is less than the sort key of \a b. |
|
2640 | Returns whether the sort key of \a a is less than the sort key of \a b. | |
@@ -2627,7 +2648,8 inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) | |||||
2627 | } |
|
2648 | } | |
2628 |
|
2649 | |||
2629 | template <class DataType> |
|
2650 | template <class DataType> | |
2630 | class QCP_LIB_DECL QCPDataContainer { |
|
2651 | class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) | |
|
2652 | { | |||
2631 | public: |
|
2653 | public: | |
2632 | typedef typename QVector<DataType>::const_iterator const_iterator; |
|
2654 | typedef typename QVector<DataType>::const_iterator const_iterator; | |
2633 | typedef typename QVector<DataType>::iterator iterator; |
|
2655 | typedef typename QVector<DataType>::iterator iterator; | |
@@ -2686,8 +2708,8 protected: | |||||
2686 |
|
2708 | |||
2687 | // include implementation in header since it is a class template: |
|
2709 | // include implementation in header since it is a class template: | |
2688 |
|
2710 | |||
2689 |
/* including file 'src/datacontainer.cpp', size 31 |
|
2711 | /* including file 'src/datacontainer.cpp', size 31349 */ | |
2690 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
2712 | /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */ | |
2691 |
|
2713 | |||
2692 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2714 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
2693 | //////////////////// QCPDataContainer |
|
2715 | //////////////////// QCPDataContainer | |
@@ -3403,7 +3425,8 QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomai | |||||
3403 |
|
3425 | |||
3404 | /*! |
|
3426 | /*! | |
3405 | Makes sure \a begin and \a end mark a data range that is both within the bounds of this data |
|
3427 | Makes sure \a begin and \a end mark a data range that is both within the bounds of this data | |
3406 | container's data, as well as within the specified \a dataRange. |
|
3428 | container's data, as well as within the specified \a dataRange. The initial range described by | |
|
3429 | the passed iterators \a begin and \a end is never expanded, only contracted if necessary. | |||
3407 |
|
3430 | |||
3408 | This function doesn't require for \a dataRange to be within the bounds of this data container's |
|
3431 | This function doesn't require for \a dataRange to be within the bounds of this data container's | |
3409 | valid range. |
|
3432 | valid range. | |
@@ -3660,8 +3683,8 private: | |||||
3660 | /* end of 'src/plottable.h' */ |
|
3683 | /* end of 'src/plottable.h' */ | |
3661 |
|
3684 | |||
3662 |
|
3685 | |||
3663 |
/* including file 'src/item.h', size 93 |
|
3686 | /* including file 'src/item.h', size 9384 */ | |
3664 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
3687 | /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | |
3665 |
|
3688 | |||
3666 | class QCP_LIB_DECL QCPItemAnchor { |
|
3689 | class QCP_LIB_DECL QCPItemAnchor { | |
3667 | Q_GADGET |
|
3690 | Q_GADGET | |
@@ -3750,7 +3773,7 public: | |||||
3750 | QCPAxis *keyAxis() const { return mKeyAxis.data(); } |
|
3773 | QCPAxis *keyAxis() const { return mKeyAxis.data(); } | |
3751 | QCPAxis *valueAxis() const { return mValueAxis.data(); } |
|
3774 | QCPAxis *valueAxis() const { return mValueAxis.data(); } | |
3752 | QCPAxisRect *axisRect() const; |
|
3775 | QCPAxisRect *axisRect() const; | |
3753 | virtual QPointF pixelPosition() const; |
|
3776 | virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; | |
3754 |
|
3777 | |||
3755 | // setters: |
|
3778 | // setters: | |
3756 | void setType(PositionType type); |
|
3779 | void setType(PositionType type); | |
@@ -3857,8 +3880,8 private: | |||||
3857 | /* end of 'src/item.h' */ |
|
3880 | /* end of 'src/item.h' */ | |
3858 |
|
3881 | |||
3859 |
|
3882 | |||
3860 |
/* including file 'src/core.h', size 14 |
|
3883 | /* including file 'src/core.h', size 14886 */ | |
3861 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
3884 | /* commit 29aafbce469a36d175d4fb32cbfd1f50a6072890 2016-10-12 19:21:24 +0200 */ | |
3862 |
|
3885 | |||
3863 | class QCP_LIB_DECL QCustomPlot : public QWidget { |
|
3886 | class QCP_LIB_DECL QCustomPlot : public QWidget { | |
3864 | Q_OBJECT |
|
3887 | Q_OBJECT | |
@@ -4091,7 +4114,9 protected: | |||||
4091 | QPoint mMousePressPos; |
|
4114 | QPoint mMousePressPos; | |
4092 | bool mMouseHasMoved; |
|
4115 | bool mMouseHasMoved; | |
4093 | QPointer<QCPLayerable> mMouseEventLayerable; |
|
4116 | QPointer<QCPLayerable> mMouseEventLayerable; | |
|
4117 | QPointer<QCPLayerable> mMouseSignalLayerable; | |||
4094 | QVariant mMouseEventLayerableDetails; |
|
4118 | QVariant mMouseEventLayerableDetails; | |
|
4119 | QVariant mMouseSignalLayerableDetails; | |||
4095 | bool mReplotting; |
|
4120 | bool mReplotting; | |
4096 | bool mReplotQueued; |
|
4121 | bool mReplotQueued; | |
4097 | int mOpenGlMultisamples; |
|
4122 | int mOpenGlMultisamples; | |
@@ -4153,11 +4178,12 Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) | |||||
4153 | /* end of 'src/core.h' */ |
|
4178 | /* end of 'src/core.h' */ | |
4154 |
|
4179 | |||
4155 |
|
4180 | |||
4156 |
/* including file 'src/plottable1d.h', size 4 |
|
4181 | /* including file 'src/plottable1d.h', size 4544 */ | |
4157 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
4182 | /* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */ | |
4158 |
|
4183 | |||
4159 |
class |
|
4184 | class QCPPlottableInterface1D { | |
4160 | public: |
|
4185 | public: | |
|
4186 | virtual ~QCPPlottableInterface1D() {} | |||
4161 | // introduced pure virtual methods: |
|
4187 | // introduced pure virtual methods: | |
4162 | virtual int dataCount() const = 0; |
|
4188 | virtual int dataCount() const = 0; | |
4163 | virtual double dataMainKey(int index) const = 0; |
|
4189 | virtual double dataMainKey(int index) const = 0; | |
@@ -4172,8 +4198,11 public: | |||||
4172 | }; |
|
4198 | }; | |
4173 |
|
4199 | |||
4174 | template <class DataType> |
|
4200 | template <class DataType> | |
4175 |
class |
|
4201 | class QCPAbstractPlottable1D : public QCPAbstractPlottable, | |
4176 |
|
|
4202 | public QCPPlottableInterface1D // no QCP_LIB_DECL, template class | |
|
4203 | // ends up in header (cpp included | |||
|
4204 | // below) | |||
|
4205 | { | |||
4177 | // No Q_OBJECT macro due to template class |
|
4206 | // No Q_OBJECT macro due to template class | |
4178 |
|
4207 | |||
4179 | public: |
|
4208 | public: | |
@@ -4181,20 +4210,22 public: | |||||
4181 | virtual ~QCPAbstractPlottable1D(); |
|
4210 | virtual ~QCPAbstractPlottable1D(); | |
4182 |
|
4211 | |||
4183 | // virtual methods of 1d plottable interface: |
|
4212 | // virtual methods of 1d plottable interface: | |
4184 | virtual int dataCount() const; |
|
4213 | virtual int dataCount() const Q_DECL_OVERRIDE; | |
4185 | virtual double dataMainKey(int index) const; |
|
4214 | virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; | |
4186 | virtual double dataSortKey(int index) const; |
|
4215 | virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; | |
4187 | virtual double dataMainValue(int index) const; |
|
4216 | virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; | |
4188 | virtual QCPRange dataValueRange(int index) const; |
|
4217 | virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; | |
4189 | virtual QPointF dataPixelPosition(int index) const; |
|
4218 | virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; | |
4190 | virtual bool sortKeyIsMainKey() const; |
|
4219 | virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; | |
4191 |
virtual QCPDataSelection selectTestRect(const QRectF &rect, |
|
4220 | virtual QCPDataSelection selectTestRect(const QRectF &rect, | |
4192 | virtual int findBegin(double sortKey, bool expandedRange = true) const; |
|
4221 | bool onlySelectable) const Q_DECL_OVERRIDE; | |
4193 |
virtual int find |
|
4222 | virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | |
|
4223 | virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | |||
4194 |
|
4224 | |||
4195 | // virtual methods: |
|
4225 | // reimplemented virtual methods: | |
4196 |
virtual double selectTest(const QPointF &pos, bool onlySelectable, |
|
4226 | virtual double selectTest(const QPointF &pos, bool onlySelectable, | |
4197 | virtual QCPPlottableInterface1D *interface1D() { return this; } |
|
4227 | QVariant *details = 0) const Q_DECL_OVERRIDE; | |
|
4228 | virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } | |||
4198 |
|
4229 | |||
4199 | protected: |
|
4230 | protected: | |
4200 | // property members: |
|
4231 | // property members: | |
@@ -4863,8 +4894,8 Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) | |||||
4863 | /* end of 'src/colorgradient.h' */ |
|
4894 | /* end of 'src/colorgradient.h' */ | |
4864 |
|
4895 | |||
4865 |
|
4896 | |||
4866 |
/* including file 'src/selectiondecorator-bracket.h', size 442 |
|
4897 | /* including file 'src/selectiondecorator-bracket.h', size 4442 */ | |
4867 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
4898 | /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | |
4868 |
|
4899 | |||
4869 | class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator { |
|
4900 | class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator { | |
4870 | Q_GADGET |
|
4901 | Q_GADGET | |
@@ -4916,7 +4947,7 public: | |||||
4916 | virtual void drawBracket(QCPPainter *painter, int direction) const; |
|
4947 | virtual void drawBracket(QCPPainter *painter, int direction) const; | |
4917 |
|
4948 | |||
4918 | // virtual methods: |
|
4949 | // virtual methods: | |
4919 | virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); |
|
4950 | virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; | |
4920 |
|
4951 | |||
4921 | protected: |
|
4952 | protected: | |
4922 | // property members: |
|
4953 | // property members: | |
@@ -4938,8 +4969,8 Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) | |||||
4938 | /* end of 'src/selectiondecorator-bracket.h' */ |
|
4969 | /* end of 'src/selectiondecorator-bracket.h' */ | |
4939 |
|
4970 | |||
4940 |
|
4971 | |||
4941 |
/* including file 'src/layoutelements/layoutelement-axisrect.h', size 75 |
|
4972 | /* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */ | |
4942 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
4973 | /* commit 77ba168312f935543fc31d1ae9b4cdcf34aae4f9 2017-08-13 18:29:48 +0200 */ | |
4943 |
|
4974 | |||
4944 | class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement { |
|
4975 | class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement { | |
4945 | Q_OBJECT |
|
4976 | Q_OBJECT | |
@@ -5037,7 +5068,6 protected: | |||||
5037 | // non-property members: |
|
5068 | // non-property members: | |
5038 | QList<QCPRange> mDragStartHorzRange, mDragStartVertRange; |
|
5069 | QList<QCPRange> mDragStartHorzRange, mDragStartVertRange; | |
5039 | QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; |
|
5070 | QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; | |
5040 | QPoint mDragStart; |
|
|||
5041 | bool mDragging; |
|
5071 | bool mDragging; | |
5042 | QHash<QCPAxis::AxisType, QList<QCPAxis *> > mAxes; |
|
5072 | QHash<QCPAxis::AxisType, QList<QCPAxis *> > mAxes; | |
5043 |
|
5073 | |||
@@ -5378,8 +5408,8 private: | |||||
5378 | /* end of 'src/layoutelements/layoutelement-textelement.h' */ |
|
5408 | /* end of 'src/layoutelements/layoutelement-textelement.h' */ | |
5379 |
|
5409 | |||
5380 |
|
5410 | |||
5381 |
/* including file 'src/layoutelements/layoutelement-colorscale.h', size 59 |
|
5411 | /* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */ | |
5382 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
5412 | /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | |
5383 |
|
5413 | |||
5384 |
|
5414 | |||
5385 | class QCPColorScaleAxisRectPrivate : public QCPAxisRect { |
|
5415 | class QCPColorScaleAxisRectPrivate : public QCPAxisRect { | |
@@ -5398,7 +5428,7 protected: | |||||
5398 | using QCPAxisRect::mouseReleaseEvent; |
|
5428 | using QCPAxisRect::mouseReleaseEvent; | |
5399 | using QCPAxisRect::wheelEvent; |
|
5429 | using QCPAxisRect::wheelEvent; | |
5400 | using QCPAxisRect::update; |
|
5430 | using QCPAxisRect::update; | |
5401 | virtual void draw(QCPPainter *painter); |
|
5431 | virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | |
5402 | void updateGradientImage(); |
|
5432 | void updateGradientImage(); | |
5403 | Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); |
|
5433 | Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); | |
5404 | Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); |
|
5434 | Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); | |
@@ -5486,8 +5516,8 private: | |||||
5486 | /* end of 'src/layoutelements/layoutelement-colorscale.h' */ |
|
5516 | /* end of 'src/layoutelements/layoutelement-colorscale.h' */ | |
5487 |
|
5517 | |||
5488 |
|
5518 | |||
5489 |
/* including file 'src/plottables/plottable-graph.h', size |
|
5519 | /* including file 'src/plottables/plottable-graph.h', size 9294 */ | |
5490 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
5520 | /* commit f3881770eaf7366171012ad01cad2aaf5f61dd27 2017-06-23 02:48:21 +0200 */ | |
5491 |
|
5521 | |||
5492 | class QCP_LIB_DECL QCPGraphData { |
|
5522 | class QCP_LIB_DECL QCPGraphData { | |
5493 | public: |
|
5523 | public: | |
@@ -5624,11 +5654,20 protected: | |||||
5624 | QVector<QPointF> dataToStepRightLines(const QVector<QCPGraphData> &data) const; |
|
5654 | QVector<QPointF> dataToStepRightLines(const QVector<QCPGraphData> &data) const; | |
5625 | QVector<QPointF> dataToStepCenterLines(const QVector<QCPGraphData> &data) const; |
|
5655 | QVector<QPointF> dataToStepCenterLines(const QVector<QCPGraphData> &data) const; | |
5626 | QVector<QPointF> dataToImpulseLines(const QVector<QCPGraphData> &data) const; |
|
5656 | QVector<QPointF> dataToImpulseLines(const QVector<QCPGraphData> &data) const; | |
5627 | void addFillBasePoints(QVector<QPointF> *lines) const; |
|
5657 | QVector<QCPDataRange> getNonNanSegments(const QVector<QPointF> *lineData, | |
5628 | void removeFillBasePoints(QVector<QPointF> *lines) const; |
|
5658 | Qt::Orientation keyOrientation) const; | |
5629 | QPointF lowerFillBasePoint(double lowerKey) const; |
|
5659 | QVector<QPair<QCPDataRange, QCPDataRange> > | |
5630 | QPointF upperFillBasePoint(double upperKey) const; |
|
5660 | getOverlappingSegments(QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData, | |
5631 | const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lines) const; |
|
5661 | QVector<QCPDataRange> otherSegments, | |
|
5662 | const QVector<QPointF> *otherData) const; | |||
|
5663 | bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, | |||
|
5664 | int &bPrecedence) const; | |||
|
5665 | QPointF getFillBasePoint(QPointF matchingDataPoint) const; | |||
|
5666 | const QPolygonF getFillPolygon(const QVector<QPointF> *lineData, QCPDataRange segment) const; | |||
|
5667 | const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lineData, | |||
|
5668 | QCPDataRange thisSegment, | |||
|
5669 | const QVector<QPointF> *otherData, | |||
|
5670 | QCPDataRange otherSegment) const; | |||
5632 | int findIndexBelowX(const QVector<QPointF> *data, double x) const; |
|
5671 | int findIndexBelowX(const QVector<QPointF> *data, double x) const; | |
5633 | int findIndexAboveX(const QVector<QPointF> *data, double x) const; |
|
5672 | int findIndexAboveX(const QVector<QPointF> *data, double x) const; | |
5634 | int findIndexBelowY(const QVector<QPointF> *data, double y) const; |
|
5673 | int findIndexBelowY(const QVector<QPointF> *data, double y) const; | |
@@ -6425,8 +6464,8 Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) | |||||
6425 | /* end of 'src/plottables/plottable-financial.h' */ |
|
6464 | /* end of 'src/plottables/plottable-financial.h' */ | |
6426 |
|
6465 | |||
6427 |
|
6466 | |||
6428 |
/* including file 'src/plottables/plottable-errorbar.h', size 7 |
|
6467 | /* including file 'src/plottables/plottable-errorbar.h', size 7727 */ | |
6429 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
6468 | /* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | |
6430 |
|
6469 | |||
6431 | class QCP_LIB_DECL QCPErrorBarsData { |
|
6470 | class QCP_LIB_DECL QCPErrorBarsData { | |
6432 | public: |
|
6471 | public: | |
@@ -6505,16 +6544,17 public: | |||||
6505 | void addData(double errorMinus, double errorPlus); |
|
6544 | void addData(double errorMinus, double errorPlus); | |
6506 |
|
6545 | |||
6507 | // virtual methods of 1d plottable interface: |
|
6546 | // virtual methods of 1d plottable interface: | |
6508 | virtual int dataCount() const; |
|
6547 | virtual int dataCount() const Q_DECL_OVERRIDE; | |
6509 | virtual double dataMainKey(int index) const; |
|
6548 | virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; | |
6510 | virtual double dataSortKey(int index) const; |
|
6549 | virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; | |
6511 | virtual double dataMainValue(int index) const; |
|
6550 | virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; | |
6512 | virtual QCPRange dataValueRange(int index) const; |
|
6551 | virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; | |
6513 | virtual QPointF dataPixelPosition(int index) const; |
|
6552 | virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; | |
6514 | virtual bool sortKeyIsMainKey() const; |
|
6553 | virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; | |
6515 |
virtual QCPDataSelection selectTestRect(const QRectF &rect, |
|
6554 | virtual QCPDataSelection selectTestRect(const QRectF &rect, | |
6516 | virtual int findBegin(double sortKey, bool expandedRange = true) const; |
|
6555 | bool onlySelectable) const Q_DECL_OVERRIDE; | |
6517 |
virtual int find |
|
6556 | virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | |
|
6557 | virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | |||
6518 |
|
6558 | |||
6519 | // reimplemented virtual methods: |
|
6559 | // reimplemented virtual methods: | |
6520 | virtual double selectTest(const QPointF &pos, bool onlySelectable, |
|
6560 | virtual double selectTest(const QPointF &pos, bool onlySelectable, |
This diff has been collapsed as it changes many lines, (1395 lines changed) Show them Hide them | |||||
@@ -1574,10 +1574,7 void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialia | |||||
1574 |
|
1574 | |||
1575 | \see initializeParentPlot |
|
1575 | \see initializeParentPlot | |
1576 | */ |
|
1576 | */ | |
1577 | void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot) |
|
1577 | void QCPLayerable::parentPlotInitialized(QCustomPlot *parentPlot){Q_UNUSED(parentPlot)} | |
1578 | { |
|
|||
1579 | Q_UNUSED(parentPlot) |
|
|||
1580 | } |
|
|||
1581 |
|
1578 | |||
1582 | /*! \internal |
|
1579 | /*! \internal | |
1583 |
|
1580 | |||
@@ -2102,8 +2099,8 bool QCPRange::validRange(const QCPRange &range) | |||||
2102 | /* end of 'src/axis/range.cpp' */ |
|
2099 | /* end of 'src/axis/range.cpp' */ | |
2103 |
|
2100 | |||
2104 |
|
2101 | |||
2105 |
/* including file 'src/selection.cpp', size 21 |
|
2102 | /* including file 'src/selection.cpp', size 21906 */ | |
2106 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
2103 | /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */ | |
2107 |
|
2104 | |||
2108 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2105 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
2109 | //////////////////// QCPDataRange |
|
2106 | //////////////////// QCPDataRange | |
@@ -2406,7 +2403,7 QCPDataSelection &QCPDataSelection::operator+=(const QCPDataRange &other) | |||||
2406 | } |
|
2403 | } | |
2407 |
|
2404 | |||
2408 | /*! |
|
2405 | /*! | |
2409 |
Removes all data point indices that are described by \a other from this data |
|
2406 | Removes all data point indices that are described by \a other from this data selection. | |
2410 | */ |
|
2407 | */ | |
2411 | QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other) |
|
2408 | QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other) | |
2412 | { |
|
2409 | { | |
@@ -2417,7 +2414,7 QCPDataSelection &QCPDataSelection::operator-=(const QCPDataSelection &other) | |||||
2417 | } |
|
2414 | } | |
2418 |
|
2415 | |||
2419 | /*! |
|
2416 | /*! | |
2420 |
Removes all data point indices that are described by \a other from this data |
|
2417 | Removes all data point indices that are described by \a other from this data selection. | |
2421 | */ |
|
2418 | */ | |
2422 | QCPDataSelection &QCPDataSelection::operator-=(const QCPDataRange &other) |
|
2419 | QCPDataSelection &QCPDataSelection::operator-=(const QCPDataRange &other) | |
2423 | { |
|
2420 | { | |
@@ -2930,8 +2927,8 void QCPSelectionRect::draw(QCPPainter *painter) | |||||
2930 | /* end of 'src/selectionrect.cpp' */ |
|
2927 | /* end of 'src/selectionrect.cpp' */ | |
2931 |
|
2928 | |||
2932 |
|
2929 | |||
2933 |
/* including file 'src/layout.cpp', size 743 |
|
2930 | /* including file 'src/layout.cpp', size 74663 */ | |
2934 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
2931 | /* commit a872eb91ec087561efd83dd9cb041a26ab95ce55 2017-07-31 00:21:41 +0200 */ | |
2935 |
|
2932 | |||
2936 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
2933 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
2937 | //////////////////// QCPMarginGroup |
|
2934 | //////////////////// QCPMarginGroup | |
@@ -3572,12 +3569,13 QCPLayout::QCPLayout() | |||||
3572 | } |
|
3569 | } | |
3573 |
|
3570 | |||
3574 | /*! |
|
3571 | /*! | |
3575 | First calls the QCPLayoutElement::update base class implementation to update the margins on this |
|
3572 | If \a phase is \ref upLayout, calls \ref updateLayout, which subclasses may reimplement to | |
3576 | layout. |
|
3573 | reposition and resize their cells. | |
3577 |
|
3574 | |||
3578 | Then calls \ref updateLayout which subclasses reimplement to reposition and resize their cells. |
|
3575 | Finally, the call is propagated down to all child \ref QCPLayoutElement "QCPLayoutElements". | |
3579 |
|
3576 | |||
3580 | Finally, \ref update is called on all child elements. |
|
3577 | For details about this method and the update phases, see the documentation of \ref | |
|
3578 | QCPLayoutElement::update. | |||
3581 | */ |
|
3579 | */ | |
3582 | void QCPLayout::update(UpdatePhase phase) |
|
3580 | void QCPLayout::update(UpdatePhase phase) | |
3583 | { |
|
3581 | { | |
@@ -4242,7 +4240,7 void QCPLayoutGrid::setWrap(int count) | |||||
4242 |
|
4240 | |||
4243 | If you want to have all current elements arranged in the new order, set \a rearrange to true. The |
|
4241 | If you want to have all current elements arranged in the new order, set \a rearrange to true. The | |
4244 | elements will be rearranged in a way that tries to preserve their linear index. However, empty |
|
4242 | elements will be rearranged in a way that tries to preserve their linear index. However, empty | |
4245 | cells are skipped during build-up of the new cell order, which shifts the succeding element's |
|
4243 | cells are skipped during build-up of the new cell order, which shifts the succeeding element's | |
4246 | index. The rearranging is performed even if the specified \a order is already the current fill |
|
4244 | index. The rearranging is performed even if the specified \a order is already the current fill | |
4247 | order. Thus this method can be used to re-wrap the current elements. |
|
4245 | order. Thus this method can be used to re-wrap the current elements. | |
4248 |
|
4246 | |||
@@ -4337,7 +4335,8 void QCPLayoutGrid::insertRow(int newIndex) | |||||
4337 |
|
4335 | |||
4338 | /*! |
|
4336 | /*! | |
4339 | Inserts a new column with empty cells at the column index \a newIndex. Valid values for \a |
|
4337 | Inserts a new column with empty cells at the column index \a newIndex. Valid values for \a | |
4340 |
newIndex range from 0 (inserts a |
|
4338 | newIndex range from 0 (inserts a column at the left) to \a columnCount (appends a column at the | |
|
4339 | right). | |||
4341 |
|
4340 | |||
4342 | \see insertRow |
|
4341 | \see insertRow | |
4343 | */ |
|
4342 | */ | |
@@ -4411,7 +4410,9 void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const | |||||
4411 | { |
|
4410 | { | |
4412 | row = -1; |
|
4411 | row = -1; | |
4413 | column = -1; |
|
4412 | column = -1; | |
4414 | if (columnCount() == 0 || rowCount() == 0) |
|
4413 | const int nCols = columnCount(); | |
|
4414 | const int nRows = rowCount(); | |||
|
4415 | if (nCols == 0 || nRows == 0) | |||
4415 | return; |
|
4416 | return; | |
4416 | if (index < 0 || index >= elementCount()) { |
|
4417 | if (index < 0 || index >= elementCount()) { | |
4417 | qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; |
|
4418 | qDebug() << Q_FUNC_INFO << "index out of bounds:" << index; | |
@@ -4420,13 +4421,13 void QCPLayoutGrid::indexToRowCol(int index, int &row, int &column) const | |||||
4420 |
|
4421 | |||
4421 | switch (mFillOrder) { |
|
4422 | switch (mFillOrder) { | |
4422 | case foRowsFirst: { |
|
4423 | case foRowsFirst: { | |
4423 |
column = index / |
|
4424 | column = index / nRows; | |
4424 |
row = index % |
|
4425 | row = index % nRows; | |
4425 | break; |
|
4426 | break; | |
4426 | } |
|
4427 | } | |
4427 | case foColumnsFirst: { |
|
4428 | case foColumnsFirst: { | |
4428 |
row = index / |
|
4429 | row = index / nCols; | |
4429 |
column = index % |
|
4430 | column = index % nCols; | |
4430 | break; |
|
4431 | break; | |
4431 | } |
|
4432 | } | |
4432 | } |
|
4433 | } | |
@@ -4592,9 +4593,8 QSize QCPLayoutGrid::minimumSizeHint() const | |||||
4592 | result.rwidth() += minColWidths.at(i); |
|
4593 | result.rwidth() += minColWidths.at(i); | |
4593 | for (int i = 0; i < minRowHeights.size(); ++i) |
|
4594 | for (int i = 0; i < minRowHeights.size(); ++i) | |
4594 | result.rheight() += minRowHeights.at(i); |
|
4595 | result.rheight() += minRowHeights.at(i); | |
4595 | result.rwidth() |
|
4596 | result.rwidth() += qMax(0, columnCount() - 1) * mColumnSpacing; | |
4596 | += qMax(0, columnCount() - 1) * mColumnSpacing + mMargins.left() + mMargins.right(); |
|
4597 | result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing; | |
4597 | result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing + mMargins.top() + mMargins.bottom(); |
|
|||
4598 | return result; |
|
4598 | return result; | |
4599 | } |
|
4599 | } | |
4600 |
|
4600 | |||
@@ -4609,9 +4609,8 QSize QCPLayoutGrid::maximumSizeHint() const | |||||
4609 | result.setWidth(qMin(result.width() + maxColWidths.at(i), QWIDGETSIZE_MAX)); |
|
4609 | result.setWidth(qMin(result.width() + maxColWidths.at(i), QWIDGETSIZE_MAX)); | |
4610 | for (int i = 0; i < maxRowHeights.size(); ++i) |
|
4610 | for (int i = 0; i < maxRowHeights.size(); ++i) | |
4611 | result.setHeight(qMin(result.height() + maxRowHeights.at(i), QWIDGETSIZE_MAX)); |
|
4611 | result.setHeight(qMin(result.height() + maxRowHeights.at(i), QWIDGETSIZE_MAX)); | |
4612 | result.rwidth() |
|
4612 | result.rwidth() += qMax(0, columnCount() - 1) * mColumnSpacing; | |
4613 | += qMax(0, columnCount() - 1) * mColumnSpacing + mMargins.left() + mMargins.right(); |
|
4613 | result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing; | |
4614 | result.rheight() += qMax(0, rowCount() - 1) * mRowSpacing + mMargins.top() + mMargins.bottom(); |
|
|||
4615 | return result; |
|
4614 | return result; | |
4616 | } |
|
4615 | } | |
4617 |
|
4616 | |||
@@ -4620,8 +4619,9 QSize QCPLayoutGrid::maximumSizeHint() const | |||||
4620 | Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights |
|
4619 | Places the minimum column widths and row heights into \a minColWidths and \a minRowHeights | |
4621 | respectively. |
|
4620 | respectively. | |
4622 |
|
4621 | |||
4623 |
The minimum height of a row is the largest minimum height of any element in that |
|
4622 | The minimum height of a row is the largest minimum height of any element's outer rect in that | |
4624 |
width of a column is the largest minimum width of any element in |
|
4623 | row. The minimum width of a column is the largest minimum width of any element's outer rect in | |
|
4624 | that column. | |||
4625 |
|
4625 | |||
4626 | This is a helper function for \ref updateLayout. |
|
4626 | This is a helper function for \ref updateLayout. | |
4627 |
|
4627 | |||
@@ -4634,11 +4634,13 void QCPLayoutGrid::getMinimumRowColSizes(QVector<int> *minColWidths, | |||||
4634 | *minRowHeights = QVector<int>(rowCount(), 0); |
|
4634 | *minRowHeights = QVector<int>(rowCount(), 0); | |
4635 | for (int row = 0; row < rowCount(); ++row) { |
|
4635 | for (int row = 0; row < rowCount(); ++row) { | |
4636 | for (int col = 0; col < columnCount(); ++col) { |
|
4636 | for (int col = 0; col < columnCount(); ++col) { | |
4637 | if (mElements.at(row).at(col)) { |
|
4637 | if (QCPLayoutElement *el = mElements.at(row).at(col)) { | |
4638 |
QSize minHint = |
|
4638 | QSize minHint = el->minimumSizeHint(); | |
4639 |
QSize min = |
|
4639 | QSize min = el->minimumSize(); | |
4640 | QSize final(min.width() > 0 ? min.width() : minHint.width(), |
|
4640 | QSize final(min.width() > 0 ? min.width() : minHint.width(), | |
4641 | min.height() > 0 ? min.height() : minHint.height()); |
|
4641 | min.height() > 0 ? min.height() : minHint.height()); | |
|
4642 | final += QSize(el->margins().left() + el->margins().right(), | |||
|
4643 | el->margins().top() + el->margins().bottom()); | |||
4642 | if (minColWidths->at(col) < final.width()) |
|
4644 | if (minColWidths->at(col) < final.width()) | |
4643 | (*minColWidths)[col] = final.width(); |
|
4645 | (*minColWidths)[col] = final.width(); | |
4644 | if (minRowHeights->at(row) < final.height()) |
|
4646 | if (minRowHeights->at(row) < final.height()) | |
@@ -4653,8 +4655,9 void QCPLayoutGrid::getMinimumRowColSizes(QVector<int> *minColWidths, | |||||
4653 | Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights |
|
4655 | Places the maximum column widths and row heights into \a maxColWidths and \a maxRowHeights | |
4654 | respectively. |
|
4656 | respectively. | |
4655 |
|
4657 | |||
4656 |
The maximum height of a row is the smallest maximum height of any element in that |
|
4658 | The maximum height of a row is the smallest maximum height of any element's outer rect in that | |
4657 |
maximum width of a column is the smallest maximum width of any element in |
|
4659 | row. The maximum width of a column is the smallest maximum width of any element's outer rect in | |
|
4660 | that column. | |||
4658 |
|
4661 | |||
4659 | This is a helper function for \ref updateLayout. |
|
4662 | This is a helper function for \ref updateLayout. | |
4660 |
|
4663 | |||
@@ -4667,11 +4670,13 void QCPLayoutGrid::getMaximumRowColSizes(QVector<int> *maxColWidths, | |||||
4667 | *maxRowHeights = QVector<int>(rowCount(), QWIDGETSIZE_MAX); |
|
4670 | *maxRowHeights = QVector<int>(rowCount(), QWIDGETSIZE_MAX); | |
4668 | for (int row = 0; row < rowCount(); ++row) { |
|
4671 | for (int row = 0; row < rowCount(); ++row) { | |
4669 | for (int col = 0; col < columnCount(); ++col) { |
|
4672 | for (int col = 0; col < columnCount(); ++col) { | |
4670 | if (mElements.at(row).at(col)) { |
|
4673 | if (QCPLayoutElement *el = mElements.at(row).at(col)) { | |
4671 |
QSize maxHint = |
|
4674 | QSize maxHint = el->maximumSizeHint(); | |
4672 |
QSize max = |
|
4675 | QSize max = el->maximumSize(); | |
4673 | QSize final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(), |
|
4676 | QSize final(max.width() < QWIDGETSIZE_MAX ? max.width() : maxHint.width(), | |
4674 | max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height()); |
|
4677 | max.height() < QWIDGETSIZE_MAX ? max.height() : maxHint.height()); | |
|
4678 | final += QSize(el->margins().left() + el->margins().right(), | |||
|
4679 | el->margins().top() + el->margins().bottom()); | |||
4675 | if (maxColWidths->at(col) > final.width()) |
|
4680 | if (maxColWidths->at(col) > final.width()) | |
4676 | (*maxColWidths)[col] = final.width(); |
|
4681 | (*maxColWidths)[col] = final.width(); | |
4677 | if (maxRowHeights->at(row) > final.height()) |
|
4682 | if (maxRowHeights->at(row) > final.height()) | |
@@ -4820,22 +4825,25 void QCPLayoutInset::setInsetRect(int index, const QRectF &rect) | |||||
4820 | void QCPLayoutInset::updateLayout() |
|
4825 | void QCPLayoutInset::updateLayout() | |
4821 | { |
|
4826 | { | |
4822 | for (int i = 0; i < mElements.size(); ++i) { |
|
4827 | for (int i = 0; i < mElements.size(); ++i) { | |
|
4828 | QCPLayoutElement *el = mElements.at(i); | |||
4823 | QRect insetRect; |
|
4829 | QRect insetRect; | |
4824 | QSize finalMinSize, finalMaxSize; |
|
4830 | QSize finalMinSize, finalMaxSize; | |
4825 |
QSize minSizeHint = |
|
4831 | QSize minSizeHint = el->minimumSizeHint(); | |
4826 |
QSize maxSizeHint = |
|
4832 | QSize maxSizeHint = el->maximumSizeHint(); | |
4827 |
finalMinSize.setWidth( |
|
4833 | finalMinSize.setWidth(el->minimumSize().width() > 0 ? el->minimumSize().width() | |
4828 |
|
|
4834 | : minSizeHint.width()); | |
4829 | : minSizeHint.width()); |
|
4835 | finalMinSize.setHeight(el->minimumSize().height() > 0 ? el->minimumSize().height() | |
4830 | finalMinSize.setHeight(mElements.at(i)->minimumSize().height() > 0 |
|
4836 | : minSizeHint.height()); | |
4831 | ? mElements.at(i)->minimumSize().height() |
|
4837 | finalMaxSize.setWidth(el->maximumSize().width() < QWIDGETSIZE_MAX | |
4832 |
|
|
4838 | ? el->maximumSize().width() | |
4833 | finalMaxSize.setWidth(mElements.at(i)->maximumSize().width() < QWIDGETSIZE_MAX |
|
|||
4834 | ? mElements.at(i)->maximumSize().width() |
|
|||
4835 | : maxSizeHint.width()); |
|
4839 | : maxSizeHint.width()); | |
4836 |
finalMaxSize.setHeight( |
|
4840 | finalMaxSize.setHeight(el->maximumSize().height() < QWIDGETSIZE_MAX | |
4837 |
? |
|
4841 | ? el->maximumSize().height() | |
4838 | : maxSizeHint.height()); |
|
4842 | : maxSizeHint.height()); | |
|
4843 | finalMinSize += QSize(el->margins().left() + el->margins().right(), | |||
|
4844 | el->margins().top() + el->margins().bottom()); | |||
|
4845 | finalMaxSize += QSize(el->margins().left() + el->margins().right(), | |||
|
4846 | el->margins().top() + el->margins().bottom()); | |||
4839 | if (mInsetPlacement.at(i) == ipFree) { |
|
4847 | if (mInsetPlacement.at(i) == ipFree) { | |
4840 | insetRect = QRect(rect().x() + rect().width() * mInsetRect.at(i).x(), |
|
4848 | insetRect = QRect(rect().x() + rect().width() * mInsetRect.at(i).x(), | |
4841 | rect().y() + rect().height() * mInsetRect.at(i).y(), |
|
4849 | rect().y() + rect().height() * mInsetRect.at(i).y(), | |
@@ -7150,8 +7158,8 QVector<double> QCPAxisTickerLog::createTickVector(double tickStep, const QCPRan | |||||
7150 | /* end of 'src/axis/axistickerlog.cpp' */ |
|
7158 | /* end of 'src/axis/axistickerlog.cpp' */ | |
7151 |
|
7159 | |||
7152 |
|
7160 | |||
7153 |
/* including file 'src/axis/axis.cpp', size 9 |
|
7161 | /* including file 'src/axis/axis.cpp', size 99397 */ | |
7154 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
7162 | /* commit 0cc4d9f61f7bf45321a88fec89d909b020ffa26f 2017-08-14 00:43:29 +0200 */ | |
7155 |
|
7163 | |||
7156 |
|
7164 | |||
7157 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
7165 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
@@ -8643,11 +8651,11 double QCPAxis::coordToPixel(double value) const | |||||
8643 | } |
|
8651 | } | |
8644 | else // mScaleType == stLogarithmic |
|
8652 | else // mScaleType == stLogarithmic | |
8645 | { |
|
8653 | { | |
8646 |
if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just |
|
8654 | if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just | |
8647 | // outside visible range |
|
8655 | // draw it outside visible range | |
8648 | return !mRangeReversed ? mAxisRect->right() + 200 : mAxisRect->left() - 200; |
|
8656 | return !mRangeReversed ? mAxisRect->right() + 200 : mAxisRect->left() - 200; | |
8649 |
else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, |
|
8657 | else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, | |
8650 | // draw it outside visible range |
|
8658 | // just draw it outside visible range | |
8651 | return !mRangeReversed ? mAxisRect->left() - 200 : mAxisRect->right() + 200; |
|
8659 | return !mRangeReversed ? mAxisRect->left() - 200 : mAxisRect->right() + 200; | |
8652 | else { |
|
8660 | else { | |
8653 | if (!mRangeReversed) |
|
8661 | if (!mRangeReversed) | |
@@ -8673,11 +8681,11 double QCPAxis::coordToPixel(double value) const | |||||
8673 | } |
|
8681 | } | |
8674 | else // mScaleType == stLogarithmic |
|
8682 | else // mScaleType == stLogarithmic | |
8675 | { |
|
8683 | { | |
8676 |
if (value >= 0 && mRange.upper < 0) // invalid value for logarithmic scale, just |
|
8684 | if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just | |
8677 | // outside visible range |
|
8685 | // draw it outside visible range | |
8678 | return !mRangeReversed ? mAxisRect->top() - 200 : mAxisRect->bottom() + 200; |
|
8686 | return !mRangeReversed ? mAxisRect->top() - 200 : mAxisRect->bottom() + 200; | |
8679 |
else if (value <= 0 && mRange.upper > 0) // invalid value for logarithmic scale, |
|
8687 | else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, | |
8680 | // draw it outside visible range |
|
8688 | // just draw it outside visible range | |
8681 | return !mRangeReversed ? mAxisRect->bottom() + 200 : mAxisRect->top() - 200; |
|
8689 | return !mRangeReversed ? mAxisRect->bottom() + 200 : mAxisRect->top() - 200; | |
8682 | else { |
|
8690 | else { | |
8683 | if (!mRangeReversed) |
|
8691 | if (!mRangeReversed) | |
@@ -8868,6 +8876,132 void QCPAxis::deselectEvent(bool *selectionStateChanged) | |||||
8868 |
|
8876 | |||
8869 | /*! \internal |
|
8877 | /*! \internal | |
8870 |
|
8878 | |||
|
8879 | This mouse event reimplementation provides the functionality to let the user drag individual axes | |||
|
8880 | exclusively, by startig the drag on top of the axis. | |||
|
8881 | ||||
|
8882 | For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect | |||
|
8883 | must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis | |||
|
8884 | (\ref QCPAxisRect::setRangeDrag) and this axis must be a draggable axis (\ref | |||
|
8885 | QCPAxisRect::setRangeDragAxes) | |||
|
8886 | ||||
|
8887 | \seebaseclassmethod | |||
|
8888 | ||||
|
8889 | \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis | |||
|
8890 | rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. | |||
|
8891 | */ | |||
|
8892 | void QCPAxis::mousePressEvent(QMouseEvent *event, const QVariant &details) | |||
|
8893 | { | |||
|
8894 | Q_UNUSED(details) | |||
|
8895 | if (!mParentPlot->interactions().testFlag(QCP::iRangeDrag) | |||
|
8896 | || !mAxisRect->rangeDrag().testFlag(orientation()) | |||
|
8897 | || !mAxisRect->rangeDragAxes(orientation()).contains(this)) { | |||
|
8898 | event->ignore(); | |||
|
8899 | return; | |||
|
8900 | } | |||
|
8901 | ||||
|
8902 | if (event->buttons() & Qt::LeftButton) { | |||
|
8903 | mDragging = true; | |||
|
8904 | // initialize antialiasing backup in case we start dragging: | |||
|
8905 | if (mParentPlot->noAntialiasingOnDrag()) { | |||
|
8906 | mAADragBackup = mParentPlot->antialiasedElements(); | |||
|
8907 | mNotAADragBackup = mParentPlot->notAntialiasedElements(); | |||
|
8908 | } | |||
|
8909 | // Mouse range dragging interaction: | |||
|
8910 | if (mParentPlot->interactions().testFlag(QCP::iRangeDrag)) | |||
|
8911 | mDragStartRange = mRange; | |||
|
8912 | } | |||
|
8913 | } | |||
|
8914 | ||||
|
8915 | /*! \internal | |||
|
8916 | ||||
|
8917 | This mouse event reimplementation provides the functionality to let the user drag individual axes | |||
|
8918 | exclusively, by startig the drag on top of the axis. | |||
|
8919 | ||||
|
8920 | \seebaseclassmethod | |||
|
8921 | ||||
|
8922 | \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis | |||
|
8923 | rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. | |||
|
8924 | ||||
|
8925 | \see QCPAxis::mousePressEvent | |||
|
8926 | */ | |||
|
8927 | void QCPAxis::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) | |||
|
8928 | { | |||
|
8929 | if (mDragging) { | |||
|
8930 | const double startPixel = orientation() == Qt::Horizontal ? startPos.x() : startPos.y(); | |||
|
8931 | const double currentPixel | |||
|
8932 | = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y(); | |||
|
8933 | if (mScaleType == QCPAxis::stLinear) { | |||
|
8934 | const double diff = pixelToCoord(startPixel) - pixelToCoord(currentPixel); | |||
|
8935 | setRange(mDragStartRange.lower + diff, mDragStartRange.upper + diff); | |||
|
8936 | } | |||
|
8937 | else if (mScaleType == QCPAxis::stLogarithmic) { | |||
|
8938 | const double diff = pixelToCoord(startPixel) / pixelToCoord(currentPixel); | |||
|
8939 | setRange(mDragStartRange.lower * diff, mDragStartRange.upper * diff); | |||
|
8940 | } | |||
|
8941 | ||||
|
8942 | if (mParentPlot->noAntialiasingOnDrag()) | |||
|
8943 | mParentPlot->setNotAntialiasedElements(QCP::aeAll); | |||
|
8944 | mParentPlot->replot(QCustomPlot::rpQueuedReplot); | |||
|
8945 | } | |||
|
8946 | } | |||
|
8947 | ||||
|
8948 | /*! \internal | |||
|
8949 | ||||
|
8950 | This mouse event reimplementation provides the functionality to let the user drag individual axes | |||
|
8951 | exclusively, by startig the drag on top of the axis. | |||
|
8952 | ||||
|
8953 | \seebaseclassmethod | |||
|
8954 | ||||
|
8955 | \note The dragging of possibly multiple axes at once by starting the drag anywhere in the axis | |||
|
8956 | rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::mousePressEvent. | |||
|
8957 | ||||
|
8958 | \see QCPAxis::mousePressEvent | |||
|
8959 | */ | |||
|
8960 | void QCPAxis::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) | |||
|
8961 | { | |||
|
8962 | Q_UNUSED(event) | |||
|
8963 | Q_UNUSED(startPos) | |||
|
8964 | mDragging = false; | |||
|
8965 | if (mParentPlot->noAntialiasingOnDrag()) { | |||
|
8966 | mParentPlot->setAntialiasedElements(mAADragBackup); | |||
|
8967 | mParentPlot->setNotAntialiasedElements(mNotAADragBackup); | |||
|
8968 | } | |||
|
8969 | } | |||
|
8970 | ||||
|
8971 | /*! \internal | |||
|
8972 | ||||
|
8973 | This mouse event reimplementation provides the functionality to let the user zoom individual axes | |||
|
8974 | exclusively, by performing the wheel event on top of the axis. | |||
|
8975 | ||||
|
8976 | For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect | |||
|
8977 | must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis | |||
|
8978 | (\ref QCPAxisRect::setRangeZoom) and this axis must be a zoomable axis (\ref | |||
|
8979 | QCPAxisRect::setRangeZoomAxes) | |||
|
8980 | ||||
|
8981 | \seebaseclassmethod | |||
|
8982 | ||||
|
8983 | \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the | |||
|
8984 | axis rect is handled by the axis rect's mouse event, e.g. \ref QCPAxisRect::wheelEvent. | |||
|
8985 | */ | |||
|
8986 | void QCPAxis::wheelEvent(QWheelEvent *event) | |||
|
8987 | { | |||
|
8988 | // Mouse range zooming interaction: | |||
|
8989 | if (!mParentPlot->interactions().testFlag(QCP::iRangeZoom) | |||
|
8990 | || !mAxisRect->rangeZoom().testFlag(orientation()) | |||
|
8991 | || !mAxisRect->rangeZoomAxes(orientation()).contains(this)) { | |||
|
8992 | event->ignore(); | |||
|
8993 | return; | |||
|
8994 | } | |||
|
8995 | ||||
|
8996 | const double wheelSteps = event->delta() / 120.0; // a single step delta is +/-120 usually | |||
|
8997 | const double factor = qPow(mAxisRect->rangeZoomFactor(orientation()), wheelSteps); | |||
|
8998 | scaleRange(factor, | |||
|
8999 | pixelToCoord(orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y())); | |||
|
9000 | mParentPlot->replot(); | |||
|
9001 | } | |||
|
9002 | ||||
|
9003 | /*! \internal | |||
|
9004 | ||||
8871 | A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter |
|
9005 | A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter | |
8872 | before drawing axis lines. |
|
9006 | before drawing axis lines. | |
8873 |
|
9007 | |||
@@ -9257,14 +9391,16 void QCPAxisPainterPrivate::draw(QCPPainter *painter) | |||||
9257 | painter->setBrush(QBrush(basePen.color())); |
|
9391 | painter->setBrush(QBrush(basePen.color())); | |
9258 | QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); |
|
9392 | QCPVector2D baseLineVector(baseLine.dx(), baseLine.dy()); | |
9259 | if (lowerEnding.style() != QCPLineEnding::esNone) |
|
9393 | if (lowerEnding.style() != QCPLineEnding::esNone) | |
9260 |
lowerEnding.draw(painter, |
|
9394 | lowerEnding.draw(painter, | |
9261 | - baseLineVector.normalized() * lowerEnding.realLength() |
|
9395 | QCPVector2D(baseLine.p1()) | |
9262 | * (lowerEnding.inverted() ? -1 : 1), |
|
9396 | - baseLineVector.normalized() * lowerEnding.realLength() | |
|
9397 | * (lowerEnding.inverted() ? -1 : 1), | |||
9263 | -baseLineVector); |
|
9398 | -baseLineVector); | |
9264 | if (upperEnding.style() != QCPLineEnding::esNone) |
|
9399 | if (upperEnding.style() != QCPLineEnding::esNone) | |
9265 |
upperEnding.draw(painter, |
|
9400 | upperEnding.draw(painter, | |
9266 | + baseLineVector.normalized() * upperEnding.realLength() |
|
9401 | QCPVector2D(baseLine.p2()) | |
9267 | * (upperEnding.inverted() ? -1 : 1), |
|
9402 | + baseLineVector.normalized() * upperEnding.realLength() | |
|
9403 | * (upperEnding.inverted() ? -1 : 1), | |||
9268 | baseLineVector); |
|
9404 | baseLineVector); | |
9269 | painter->setAntialiasing(antialiasingBackup); |
|
9405 | painter->setAntialiasing(antialiasingBackup); | |
9270 |
|
9406 | |||
@@ -9524,12 +9660,15 void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, | |||||
9524 | cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size() |
|
9660 | cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size() | |
9525 | * mParentPlot->bufferDevicePixelRatio()); |
|
9661 | * mParentPlot->bufferDevicePixelRatio()); | |
9526 | #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED |
|
9662 | #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED | |
|
9663 | #ifdef QCP_DEVICEPIXELRATIO_FLOAT | |||
|
9664 | cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatioF()); | |||
|
9665 | #else | |||
9527 | cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); |
|
9666 | cachedLabel->pixmap.setDevicePixelRatio(mParentPlot->devicePixelRatio()); | |
9528 | #endif |
|
9667 | #endif | |
|
9668 | #endif | |||
9529 | } |
|
9669 | } | |
9530 | else |
|
9670 | else | |
9531 | cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); |
|
9671 | cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); | |
9532 | cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()); |
|
|||
9533 | cachedLabel->pixmap.fill(Qt::transparent); |
|
9672 | cachedLabel->pixmap.fill(Qt::transparent); | |
9534 | QCPPainter cachePainter(&cachedLabel->pixmap); |
|
9673 | QCPPainter cachePainter(&cachedLabel->pixmap); | |
9535 | cachePainter.setPen(painter->pen()); |
|
9674 | cachePainter.setPen(painter->pen()); | |
@@ -9894,8 +10033,8 void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString | |||||
9894 | /* end of 'src/axis/axis.cpp' */ |
|
10033 | /* end of 'src/axis/axis.cpp' */ | |
9895 |
|
10034 | |||
9896 |
|
10035 | |||
9897 |
/* including file 'src/scatterstyle.cpp', size 174 |
|
10036 | /* including file 'src/scatterstyle.cpp', size 17450 */ | |
9898 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
10037 | /* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */ | |
9899 |
|
10038 | |||
9900 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
10039 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
9901 | //////////////////// QCPScatterStyle |
|
10040 | //////////////////// QCPScatterStyle | |
@@ -10065,8 +10204,8 QCPScatterStyle::QCPScatterStyle(const QPixmap &pixmap) | |||||
10065 |
|
10204 | |||
10066 | The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly |
|
10205 | The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly | |
10067 | different meaning than for built-in scatter points: The custom path will be drawn scaled by a |
|
10206 | different meaning than for built-in scatter points: The custom path will be drawn scaled by a | |
10068 |
factor of \a size/6.0. Since the default \a size is 6, the custom path will appear |
|
10207 | factor of \a size/6.0. Since the default \a size is 6, the custom path will appear in its | |
10069 |
n |
|
10208 | original size by default. To for example double the size of the path, set \a size to 12. | |
10070 | */ |
|
10209 | */ | |
10071 | QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, |
|
10210 | QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, | |
10072 | const QBrush &brush, double size) |
|
10211 | const QBrush &brush, double size) | |
@@ -10253,10 +10392,9 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const | |||||
10253 | break; |
|
10392 | break; | |
10254 | } |
|
10393 | } | |
10255 | case ssDiamond: { |
|
10394 | case ssDiamond: { | |
10256 | painter->drawLine(QLineF(x - w, y, x, y - w)); |
|
10395 | QPointF lineArray[4] | |
10257 | painter->drawLine(QLineF(x, y - w, x + w, y)); |
|
10396 | = {QPointF(x - w, y), QPointF(x, y - w), QPointF(x + w, y), QPointF(x, y + w)}; | |
10258 |
painter->draw |
|
10397 | painter->drawPolygon(lineArray, 4); | |
10259 | painter->drawLine(QLineF(x, y + w, x - w, y)); |
|
|||
10260 | break; |
|
10398 | break; | |
10261 | } |
|
10399 | } | |
10262 | case ssStar: { |
|
10400 | case ssStar: { | |
@@ -10267,46 +10405,46 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const | |||||
10267 | break; |
|
10405 | break; | |
10268 | } |
|
10406 | } | |
10269 | case ssTriangle: { |
|
10407 | case ssTriangle: { | |
10270 |
|
|
10408 | QPointF lineArray[3] = {QPointF(x - w, y + 0.755 * w), QPointF(x + w, y + 0.755 * w), | |
10271 | painter->drawLine(QLineF(x + w, y + 0.755 * w, x, y - 0.977 * w)); |
|
10409 | QPointF(x, y - 0.977 * w)}; | |
10272 | painter->drawLine(QLineF(x, y - 0.977 * w, x - w, y + 0.755 * w)); |
|
10410 | painter->drawPolygon(lineArray, 3); | |
10273 | break; |
|
10411 | break; | |
10274 | } |
|
10412 | } | |
10275 | case ssTriangleInverted: { |
|
10413 | case ssTriangleInverted: { | |
10276 |
|
|
10414 | QPointF lineArray[3] = {QPointF(x - w, y - 0.755 * w), QPointF(x + w, y - 0.755 * w), | |
10277 | painter->drawLine(QLineF(x + w, y - 0.755 * w, x, y + 0.977 * w)); |
|
10415 | QPointF(x, y + 0.977 * w)}; | |
10278 | painter->drawLine(QLineF(x, y + 0.977 * w, x - w, y - 0.755 * w)); |
|
10416 | painter->drawPolygon(lineArray, 3); | |
10279 | break; |
|
10417 | break; | |
10280 | } |
|
10418 | } | |
10281 | case ssCrossSquare: { |
|
10419 | case ssCrossSquare: { | |
|
10420 | painter->drawRect(QRectF(x - w, y - w, mSize, mSize)); | |||
10282 | painter->drawLine(QLineF(x - w, y - w, x + w * 0.95, y + w * 0.95)); |
|
10421 | painter->drawLine(QLineF(x - w, y - w, x + w * 0.95, y + w * 0.95)); | |
10283 | painter->drawLine(QLineF(x - w, y + w * 0.95, x + w * 0.95, y - w)); |
|
10422 | painter->drawLine(QLineF(x - w, y + w * 0.95, x + w * 0.95, y - w)); | |
10284 | painter->drawRect(QRectF(x - w, y - w, mSize, mSize)); |
|
|||
10285 | break; |
|
10423 | break; | |
10286 | } |
|
10424 | } | |
10287 | case ssPlusSquare: { |
|
10425 | case ssPlusSquare: { | |
|
10426 | painter->drawRect(QRectF(x - w, y - w, mSize, mSize)); | |||
10288 | painter->drawLine(QLineF(x - w, y, x + w * 0.95, y)); |
|
10427 | painter->drawLine(QLineF(x - w, y, x + w * 0.95, y)); | |
10289 | painter->drawLine(QLineF(x, y + w, x, y - w)); |
|
10428 | painter->drawLine(QLineF(x, y + w, x, y - w)); | |
10290 | painter->drawRect(QRectF(x - w, y - w, mSize, mSize)); |
|
|||
10291 | break; |
|
10429 | break; | |
10292 | } |
|
10430 | } | |
10293 | case ssCrossCircle: { |
|
10431 | case ssCrossCircle: { | |
|
10432 | painter->drawEllipse(QPointF(x, y), w, w); | |||
10294 | painter->drawLine(QLineF(x - w * 0.707, y - w * 0.707, x + w * 0.670, y + w * 0.670)); |
|
10433 | painter->drawLine(QLineF(x - w * 0.707, y - w * 0.707, x + w * 0.670, y + w * 0.670)); | |
10295 | painter->drawLine(QLineF(x - w * 0.707, y + w * 0.670, x + w * 0.670, y - w * 0.707)); |
|
10434 | painter->drawLine(QLineF(x - w * 0.707, y + w * 0.670, x + w * 0.670, y - w * 0.707)); | |
10296 | painter->drawEllipse(QPointF(x, y), w, w); |
|
|||
10297 | break; |
|
10435 | break; | |
10298 | } |
|
10436 | } | |
10299 | case ssPlusCircle: { |
|
10437 | case ssPlusCircle: { | |
|
10438 | painter->drawEllipse(QPointF(x, y), w, w); | |||
10300 | painter->drawLine(QLineF(x - w, y, x + w, y)); |
|
10439 | painter->drawLine(QLineF(x - w, y, x + w, y)); | |
10301 | painter->drawLine(QLineF(x, y + w, x, y - w)); |
|
10440 | painter->drawLine(QLineF(x, y + w, x, y - w)); | |
10302 | painter->drawEllipse(QPointF(x, y), w, w); |
|
|||
10303 | break; |
|
10441 | break; | |
10304 | } |
|
10442 | } | |
10305 | case ssPeace: { |
|
10443 | case ssPeace: { | |
|
10444 | painter->drawEllipse(QPointF(x, y), w, w); | |||
10306 | painter->drawLine(QLineF(x, y - w, x, y + w)); |
|
10445 | painter->drawLine(QLineF(x, y - w, x, y + w)); | |
10307 | painter->drawLine(QLineF(x, y, x - w * 0.707, y + w * 0.707)); |
|
10446 | painter->drawLine(QLineF(x, y, x - w * 0.707, y + w * 0.707)); | |
10308 | painter->drawLine(QLineF(x, y, x + w * 0.707, y + w * 0.707)); |
|
10447 | painter->drawLine(QLineF(x, y, x + w * 0.707, y + w * 0.707)); | |
10309 | painter->drawEllipse(QPointF(x, y), w, w); |
|
|||
10310 | break; |
|
10448 | break; | |
10311 | } |
|
10449 | } | |
10312 | case ssPixmap: { |
|
10450 | case ssPixmap: { | |
@@ -10337,8 +10475,8 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const | |||||
10337 |
|
10475 | |||
10338 | // amalgamation: add datacontainer.cpp |
|
10476 | // amalgamation: add datacontainer.cpp | |
10339 |
|
10477 | |||
10340 |
/* including file 'src/plottable.cpp', size 388 |
|
10478 | /* including file 'src/plottable.cpp', size 38845 */ | |
10341 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
10479 | /* commit b0bed12626f942821097f43091126b6fb7163122 2017-08-13 17:17:33 +0200 */ | |
10342 |
|
10480 | |||
10343 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
10481 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
10344 | //////////////////// QCPSelectionDecorator |
|
10482 | //////////////////// QCPSelectionDecorator | |
@@ -10376,8 +10514,8 void QCPScatterStyle::drawShape(QCPPainter *painter, double x, double y) const | |||||
10376 | QCPSelectionDecorator::QCPSelectionDecorator() |
|
10514 | QCPSelectionDecorator::QCPSelectionDecorator() | |
10377 | : mPen(QColor(80, 80, 255), 2.5), |
|
10515 | : mPen(QColor(80, 80, 255), 2.5), | |
10378 | mBrush(Qt::NoBrush), |
|
10516 | mBrush(Qt::NoBrush), | |
10379 | mScatterStyle(QCPScatterStyle::ssNone, QPen(Qt::blue, 2), Qt::NoBrush, 6.0), |
|
10517 | mScatterStyle(), | |
10380 |
mUsedScatterProperties(QCPScatterStyle::sp |
|
10518 | mUsedScatterProperties(QCPScatterStyle::spNone), | |
10381 | mPlottable(0) |
|
10519 | mPlottable(0) | |
10382 | { |
|
10520 | { | |
10383 | } |
|
10521 | } | |
@@ -10420,6 +10558,8 void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, | |||||
10420 | Use this method to define which properties of the scatter style (set via \ref setScatterStyle) |
|
10558 | Use this method to define which properties of the scatter style (set via \ref setScatterStyle) | |
10421 | will be used for selected data segments. All properties of the scatter style that are not |
|
10559 | will be used for selected data segments. All properties of the scatter style that are not | |
10422 | specified in \a properties will remain as specified in the plottable's original scatter style. |
|
10560 | specified in \a properties will remain as specified in the plottable's original scatter style. | |
|
10561 | ||||
|
10562 | \see QCPScatterStyle::ScatterProperty | |||
10423 | */ |
|
10563 | */ | |
10424 | void QCPSelectionDecorator::setUsedScatterProperties( |
|
10564 | void QCPSelectionDecorator::setUsedScatterProperties( | |
10425 | const QCPScatterStyle::ScatterProperties &properties) |
|
10565 | const QCPScatterStyle::ScatterProperties &properties) | |
@@ -12624,8 +12764,8 QCP::Interaction QCPAbstractItem::selectionCategory() const | |||||
12624 | /* end of 'src/item.cpp' */ |
|
12764 | /* end of 'src/item.cpp' */ | |
12625 |
|
12765 | |||
12626 |
|
12766 | |||
12627 |
/* including file 'src/core.cpp', size 12 |
|
12767 | /* including file 'src/core.cpp', size 125027 */ | |
12628 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
12768 | /* commit 9ede7553208db59867d1ea9f1988cd90e3c7ffed 2017-08-13 17:25:24 +0200 */ | |
12629 |
|
12769 | |||
12630 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
12770 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
12631 | //////////////////// QCustomPlot |
|
12771 | //////////////////// QCustomPlot | |
@@ -12969,6 +13109,7 QCustomPlot::QCustomPlot(QWidget *parent) | |||||
12969 | mOpenGl(false), |
|
13109 | mOpenGl(false), | |
12970 | mMouseHasMoved(false), |
|
13110 | mMouseHasMoved(false), | |
12971 | mMouseEventLayerable(0), |
|
13111 | mMouseEventLayerable(0), | |
|
13112 | mMouseSignalLayerable(0), | |||
12972 | mReplotting(false), |
|
13113 | mReplotting(false), | |
12973 | mReplotQueued(false), |
|
13114 | mReplotQueued(false), | |
12974 | mOpenGlMultisamples(16), |
|
13115 | mOpenGlMultisamples(16), | |
@@ -12983,8 +13124,12 QCustomPlot::QCustomPlot(QWidget *parent) | |||||
12983 | currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); |
|
13124 | currentLocale.setNumberOptions(QLocale::OmitGroupSeparator); | |
12984 | setLocale(currentLocale); |
|
13125 | setLocale(currentLocale); | |
12985 | #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED |
|
13126 | #ifdef QCP_DEVICEPIXELRATIO_SUPPORTED | |
|
13127 | #ifdef QCP_DEVICEPIXELRATIO_FLOAT | |||
|
13128 | setBufferDevicePixelRatio(QWidget::devicePixelRatioF()); | |||
|
13129 | #else | |||
12986 | setBufferDevicePixelRatio(QWidget::devicePixelRatio()); |
|
13130 | setBufferDevicePixelRatio(QWidget::devicePixelRatio()); | |
12987 | #endif |
|
13131 | #endif | |
|
13132 | #endif | |||
12988 |
|
13133 | |||
12989 | mOpenGlAntialiasedElementsBackup = mAntialiasedElements; |
|
13134 | mOpenGlAntialiasedElementsBackup = mAntialiasedElements; | |
12990 | mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); |
|
13135 | mOpenGlCacheLabelsBackup = mPlottingHints.testFlag(QCP::phCacheLabels); | |
@@ -13386,6 +13531,10 void QCustomPlot::setSelectionRect(QCPSelectionRect *selectionRect) | |||||
13386 | } |
|
13531 | } | |
13387 |
|
13532 | |||
13388 | /*! |
|
13533 | /*! | |
|
13534 | \warning This is still an experimental feature and its performance depends on the system that it | |||
|
13535 | runs on. Having multiple QCustomPlot widgets in one application with enabled OpenGL rendering | |||
|
13536 | might cause context conflicts on some systems. | |||
|
13537 | ||||
13389 | This method allows to enable OpenGL plot rendering, for increased plotting performance of |
|
13538 | This method allows to enable OpenGL plot rendering, for increased plotting performance of | |
13390 | graphically demanding plots (thick lines, translucent fills, etc.). |
|
13539 | graphically demanding plots (thick lines, translucent fills, etc.). | |
13391 |
|
13540 | |||
@@ -14934,12 +15083,20 void QCustomPlot::mousePressEvent(QMouseEvent *event) | |||||
14934 | mSelectionRect->startSelection(event); |
|
15083 | mSelectionRect->startSelection(event); | |
14935 | } |
|
15084 | } | |
14936 | else { |
|
15085 | else { | |
14937 |
// no selection rect interaction, so forward event to |
|
15086 | // no selection rect interaction, prepare for click signal emission and forward event to | |
|
15087 | // layerable under the cursor: | |||
14938 | QList<QVariant> details; |
|
15088 | QList<QVariant> details; | |
14939 | QList<QCPLayerable *> candidates = layerableListAt(mMousePressPos, false, &details); |
|
15089 | QList<QCPLayerable *> candidates = layerableListAt(mMousePressPos, false, &details); | |
|
15090 | if (!candidates.isEmpty()) { | |||
|
15091 | mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always | |||
|
15092 | // topmost hit layerable (signal emitted in | |||
|
15093 | // release event) | |||
|
15094 | mMouseSignalLayerableDetails = details.first(); | |||
|
15095 | } | |||
|
15096 | // forward event to topmost candidate which accepts the event: | |||
14940 | for (int i = 0; i < candidates.size(); ++i) { |
|
15097 | for (int i = 0; i < candidates.size(); ++i) { | |
14941 |
event->accept(); // default impl of QCPLayerable's mouse events ignore the |
|
15098 | event->accept(); // default impl of QCPLayerable's mouse events call ignore() on the | |
14942 | // that case propagate to next candidate in list |
|
15099 | // event, in that case propagate to next candidate in list | |
14943 | candidates.at(i)->mousePressEvent(event, details.at(i)); |
|
15100 | candidates.at(i)->mousePressEvent(event, details.at(i)); | |
14944 | if (event->isAccepted()) { |
|
15101 | if (event->isAccepted()) { | |
14945 | mMouseEventLayerable = candidates.at(i); |
|
15102 | mMouseEventLayerable = candidates.at(i); | |
@@ -15010,22 +15167,25 void QCustomPlot::mouseReleaseEvent(QMouseEvent *event) | |||||
15010 | processPointSelection(event); |
|
15167 | processPointSelection(event); | |
15011 |
|
15168 | |||
15012 | // emit specialized click signals of QCustomPlot instance: |
|
15169 | // emit specialized click signals of QCustomPlot instance: | |
15013 | if (QCPAbstractPlottable *ap = qobject_cast<QCPAbstractPlottable *>(mMouseEventLayerable)) { |
|
15170 | if (QCPAbstractPlottable *ap | |
|
15171 | = qobject_cast<QCPAbstractPlottable *>(mMouseSignalLayerable)) { | |||
15014 | int dataIndex = 0; |
|
15172 | int dataIndex = 0; | |
15015 |
if (!mMouse |
|
15173 | if (!mMouseSignalLayerableDetails.value<QCPDataSelection>().isEmpty()) | |
15016 | dataIndex |
|
15174 | dataIndex | |
15017 |
= mMouse |
|
15175 | = mMouseSignalLayerableDetails.value<QCPDataSelection>().dataRange().begin(); | |
15018 | emit plottableClick(ap, dataIndex, event); |
|
15176 | emit plottableClick(ap, dataIndex, event); | |
15019 | } |
|
15177 | } | |
15020 |
else if (QCPAxis *ax = qobject_cast<QCPAxis *>(mMouse |
|
15178 | else if (QCPAxis *ax = qobject_cast<QCPAxis *>(mMouseSignalLayerable)) | |
15021 |
emit axisClick(ax, mMouse |
|
15179 | emit axisClick(ax, mMouseSignalLayerableDetails.value<QCPAxis::SelectablePart>(), | |
15022 | else if (QCPAbstractItem *ai = qobject_cast<QCPAbstractItem *>(mMouseEventLayerable)) |
|
15180 | event); | |
|
15181 | else if (QCPAbstractItem *ai = qobject_cast<QCPAbstractItem *>(mMouseSignalLayerable)) | |||
15023 | emit itemClick(ai, event); |
|
15182 | emit itemClick(ai, event); | |
15024 |
else if (QCPLegend *lg = qobject_cast<QCPLegend *>(mMouse |
|
15183 | else if (QCPLegend *lg = qobject_cast<QCPLegend *>(mMouseSignalLayerable)) | |
15025 | emit legendClick(lg, 0, event); |
|
15184 | emit legendClick(lg, 0, event); | |
15026 | else if (QCPAbstractLegendItem *li |
|
15185 | else if (QCPAbstractLegendItem *li | |
15027 |
= qobject_cast<QCPAbstractLegendItem *>(mMouse |
|
15186 | = qobject_cast<QCPAbstractLegendItem *>(mMouseSignalLayerable)) | |
15028 | emit legendClick(li->parentLegend(), li, event); |
|
15187 | emit legendClick(li->parentLegend(), li, event); | |
|
15188 | mMouseSignalLayerable = 0; | |||
15029 | } |
|
15189 | } | |
15030 |
|
15190 | |||
15031 | if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the |
|
15191 | if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the | |
@@ -16469,8 +16629,9 void QCPColorGradient::updateColorBuffer() | |||||
16469 | hue -= 1.0; |
|
16629 | hue -= 1.0; | |
16470 | if (useAlpha) { |
|
16630 | if (useAlpha) { | |
16471 | const QRgb rgb |
|
16631 | const QRgb rgb | |
16472 |
= QColor::fromHsvF(hue, |
|
16632 | = QColor::fromHsvF(hue, | |
16473 |
|
|
16633 | (1 - t) * lowHsv.saturationF() | |
|
16634 | + t * highHsv.saturationF(), | |||
16474 | (1 - t) * lowHsv.valueF() + t * highHsv.valueF()) |
|
16635 | (1 - t) * lowHsv.valueF() + t * highHsv.valueF()) | |
16475 | .rgb(); |
|
16636 | .rgb(); | |
16476 | const float alpha = (1 - t) * lowHsv.alphaF() + t * highHsv.alphaF(); |
|
16637 | const float alpha = (1 - t) * lowHsv.alphaF() + t * highHsv.alphaF(); | |
@@ -16479,8 +16640,9 void QCPColorGradient::updateColorBuffer() | |||||
16479 | } |
|
16640 | } | |
16480 | else { |
|
16641 | else { | |
16481 | mColorBuffer[i] |
|
16642 | mColorBuffer[i] | |
16482 |
= QColor::fromHsvF(hue, |
|
16643 | = QColor::fromHsvF(hue, | |
16483 |
|
|
16644 | (1 - t) * lowHsv.saturationF() | |
|
16645 | + t * highHsv.saturationF(), | |||
16484 | (1 - t) * lowHsv.valueF() + t * highHsv.valueF()) |
|
16646 | (1 - t) * lowHsv.valueF() + t * highHsv.valueF()) | |
16485 | .rgb(); |
|
16647 | .rgb(); | |
16486 | } |
|
16648 | } | |
@@ -16797,8 +16959,8 QCPSelectionDecoratorBracket::getPixelCoordinates(const QCPPlottableInterface1D | |||||
16797 | /* end of 'src/selectiondecorator-bracket.cpp' */ |
|
16959 | /* end of 'src/selectiondecorator-bracket.cpp' */ | |
16798 |
|
16960 | |||
16799 |
|
16961 | |||
16800 |
/* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 475 |
|
16962 | /* including file 'src/layoutelements/layoutelement-axisrect.cpp', size 47584 */ | |
16801 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
16963 | /* commit 77ba168312f935543fc31d1ae9b4cdcf34aae4f9 2017-08-13 18:29:48 +0200 */ | |
16802 |
|
16964 | |||
16803 |
|
16965 | |||
16804 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
16966 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
@@ -17052,7 +17214,7 QList<QCPAxis *> QCPAxisRect::axes() const | |||||
17052 | new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to |
|
17214 | new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to | |
17053 | remove an axis, use \ref removeAxis instead of deleting it manually. |
|
17215 | remove an axis, use \ref removeAxis instead of deleting it manually. | |
17054 |
|
17216 | |||
17055 | You may inject QCPAxis instances (or sublasses of QCPAxis) by setting \a axis to an axis that was |
|
17217 | You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was | |
17056 | previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership |
|
17218 | previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership | |
17057 | of the axis, so you may not delete it afterwards. Further, the \a axis must have been created |
|
17219 | of the axis, so you may not delete it afterwards. Further, the \a axis must have been created | |
17058 | with this axis rect as parent and with the same axis type as specified in \a type. If this is not |
|
17220 | with this axis rect as parent and with the same axis type as specified in \a type. If this is not | |
@@ -17165,6 +17327,12 bool QCPAxisRect::removeAxis(QCPAxis *axis) | |||||
17165 | while (it.hasNext()) { |
|
17327 | while (it.hasNext()) { | |
17166 | it.next(); |
|
17328 | it.next(); | |
17167 | if (it.value().contains(axis)) { |
|
17329 | if (it.value().contains(axis)) { | |
|
17330 | if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, | |||
|
17331 | // transfer axis offset to the | |||
|
17332 | // new first axis (which at | |||
|
17333 | // this point is the second | |||
|
17334 | // axis, if it exists) | |||
|
17335 | it.value()[1]->setOffset(axis->offset()); | |||
17168 | mAxes[it.key()].removeOne(axis); |
|
17336 | mAxes[it.key()].removeOne(axis); | |
17169 | if (qobject_cast<QCustomPlot *>(parentPlot())) // make sure this isn't called from |
|
17337 | if (qobject_cast<QCustomPlot *>(parentPlot())) // make sure this isn't called from | |
17170 | // QObject dtor when QCustomPlot is |
|
17338 | // QObject dtor when QCustomPlot is | |
@@ -17934,9 +18102,6 void QCPAxisRect::layoutChanged() | |||||
17934 | void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) |
|
18102 | void QCPAxisRect::mousePressEvent(QMouseEvent *event, const QVariant &details) | |
17935 | { |
|
18103 | { | |
17936 | Q_UNUSED(details) |
|
18104 | Q_UNUSED(details) | |
17937 | mDragStart = event->pos(); // need this even when not LeftButton is pressed, to determine in |
|
|||
17938 | // releaseEvent whether it was a full click (no position change |
|
|||
17939 | // between press and release) |
|
|||
17940 | if (event->buttons() & Qt::LeftButton) { |
|
18105 | if (event->buttons() & Qt::LeftButton) { | |
17941 | mDragging = true; |
|
18106 | mDragging = true; | |
17942 | // initialize antialiasing backup in case we start dragging: |
|
18107 | // initialize antialiasing backup in case we start dragging: | |
@@ -17982,13 +18147,13 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) | |||||
17982 | break; |
|
18147 | break; | |
17983 | if (ax->mScaleType == QCPAxis::stLinear) { |
|
18148 | if (ax->mScaleType == QCPAxis::stLinear) { | |
17984 | double diff |
|
18149 | double diff | |
17985 |
= ax->pixelToCoord( |
|
18150 | = ax->pixelToCoord(startPos.x()) - ax->pixelToCoord(event->pos().x()); | |
17986 | ax->setRange(mDragStartHorzRange.at(i).lower + diff, |
|
18151 | ax->setRange(mDragStartHorzRange.at(i).lower + diff, | |
17987 | mDragStartHorzRange.at(i).upper + diff); |
|
18152 | mDragStartHorzRange.at(i).upper + diff); | |
17988 | } |
|
18153 | } | |
17989 | else if (ax->mScaleType == QCPAxis::stLogarithmic) { |
|
18154 | else if (ax->mScaleType == QCPAxis::stLogarithmic) { | |
17990 | double diff |
|
18155 | double diff | |
17991 |
= ax->pixelToCoord( |
|
18156 | = ax->pixelToCoord(startPos.x()) / ax->pixelToCoord(event->pos().x()); | |
17992 | ax->setRange(mDragStartHorzRange.at(i).lower * diff, |
|
18157 | ax->setRange(mDragStartHorzRange.at(i).lower * diff, | |
17993 | mDragStartHorzRange.at(i).upper * diff); |
|
18158 | mDragStartHorzRange.at(i).upper * diff); | |
17994 | } |
|
18159 | } | |
@@ -18004,13 +18169,13 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) | |||||
18004 | break; |
|
18169 | break; | |
18005 | if (ax->mScaleType == QCPAxis::stLinear) { |
|
18170 | if (ax->mScaleType == QCPAxis::stLinear) { | |
18006 | double diff |
|
18171 | double diff | |
18007 |
= ax->pixelToCoord( |
|
18172 | = ax->pixelToCoord(startPos.y()) - ax->pixelToCoord(event->pos().y()); | |
18008 | ax->setRange(mDragStartVertRange.at(i).lower + diff, |
|
18173 | ax->setRange(mDragStartVertRange.at(i).lower + diff, | |
18009 | mDragStartVertRange.at(i).upper + diff); |
|
18174 | mDragStartVertRange.at(i).upper + diff); | |
18010 | } |
|
18175 | } | |
18011 | else if (ax->mScaleType == QCPAxis::stLogarithmic) { |
|
18176 | else if (ax->mScaleType == QCPAxis::stLogarithmic) { | |
18012 | double diff |
|
18177 | double diff | |
18013 |
= ax->pixelToCoord( |
|
18178 | = ax->pixelToCoord(startPos.y()) / ax->pixelToCoord(event->pos().y()); | |
18014 | ax->setRange(mDragStartVertRange.at(i).lower * diff, |
|
18179 | ax->setRange(mDragStartVertRange.at(i).lower * diff, | |
18015 | mDragStartVertRange.at(i).upper * diff); |
|
18180 | mDragStartVertRange.at(i).upper * diff); | |
18016 | } |
|
18181 | } | |
@@ -18021,7 +18186,7 void QCPAxisRect::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) | |||||
18021 | { |
|
18186 | { | |
18022 | if (mParentPlot->noAntialiasingOnDrag()) |
|
18187 | if (mParentPlot->noAntialiasingOnDrag()) | |
18023 | mParentPlot->setNotAntialiasedElements(QCP::aeAll); |
|
18188 | mParentPlot->setNotAntialiasedElements(QCP::aeAll); | |
18024 | mParentPlot->replot(); |
|
18189 | mParentPlot->replot(QCustomPlot::rpQueuedReplot); | |
18025 | } |
|
18190 | } | |
18026 | } |
|
18191 | } | |
18027 | } |
|
18192 | } | |
@@ -18082,8 +18247,8 void QCPAxisRect::wheelEvent(QWheelEvent *event) | |||||
18082 | /* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ |
|
18247 | /* end of 'src/layoutelements/layoutelement-axisrect.cpp' */ | |
18083 |
|
18248 | |||
18084 |
|
18249 | |||
18085 |
/* including file 'src/layoutelements/layoutelement-legend.cpp', size 309 |
|
18250 | /* including file 'src/layoutelements/layoutelement-legend.cpp', size 30971 */ | |
18086 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
18251 | /* commit 305808813c9c6451dca8399c2fc66d68ebd24b5e 2017-08-15 23:03:07 +0200 */ | |
18087 |
|
18252 | |||
18088 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
18253 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
18089 | //////////////////// QCPAbstractLegendItem |
|
18254 | //////////////////// QCPAbstractLegendItem | |
@@ -18286,9 +18451,7 void QCPAbstractLegendItem::deselectEvent(bool *selectionStateChanged) | |||||
18286 | QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. |
|
18451 | QCPLegend::setIconBorderPen and \ref QCPLegend::setIconTextPadding. | |
18287 |
|
18452 | |||
18288 | The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend |
|
18453 | The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend | |
18289 |
creates/removes legend items of this type |
|
18454 | creates/removes legend items of this type. | |
18290 | may be reimplemented such that a different kind of legend item (e.g a direct subclass of |
|
|||
18291 | QCPAbstractLegendItem) is used for that plottable. |
|
|||
18292 |
|
18455 | |||
18293 | Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of |
|
18456 | Since QCPLegend is based on QCPLayoutGrid, a legend item itself is just a subclass of | |
18294 | QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout |
|
18457 | QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout | |
@@ -18395,10 +18558,8 QSize QCPPlottableLegendItem::minimumSizeHint() const | |||||
18395 | QSize iconSize = mParentLegend->iconSize(); |
|
18558 | QSize iconSize = mParentLegend->iconSize(); | |
18396 | textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, |
|
18559 | textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, | |
18397 | mPlottable->name()); |
|
18560 | mPlottable->name()); | |
18398 | result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width() |
|
18561 | result.setWidth(iconSize.width() + mParentLegend->iconTextPadding() + textRect.width()); | |
18399 | + mMargins.left() + mMargins.right()); |
|
18562 | result.setHeight(qMax(textRect.height(), iconSize.height())); | |
18400 | result.setHeight(qMax(textRect.height(), iconSize.height()) + mMargins.top() |
|
|||
18401 | + mMargins.bottom()); |
|
|||
18402 | return result; |
|
18563 | return result; | |
18403 | } |
|
18564 | } | |
18404 |
|
18565 | |||
@@ -18412,10 +18573,14 QSize QCPPlottableLegendItem::minimumSizeHint() const | |||||
18412 |
|
18573 | |||
18413 | A legend is a small box somewhere in the plot which lists plottables with their name and icon. |
|
18574 | A legend is a small box somewhere in the plot which lists plottables with their name and icon. | |
18414 |
|
18575 | |||
18415 |
|
|
18576 | A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the | |
18416 | respective legend item can be removed with \ref QCPAbstractPlottable::removeFromLegend. However, |
|
18577 | plottable, for which a legend item shall be created. In the case of the main legend (\ref | |
18417 | QCPLegend also offers an interface to add and manipulate legend items directly: \ref item, \ref |
|
18578 | QCustomPlot::legend), simply adding plottables to the plot while \ref | |
18418 | itemWithPlottable, \ref itemCount, \ref addItem, \ref removeItem, etc. |
|
18579 | QCustomPlot::setAutoAddPlottableToLegend is set to true (the default) creates corresponding | |
|
18580 | legend items. The legend item associated with a certain plottable can be removed with \ref | |||
|
18581 | QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and | |||
|
18582 | manipulate legend items directly: \ref item, \ref itemWithPlottable, \ref itemCount, \ref | |||
|
18583 | addItem, \ref removeItem, etc. | |||
18419 |
|
18584 | |||
18420 | Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref |
|
18585 | Since \ref QCPLegend derives from \ref QCPLayoutGrid, it can be placed in any position a \ref | |
18421 | QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement |
|
18586 | QCPLayoutElement may be positioned. The legend items are themselves \ref QCPLayoutElement | |
@@ -18570,7 +18735,7 void QCPLegend::setIconSize(const QSize &size) | |||||
18570 | } |
|
18735 | } | |
18571 |
|
18736 | |||
18572 | /*! \overload |
|
18737 | /*! \overload | |
18573 |
|
|
18738 | */ | |
18574 | void QCPLegend::setIconSize(int width, int height) |
|
18739 | void QCPLegend::setIconSize(int width, int height) | |
18575 | { |
|
18740 | { | |
18576 | mIconSize.setWidth(width); |
|
18741 | mIconSize.setWidth(width); | |
@@ -19012,8 +19177,8 void QCPLegend::parentPlotInitialized(QCustomPlot *parentPlot) | |||||
19012 | /* end of 'src/layoutelements/layoutelement-legend.cpp' */ |
|
19177 | /* end of 'src/layoutelements/layoutelement-legend.cpp' */ | |
19013 |
|
19178 | |||
19014 |
|
19179 | |||
19015 |
/* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12 |
|
19180 | /* including file 'src/layoutelements/layoutelement-textelement.cpp', size 12561 */ | |
19016 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
19181 | /* commit a872eb91ec087561efd83dd9cb041a26ab95ce55 2017-07-31 00:21:41 +0200 */ | |
19017 |
|
19182 | |||
19018 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
19183 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
19019 | //////////////////// QCPTextElement |
|
19184 | //////////////////// QCPTextElement | |
@@ -19299,10 +19464,7 void QCPTextElement::draw(QCPPainter *painter) | |||||
19299 | QSize QCPTextElement::minimumSizeHint() const |
|
19464 | QSize QCPTextElement::minimumSizeHint() const | |
19300 | { |
|
19465 | { | |
19301 | QFontMetrics metrics(mFont); |
|
19466 | QFontMetrics metrics(mFont); | |
19302 |
|
|
19467 | return metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size(); | |
19303 | result.rwidth() += mMargins.left() + mMargins.right(); |
|
|||
19304 | result.rheight() += mMargins.top() + mMargins.bottom(); |
|
|||
19305 | return result; |
|
|||
19306 | } |
|
19468 | } | |
19307 |
|
19469 | |||
19308 | /* inherits documentation from base class */ |
|
19470 | /* inherits documentation from base class */ | |
@@ -19310,7 +19472,6 QSize QCPTextElement::maximumSizeHint() const | |||||
19310 | { |
|
19472 | { | |
19311 | QFontMetrics metrics(mFont); |
|
19473 | QFontMetrics metrics(mFont); | |
19312 | QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size(); |
|
19474 | QSize result = metrics.boundingRect(0, 0, 0, 0, Qt::AlignCenter, mText).size(); | |
19313 | result.rheight() += mMargins.top() + mMargins.bottom(); |
|
|||
19314 | result.setWidth(QWIDGETSIZE_MAX); |
|
19475 | result.setWidth(QWIDGETSIZE_MAX); | |
19315 | return result; |
|
19476 | return result; | |
19316 | } |
|
19477 | } | |
@@ -19838,12 +19999,14 void QCPColorScale::update(UpdatePhase phase) | |||||
19838 | switch (phase) { |
|
19999 | switch (phase) { | |
19839 | case upMargins: { |
|
20000 | case upMargins: { | |
19840 | if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) { |
|
20001 | if (mType == QCPAxis::atBottom || mType == QCPAxis::atTop) { | |
19841 |
setMaximumSize(QWIDGETSIZE_MAX, |
|
20002 | setMaximumSize(QWIDGETSIZE_MAX, | |
19842 |
|
|
20003 | mBarWidth + mAxisRect.data()->margins().top() | |
19843 |
|
|
20004 | + mAxisRect.data()->margins().bottom() + margins().top() | |
19844 | setMinimumSize(0, mBarWidth + mAxisRect.data()->margins().top() |
|
20005 | + margins().bottom()); | |
19845 | + mAxisRect.data()->margins().bottom() + margins().top() |
|
20006 | setMinimumSize(0, | |
19846 |
|
|
20007 | mBarWidth + mAxisRect.data()->margins().top() | |
|
20008 | + mAxisRect.data()->margins().bottom() + margins().top() | |||
|
20009 | + margins().bottom()); | |||
19847 | } |
|
20010 | } | |
19848 | else { |
|
20011 | else { | |
19849 | setMaximumSize(mBarWidth + mAxisRect.data()->margins().left() |
|
20012 | setMaximumSize(mBarWidth + mAxisRect.data()->margins().left() | |
@@ -20100,8 +20263,8 void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectablePart | |||||
20100 | /* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ |
|
20263 | /* end of 'src/layoutelements/layoutelement-colorscale.cpp' */ | |
20101 |
|
20264 | |||
20102 |
|
20265 | |||
20103 |
/* including file 'src/plottables/plottable-graph.cpp', size 7 |
|
20266 | /* including file 'src/plottables/plottable-graph.cpp', size 73960 */ | |
20104 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
20267 | /* commit 7e7381ef4f218e004d72a218820634fff0959d1b 2017-08-02 00:02:36 +0200 */ | |
20105 |
|
20268 | |||
20106 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
20269 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
20107 | //////////////////// QCPGraphData |
|
20270 | //////////////////// QCPGraphData | |
@@ -20649,6 +20812,12 void QCPGraph::getLines(QVector<QPointF> *lines, const QCPDataRange &dataRange) | |||||
20649 | if (mLineStyle != lsNone) |
|
20812 | if (mLineStyle != lsNone) | |
20650 | getOptimizedLineData(&lineData, begin, end); |
|
20813 | getOptimizedLineData(&lineData, begin, end); | |
20651 |
|
20814 | |||
|
20815 | if (mKeyAxis->rangeReversed() | |||
|
20816 | != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending | |||
|
20817 | // in lineData (significantly simplifies | |||
|
20818 | // following processing) | |||
|
20819 | std::reverse(lineData.begin(), lineData.end()); | |||
|
20820 | ||||
20652 | switch (mLineStyle) { |
|
20821 | switch (mLineStyle) { | |
20653 | case lsNone: |
|
20822 | case lsNone: | |
20654 | lines->clear(); |
|
20823 | lines->clear(); | |
@@ -20704,6 +20873,13 void QCPGraph::getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataR | |||||
20704 |
|
20873 | |||
20705 | QVector<QCPGraphData> data; |
|
20874 | QVector<QCPGraphData> data; | |
20706 | getOptimizedScatterData(&data, begin, end); |
|
20875 | getOptimizedScatterData(&data, begin, end); | |
|
20876 | ||||
|
20877 | if (mKeyAxis->rangeReversed() | |||
|
20878 | != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending | |||
|
20879 | // in data (significantly simplifies following | |||
|
20880 | // processing) | |||
|
20881 | std::reverse(data.begin(), data.end()); | |||
|
20882 | ||||
20707 | scatters->resize(data.size()); |
|
20883 | scatters->resize(data.size()); | |
20708 | if (keyAxis->orientation() == Qt::Vertical) { |
|
20884 | if (keyAxis->orientation() == Qt::Vertical) { | |
20709 | for (int i = 0; i < data.size(); ++i) { |
|
20885 | for (int i = 0; i < data.size(); ++i) { | |
@@ -20744,8 +20920,6 QVector<QPointF> QCPGraph::dataToLines(const QVector<QCPGraphData> &data) const | |||||
20744 | return result; |
|
20920 | return result; | |
20745 | } |
|
20921 | } | |
20746 |
|
20922 | |||
20747 | result.reserve(data.size() + 2); // added 2 to reserve memory for lower/upper fill base points |
|
|||
20748 | // that might be needed for fill |
|
|||
20749 | result.resize(data.size()); |
|
20923 | result.resize(data.size()); | |
20750 |
|
20924 | |||
20751 | // transform data points to pixels: |
|
20925 | // transform data points to pixels: | |
@@ -20786,8 +20960,6 QVector<QPointF> QCPGraph::dataToStepLeftLines(const QVector<QCPGraphData> &data | |||||
20786 | return result; |
|
20960 | return result; | |
20787 | } |
|
20961 | } | |
20788 |
|
20962 | |||
20789 | result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base |
|
|||
20790 | // points that might be needed for fill |
|
|||
20791 | result.resize(data.size() * 2); |
|
20963 | result.resize(data.size() * 2); | |
20792 |
|
20964 | |||
20793 | // calculate steps from data and transform to pixel coordinates: |
|
20965 | // calculate steps from data and transform to pixel coordinates: | |
@@ -20838,8 +21010,6 QVector<QPointF> QCPGraph::dataToStepRightLines(const QVector<QCPGraphData> &dat | |||||
20838 | return result; |
|
21010 | return result; | |
20839 | } |
|
21011 | } | |
20840 |
|
21012 | |||
20841 | result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base |
|
|||
20842 | // points that might be needed for fill |
|
|||
20843 | result.resize(data.size() * 2); |
|
21013 | result.resize(data.size() * 2); | |
20844 |
|
21014 | |||
20845 | // calculate steps from data and transform to pixel coordinates: |
|
21015 | // calculate steps from data and transform to pixel coordinates: | |
@@ -20890,8 +21060,6 QVector<QPointF> QCPGraph::dataToStepCenterLines(const QVector<QCPGraphData> &da | |||||
20890 | return result; |
|
21060 | return result; | |
20891 | } |
|
21061 | } | |
20892 |
|
21062 | |||
20893 | result.reserve(data.size() * 2 + 2); // added 2 to reserve memory for lower/upper fill base |
|
|||
20894 | // points that might be needed for fill |
|
|||
20895 | result.resize(data.size() * 2); |
|
21063 | result.resize(data.size() * 2); | |
20896 |
|
21064 | |||
20897 | // calculate steps from data and transform to pixel coordinates: |
|
21065 | // calculate steps from data and transform to pixel coordinates: | |
@@ -20954,8 +21122,7 QVector<QPointF> QCPGraph::dataToImpulseLines(const QVector<QCPGraphData> &data) | |||||
20954 | return result; |
|
21122 | return result; | |
20955 | } |
|
21123 | } | |
20956 |
|
21124 | |||
20957 | result.resize(data.size() |
|
21125 | result.resize(data.size() * 2); | |
20958 | * 2); // no need to reserve 2 extra points because impulse plot has no fill |
|
|||
20959 |
|
21126 | |||
20960 | // transform data points to pixels: |
|
21127 | // transform data points to pixels: | |
20961 | if (keyAxis->orientation() == Qt::Vertical) { |
|
21128 | if (keyAxis->orientation() == Qt::Vertical) { | |
@@ -20984,15 +21151,16 QVector<QPointF> QCPGraph::dataToImpulseLines(const QVector<QCPGraphData> &data) | |||||
20984 |
|
21151 | |||
20985 | Draws the fill of the graph using the specified \a painter, with the currently set brush. |
|
21152 | Draws the fill of the graph using the specified \a painter, with the currently set brush. | |
20986 |
|
21153 | |||
20987 | \a lines contains the points of the graph line, in pixel coordinates. |
|
21154 | Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref | |
|
21155 | getFillPolygon or \ref getChannelFillPolygon are used to find the according fill polygons. | |||
20988 |
|
21156 | |||
20989 | If the fill is a normal fill towards the zero-value-line, only the points in \a lines are |
|
21157 | In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas), | |
20990 | required and two extra points at the zero-value-line, which are added by \ref addFillBasePoints |
|
21158 | this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to | |
20991 | and removed by \ref removeFillBasePoints after the fill drawing is done. |
|
21159 | operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN | |
|
21160 | segments of the two involved graphs, before passing the overlapping pairs to \ref | |||
|
21161 | getChannelFillPolygon. | |||
20992 |
|
21162 | |||
20993 | On the other hand if the fill is a channel fill between this QCPGraph and another QCPGraph (\a |
|
21163 | Pass the points of this graph's line as \a lines, in pixel coordinates. | |
20994 | mChannelFillGraph), the more complex polygon is calculated with the \ref getChannelFillPolygon |
|
|||
20995 | function, and then drawn. |
|
|||
20996 |
|
21164 | |||
20997 | \see drawLinePlot, drawImpulsePlot, drawScatterPlot |
|
21165 | \see drawLinePlot, drawImpulsePlot, drawScatterPlot | |
20998 | */ |
|
21166 | */ | |
@@ -21004,15 +21172,25 void QCPGraph::drawFill(QCPPainter *painter, QVector<QPointF> *lines) const | |||||
21004 | return; |
|
21172 | return; | |
21005 |
|
21173 | |||
21006 | applyFillAntialiasingHint(painter); |
|
21174 | applyFillAntialiasingHint(painter); | |
|
21175 | QVector<QCPDataRange> segments = getNonNanSegments(lines, keyAxis()->orientation()); | |||
21007 | if (!mChannelFillGraph) { |
|
21176 | if (!mChannelFillGraph) { | |
21008 | // draw base fill under graph, fill goes all the way to the zero-value-line: |
|
21177 | // draw base fill under graph, fill goes all the way to the zero-value-line: | |
21009 | addFillBasePoints(lines); |
|
21178 | for (int i = 0; i < segments.size(); ++i) | |
21010 |
painter->drawPolygon( |
|
21179 | painter->drawPolygon(getFillPolygon(lines, segments.at(i))); | |
21011 | removeFillBasePoints(lines); |
|
|||
21012 | } |
|
21180 | } | |
21013 | else { |
|
21181 | else { | |
21014 |
// draw |
|
21182 | // draw fill between this graph and mChannelFillGraph: | |
21015 | painter->drawPolygon(getChannelFillPolygon(lines)); |
|
21183 | QVector<QPointF> otherLines; | |
|
21184 | mChannelFillGraph->getLines(&otherLines, QCPDataRange(0, mChannelFillGraph->dataCount())); | |||
|
21185 | if (!otherLines.isEmpty()) { | |||
|
21186 | QVector<QCPDataRange> otherSegments | |||
|
21187 | = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation()); | |||
|
21188 | QVector<QPair<QCPDataRange, QCPDataRange> > segmentPairs | |||
|
21189 | = getOverlappingSegments(segments, lines, otherSegments, &otherLines); | |||
|
21190 | for (int i = 0; i < segmentPairs.size(); ++i) | |||
|
21191 | painter->drawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, | |||
|
21192 | &otherLines, segmentPairs.at(i).second)); | |||
|
21193 | } | |||
21016 | } |
|
21194 | } | |
21017 | } |
|
21195 | } | |
21018 |
|
21196 | |||
@@ -21205,12 +21383,8 void QCPGraph::getOptimizedLineData(QVector<QCPGraphData> *lineData, | |||||
21205 | else // don't use adaptive sampling algorithm, transfer points one-to-one from the data |
|
21383 | else // don't use adaptive sampling algorithm, transfer points one-to-one from the data | |
21206 | // container into the output |
|
21384 | // container into the output | |
21207 | { |
|
21385 | { | |
21208 | QCPGraphDataContainer::const_iterator it = begin; |
|
21386 | lineData->resize(dataCount); | |
21209 | lineData->reserve(dataCount + 2); // +2 for possible fill end points |
|
21387 | std::copy(begin, end, lineData->begin()); | |
21210 | while (it != end) { |
|
|||
21211 | lineData->append(*it); |
|
|||
21212 | ++it; |
|
|||
21213 | } |
|
|||
21214 | } |
|
21388 | } | |
21215 | } |
|
21389 | } | |
21216 |
|
21390 | |||
@@ -21479,151 +21653,177 void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin | |||||
21479 | } |
|
21653 | } | |
21480 | } |
|
21654 | } | |
21481 |
|
21655 | |||
21482 | /*! \internal |
|
21656 | /*! \internal | |
21483 |
|
21657 | |||
21484 | The line vector generated by e.g. \ref getLines describes only the line that connects the data |
|
21658 | This method goes through the passed points in \a lineData and returns a list of the segments | |
21485 | points. If the graph needs to be filled, two additional points need to be added at the |
|
21659 | which don't contain NaN data points. | |
21486 | value-zero-line in the lower and upper key positions of the graph. This function calculates these |
|
|||
21487 | points and adds them to the end of \a lineData. Since the fill is typically drawn before the line |
|
|||
21488 | stroke, these added points need to be removed again after the fill is done, with the |
|
|||
21489 | removeFillBasePoints function. |
|
|||
21490 |
|
21660 | |||
21491 | The expanding of \a lines by two points will not cause unnecessary memory reallocations, because |
|
21661 | \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check | |
21492 | the data vector generation functions (e.g. \ref getLines) reserve two extra points when they |
|
21662 | for NaN. If \a keyOrientation is \c Qt::Horizontal, the \a y member is checked, if it is \c | |
21493 | allocate memory for \a lines. |
|
21663 | Qt::Vertical, the \a x member is checked. | |
21494 |
|
21664 | |||
21495 | \see removeFillBasePoints, lowerFillBasePoint, upperFillBasePoint |
|
21665 | \see getOverlappingSegments, drawFill | |
21496 | */ |
|
21666 | */ | |
21497 | void QCPGraph::addFillBasePoints(QVector<QPointF> *lines) const |
|
21667 | QVector<QCPDataRange> QCPGraph::getNonNanSegments(const QVector<QPointF> *lineData, | |
|
21668 | Qt::Orientation keyOrientation) const | |||
21498 | { |
|
21669 | { | |
21499 | if (!mKeyAxis) { |
|
21670 | QVector<QCPDataRange> result; | |
21500 | qDebug() << Q_FUNC_INFO << "invalid key axis"; |
|
21671 | const int n = lineData->size(); | |
21501 | return; |
|
21672 | ||
21502 | } |
|
21673 | QCPDataRange currentSegment(-1, -1); | |
21503 | if (!lines) { |
|
21674 | int i = 0; | |
21504 | qDebug() << Q_FUNC_INFO << "passed null as lineData"; |
|
|||
21505 | return; |
|
|||
21506 | } |
|
|||
21507 | if (lines->isEmpty()) |
|
|||
21508 | return; |
|
|||
21509 |
|
21675 | |||
21510 | // append points that close the polygon fill at the key axis: |
|
21676 | if (keyOrientation == Qt::Horizontal) { | |
21511 | if (mKeyAxis.data()->orientation() == Qt::Vertical) { |
|
21677 | while (i < n) { | |
21512 | *lines << upperFillBasePoint(lines->last().y()); |
|
21678 | while (i < n && qIsNaN(lineData->at(i).y())) // seek next non-NaN data point | |
21513 | *lines << lowerFillBasePoint(lines->first().y()); |
|
21679 | ++i; | |
|
21680 | if (i == n) | |||
|
21681 | break; | |||
|
21682 | currentSegment.setBegin(i++); | |||
|
21683 | while (i < n && !qIsNaN(lineData->at(i).y())) // seek next NaN data point or end of data | |||
|
21684 | ++i; | |||
|
21685 | currentSegment.setEnd(i++); | |||
|
21686 | result.append(currentSegment); | |||
|
21687 | } | |||
21514 | } |
|
21688 | } | |
21515 | else { |
|
21689 | else // keyOrientation == Qt::Vertical | |
21516 | *lines << upperFillBasePoint(lines->last().x()); |
|
21690 | { | |
21517 | *lines << lowerFillBasePoint(lines->first().x()); |
|
21691 | while (i < n) { | |
|
21692 | while (i < n && qIsNaN(lineData->at(i).x())) // seek next non-NaN data point | |||
|
21693 | ++i; | |||
|
21694 | if (i == n) | |||
|
21695 | break; | |||
|
21696 | currentSegment.setBegin(i++); | |||
|
21697 | while (i < n && !qIsNaN(lineData->at(i).x())) // seek next NaN data point or end of data | |||
|
21698 | ++i; | |||
|
21699 | currentSegment.setEnd(i++); | |||
|
21700 | result.append(currentSegment); | |||
|
21701 | } | |||
21518 | } |
|
21702 | } | |
|
21703 | return result; | |||
21519 | } |
|
21704 | } | |
21520 |
|
21705 | |||
21521 | /*! \internal |
|
21706 | /*! \internal | |
|
21707 | ||||
|
21708 | This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and | |||
|
21709 | \a otherSegments, and their associated point data \a thisData and \a otherData. | |||
|
21710 | ||||
|
21711 | It returns all pairs of segments (the first from \a thisSegments, the second from \a | |||
|
21712 | otherSegments), which overlap in plot coordinates. | |||
|
21713 | ||||
|
21714 | This method is useful in the case of a channel fill between two graphs, when only those non-NaN | |||
|
21715 | segments which actually overlap in their key coordinate shall be considered for drawing a channel | |||
|
21716 | fill polygon. | |||
21522 |
|
21717 | |||
21523 | removes the two points from \a lines that were added by \ref addFillBasePoints. |
|
21718 | It is assumed that the passed segments in \a thisSegments are ordered ascending by index, and | |
|
21719 | that the segments don't overlap themselves. The same is assumed for the segments in \a | |||
|
21720 | otherSegments. This is fulfilled when the segments are obtained via \ref getNonNanSegments. | |||
21524 |
|
21721 | |||
21525 | \see addFillBasePoints, lowerFillBasePoint, upperFillBasePoint |
|
21722 | \see getNonNanSegments, segmentsIntersect, drawFill, getChannelFillPolygon | |
21526 | */ |
|
21723 | */ | |
21527 | void QCPGraph::removeFillBasePoints(QVector<QPointF> *lines) const |
|
21724 | QVector<QPair<QCPDataRange, QCPDataRange> > QCPGraph::getOverlappingSegments( | |
|
21725 | QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData, | |||
|
21726 | QVector<QCPDataRange> otherSegments, const QVector<QPointF> *otherData) const | |||
21528 | { |
|
21727 | { | |
21529 | if (!lines) { |
|
21728 | QVector<QPair<QCPDataRange, QCPDataRange> > result; | |
21530 | qDebug() << Q_FUNC_INFO << "passed null as lineData"; |
|
21729 | if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() | |
21531 | return; |
|
21730 | || otherSegments.isEmpty()) | |
|
21731 | return result; | |||
|
21732 | ||||
|
21733 | int thisIndex = 0; | |||
|
21734 | int otherIndex = 0; | |||
|
21735 | const bool verticalKey = mKeyAxis->orientation() == Qt::Vertical; | |||
|
21736 | while (thisIndex < thisSegments.size() && otherIndex < otherSegments.size()) { | |||
|
21737 | if (thisSegments.at(thisIndex).size() | |||
|
21738 | < 2) // segments with fewer than two points won't have a fill anyhow | |||
|
21739 | { | |||
|
21740 | ++thisIndex; | |||
|
21741 | continue; | |||
|
21742 | } | |||
|
21743 | if (otherSegments.at(otherIndex).size() | |||
|
21744 | < 2) // segments with fewer than two points won't have a fill anyhow | |||
|
21745 | { | |||
|
21746 | ++otherIndex; | |||
|
21747 | continue; | |||
|
21748 | } | |||
|
21749 | double thisLower, thisUpper, otherLower, otherUpper; | |||
|
21750 | if (!verticalKey) { | |||
|
21751 | thisLower = thisData->at(thisSegments.at(thisIndex).begin()).x(); | |||
|
21752 | thisUpper = thisData->at(thisSegments.at(thisIndex).end() - 1).x(); | |||
|
21753 | otherLower = otherData->at(otherSegments.at(otherIndex).begin()).x(); | |||
|
21754 | otherUpper = otherData->at(otherSegments.at(otherIndex).end() - 1).x(); | |||
|
21755 | } | |||
|
21756 | else { | |||
|
21757 | thisLower = thisData->at(thisSegments.at(thisIndex).begin()).y(); | |||
|
21758 | thisUpper = thisData->at(thisSegments.at(thisIndex).end() - 1).y(); | |||
|
21759 | otherLower = otherData->at(otherSegments.at(otherIndex).begin()).y(); | |||
|
21760 | otherUpper = otherData->at(otherSegments.at(otherIndex).end() - 1).y(); | |||
|
21761 | } | |||
|
21762 | ||||
|
21763 | int bPrecedence; | |||
|
21764 | if (segmentsIntersect(thisLower, thisUpper, otherLower, otherUpper, bPrecedence)) | |||
|
21765 | result.append(QPair<QCPDataRange, QCPDataRange>(thisSegments.at(thisIndex), | |||
|
21766 | otherSegments.at(otherIndex))); | |||
|
21767 | ||||
|
21768 | if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with | |||
|
21769 | // next otherSegment, keeping current thisSegment | |||
|
21770 | ++otherIndex; | |||
|
21771 | else // otherSegment reaches further than thisSegment, so continue with next thisSegment, | |||
|
21772 | // keeping current otherSegment | |||
|
21773 | ++thisIndex; | |||
21532 | } |
|
21774 | } | |
21533 | if (lines->isEmpty()) |
|
|||
21534 | return; |
|
|||
21535 |
|
21775 | |||
21536 | lines->remove(lines->size() - 2, 2); |
|
21776 | return result; | |
21537 | } |
|
21777 | } | |
21538 |
|
21778 | |||
21539 | /*! \internal |
|
21779 | /*! \internal | |
|
21780 | ||||
|
21781 | Returns whether the segments defined by the coordinates (aLower, aUpper) and (bLower, bUpper) | |||
|
21782 | have overlap. | |||
21540 |
|
21783 | |||
21541 | called by \ref addFillBasePoints to conveniently assign the point which closes the fill polygon |
|
21784 | The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the | |
21542 | on the lower side of the zero-value-line parallel to the key axis. The logarithmic axis scale |
|
21785 | \a a segment or not. If \a bPrecedence returns 1, segment \a b reaches the farthest to higher | |
21543 | case is a bit special, since the zero-value-line in pixel coordinates is in positive or negative |
|
21786 | coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if | |
21544 | infinity. So this case is handled separately by just closing the fill polygon on the axis which |
|
21787 | both segment's upper bounds are identical, 0 is returned as \a bPrecedence. | |
21545 | lies in the direction towards the zero value. |
|
|||
21546 |
|
21788 | |||
21547 | \a lowerKey will be the the key (in pixels) of the returned point. Depending on whether the key |
|
21789 | It is assumed that the lower bounds always have smaller or equal values than the upper bounds. | |
21548 | axis is horizontal or vertical, \a lowerKey will end up as the x or y value of the returned |
|
|||
21549 | point, respectively. |
|
|||
21550 |
|
21790 | |||
21551 | \see upperFillBasePoint, addFillBasePoints |
|
21791 | \see getOverlappingSegments | |
21552 | */ |
|
21792 | */ | |
21553 | QPointF QCPGraph::lowerFillBasePoint(double lowerKey) const |
|
21793 | bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, | |
|
21794 | int &bPrecedence) const | |||
21554 | { |
|
21795 | { | |
21555 | QCPAxis *keyAxis = mKeyAxis.data(); |
|
21796 | bPrecedence = 0; | |
21556 | QCPAxis *valueAxis = mValueAxis.data(); |
|
21797 | if (aLower > bUpper) { | |
21557 | if (!keyAxis || !valueAxis) { |
|
21798 | bPrecedence = -1; | |
21558 | qDebug() << Q_FUNC_INFO << "invalid key or value axis"; |
|
21799 | return false; | |
21559 | return QPointF(); |
|
|||
21560 | } |
|
21800 | } | |
21561 |
|
21801 | else if (bLower > aUpper) { | ||
21562 | QPointF point; |
|
21802 | bPrecedence = 1; | |
21563 | if (valueAxis->scaleType() == QCPAxis::stLinear) { |
|
21803 | return false; | |
21564 | if (keyAxis->axisType() == QCPAxis::atLeft) { |
|
|||
21565 | point.setX(valueAxis->coordToPixel(0)); |
|
|||
21566 | point.setY(lowerKey); |
|
|||
21567 | } |
|
|||
21568 | else if (keyAxis->axisType() == QCPAxis::atRight) { |
|
|||
21569 | point.setX(valueAxis->coordToPixel(0)); |
|
|||
21570 | point.setY(lowerKey); |
|
|||
21571 | } |
|
|||
21572 | else if (keyAxis->axisType() == QCPAxis::atTop) { |
|
|||
21573 | point.setX(lowerKey); |
|
|||
21574 | point.setY(valueAxis->coordToPixel(0)); |
|
|||
21575 | } |
|
|||
21576 | else if (keyAxis->axisType() == QCPAxis::atBottom) { |
|
|||
21577 | point.setX(lowerKey); |
|
|||
21578 | point.setY(valueAxis->coordToPixel(0)); |
|
|||
21579 | } |
|
|||
21580 | } |
|
21804 | } | |
21581 | else // valueAxis->mScaleType == QCPAxis::stLogarithmic |
|
21805 | else { | |
21582 | { |
|
21806 | if (aUpper > bUpper) | |
21583 | // In logarithmic scaling we can't just draw to value zero so we just fill all the way |
|
21807 | bPrecedence = -1; | |
21584 | // to the axis which is in the direction towards zero |
|
21808 | else if (aUpper < bUpper) | |
21585 | if (keyAxis->orientation() == Qt::Vertical) { |
|
21809 | bPrecedence = 1; | |
21586 | if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) |
|
21810 | ||
21587 | || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is |
|
21811 | return true; | |
21588 | // negative, zero |
|
|||
21589 | // is on opposite |
|
|||
21590 | // side of key axis |
|
|||
21591 | point.setX(keyAxis->axisRect()->right()); |
|
|||
21592 | else |
|
|||
21593 | point.setX(keyAxis->axisRect()->left()); |
|
|||
21594 | point.setY(lowerKey); |
|
|||
21595 | } |
|
|||
21596 | else if (keyAxis->axisType() == QCPAxis::atTop |
|
|||
21597 | || keyAxis->axisType() == QCPAxis::atBottom) { |
|
|||
21598 | point.setX(lowerKey); |
|
|||
21599 | if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) |
|
|||
21600 | || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is |
|
|||
21601 | // negative, zero |
|
|||
21602 | // is on opposite |
|
|||
21603 | // side of key axis |
|
|||
21604 | point.setY(keyAxis->axisRect()->top()); |
|
|||
21605 | else |
|
|||
21606 | point.setY(keyAxis->axisRect()->bottom()); |
|
|||
21607 | } |
|
|||
21608 | } |
|
21812 | } | |
21609 | return point; |
|
|||
21610 | } |
|
21813 | } | |
21611 |
|
21814 | |||
21612 | /*! \internal |
|
21815 | /*! \internal | |
21613 |
|
21816 | |||
21614 | called by \ref addFillBasePoints to conveniently assign the point which closes the fill |
|
21817 | Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis. | |
21615 | polygon on the upper side of the zero-value-line parallel to the key axis. The logarithmic axis |
|
21818 | The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates | |
21616 | scale case is a bit special, since the zero-value-line in pixel coordinates is in positive or |
|
21819 | is in positive or negative infinity. So this case is handled separately by just closing the fill | |
21617 | negative infinity. So this case is handled separately by just closing the fill polygon on the |
|
21820 | polygon on the axis which lies in the direction towards the zero value. | |
21618 | axis which lies in the direction towards the zero value. |
|
|||
21619 |
|
21821 | |||
21620 |
\a |
|
21822 | \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether | |
21621 | axis is horizontal or vertical, \a upperKey will end up as the x or y value of the returned |
|
21823 | the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or | |
21622 | point, respectively. |
|
21824 | y value of the returned point, respectively. | |
21623 |
|
||||
21624 | \see lowerFillBasePoint, addFillBasePoints |
|
|||
21625 | */ |
|
21825 | */ | |
21626 |
QPointF QCPGraph:: |
|
21826 | QPointF QCPGraph::getFillBasePoint(QPointF matchingDataPoint) const | |
21627 | { |
|
21827 | { | |
21628 | QCPAxis *keyAxis = mKeyAxis.data(); |
|
21828 | QCPAxis *keyAxis = mKeyAxis.data(); | |
21629 | QCPAxis *valueAxis = mValueAxis.data(); |
|
21829 | QCPAxis *valueAxis = mValueAxis.data(); | |
@@ -21632,23 +21832,16 QPointF QCPGraph::upperFillBasePoint(double upperKey) const | |||||
21632 | return QPointF(); |
|
21832 | return QPointF(); | |
21633 | } |
|
21833 | } | |
21634 |
|
21834 | |||
21635 |
QPointF |
|
21835 | QPointF result; | |
21636 | if (valueAxis->scaleType() == QCPAxis::stLinear) { |
|
21836 | if (valueAxis->scaleType() == QCPAxis::stLinear) { | |
21637 |
if (keyAxis-> |
|
21837 | if (keyAxis->orientation() == Qt::Horizontal) { | |
21638 | point.setX(valueAxis->coordToPixel(0)); |
|
21838 | result.setX(matchingDataPoint.x()); | |
21639 | point.setY(upperKey); |
|
21839 | result.setY(valueAxis->coordToPixel(0)); | |
21640 | } |
|
21840 | } | |
21641 |
else |
|
21841 | else // keyAxis->orientation() == Qt::Vertical | |
21642 | point.setX(valueAxis->coordToPixel(0)); |
|
21842 | { | |
21643 | point.setY(upperKey); |
|
21843 | result.setX(valueAxis->coordToPixel(0)); | |
21644 | } |
|
21844 | result.setY(matchingDataPoint.y()); | |
21645 | else if (keyAxis->axisType() == QCPAxis::atTop) { |
|
|||
21646 | point.setX(upperKey); |
|
|||
21647 | point.setY(valueAxis->coordToPixel(0)); |
|
|||
21648 | } |
|
|||
21649 | else if (keyAxis->axisType() == QCPAxis::atBottom) { |
|
|||
21650 | point.setX(upperKey); |
|
|||
21651 | point.setY(valueAxis->coordToPixel(0)); |
|
|||
21652 | } |
|
21845 | } | |
21653 | } |
|
21846 | } | |
21654 | else // valueAxis->mScaleType == QCPAxis::stLogarithmic |
|
21847 | else // valueAxis->mScaleType == QCPAxis::stLogarithmic | |
@@ -21661,40 +21854,80 QPointF QCPGraph::upperFillBasePoint(double upperKey) const | |||||
21661 | // negative, zero |
|
21854 | // negative, zero | |
21662 | // is on opposite |
|
21855 | // is on opposite | |
21663 | // side of key axis |
|
21856 | // side of key axis | |
21664 |
|
|
21857 | result.setX(keyAxis->axisRect()->right()); | |
21665 | else |
|
21858 | else | |
21666 |
|
|
21859 | result.setX(keyAxis->axisRect()->left()); | |
21667 | point.setY(upperKey); |
|
21860 | result.setY(matchingDataPoint.y()); | |
21668 | } |
|
21861 | } | |
21669 | else if (keyAxis->axisType() == QCPAxis::atTop |
|
21862 | else if (keyAxis->axisType() == QCPAxis::atTop | |
21670 | || keyAxis->axisType() == QCPAxis::atBottom) { |
|
21863 | || keyAxis->axisType() == QCPAxis::atBottom) { | |
21671 | point.setX(upperKey); |
|
21864 | result.setX(matchingDataPoint.x()); | |
21672 | if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) |
|
21865 | if ((valueAxis->range().upper < 0 && !valueAxis->rangeReversed()) | |
21673 | || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is |
|
21866 | || (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is | |
21674 | // negative, zero |
|
21867 | // negative, zero | |
21675 | // is on opposite |
|
21868 | // is on opposite | |
21676 | // side of key axis |
|
21869 | // side of key axis | |
21677 |
|
|
21870 | result.setY(keyAxis->axisRect()->top()); | |
21678 | else |
|
21871 | else | |
21679 |
|
|
21872 | result.setY(keyAxis->axisRect()->bottom()); | |
21680 | } |
|
21873 | } | |
21681 | } |
|
21874 | } | |
21682 |
return |
|
21875 | return result; | |
21683 | } |
|
21876 | } | |
21684 |
|
21877 | |||
21685 | /*! \internal |
|
21878 | /*! \internal | |
21686 |
|
21879 | |||
21687 |
|
|
21880 | Returns the polygon needed for drawing normal fills between this graph and the key axis. | |
21688 | in \a mChannelFillGraph (see \ref setChannelFillGraph). The data points representing the line of |
|
|||
21689 | this graph in pixel coordinates must be passed in \a lines, the corresponding points of the other |
|
|||
21690 | graph are generated by calling its \ref getLines method. |
|
|||
21691 |
|
21881 | |||
21692 | This method may return an empty polygon if the key ranges of the two graphs have no overlap of if |
|
21882 | Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment | |
21693 | they don't have the same orientation (e.g. one key axis vertical, the other horizontal). For |
|
21883 | which shall be used for the fill. The collection of \a lineData points described by \a segment | |
21694 | increased performance (due to implicit sharing), it is recommended to keep the returned QPolygonF |
|
21884 | must not contain NaN data points (see \ref getNonNanSegments). | |
21695 | const. |
|
21885 | ||
|
21886 | The returned fill polygon will be closed at the key axis (the zero-value line) for linear value | |||
|
21887 | axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect | |||
|
21888 | side (see \ref getFillBasePoint). | |||
|
21889 | ||||
|
21890 | For increased performance (due to implicit sharing), keep the returned QPolygonF const. | |||
|
21891 | ||||
|
21892 | \see drawFill, getNonNanSegments | |||
|
21893 | */ | |||
|
21894 | const QPolygonF QCPGraph::getFillPolygon(const QVector<QPointF> *lineData, | |||
|
21895 | QCPDataRange segment) const | |||
|
21896 | { | |||
|
21897 | if (segment.size() < 2) | |||
|
21898 | return QPolygonF(); | |||
|
21899 | QPolygonF result(segment.size() + 2); | |||
|
21900 | ||||
|
21901 | result[0] = getFillBasePoint(lineData->at(segment.begin())); | |||
|
21902 | std::copy(lineData->constBegin() + segment.begin(), lineData->constBegin() + segment.end(), | |||
|
21903 | result.begin() + 1); | |||
|
21904 | result[result.size() - 1] = getFillBasePoint(lineData->at(segment.end() - 1)); | |||
|
21905 | ||||
|
21906 | return result; | |||
|
21907 | } | |||
|
21908 | ||||
|
21909 | /*! \internal | |||
|
21910 | ||||
|
21911 | Returns the polygon needed for drawing (partial) channel fills between this graph and the graph | |||
|
21912 | specified by \ref setChannelFillGraph. | |||
|
21913 | ||||
|
21914 | The data points of this graph are passed as pixel coordinates via \a thisData, the data of the | |||
|
21915 | other graph as \a otherData. The returned polygon will be calculated for the specified data | |||
|
21916 | segments \a thisSegment and \a otherSegment, pertaining to the respective \a thisData and \a | |||
|
21917 | otherData, respectively. | |||
|
21918 | ||||
|
21919 | The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by | |||
|
21920 | \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap | |||
|
21921 | need to be processed here. | |||
|
21922 | ||||
|
21923 | For increased performance due to implicit sharing, keep the returned QPolygonF const. | |||
|
21924 | ||||
|
21925 | \see drawFill, getOverlappingSegments, getNonNanSegments | |||
21696 | */ |
|
21926 | */ | |
21697 |
const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> * |
|
21927 | const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData, | |
|
21928 | QCPDataRange thisSegment, | |||
|
21929 | const QVector<QPointF> *otherData, | |||
|
21930 | QCPDataRange otherSegment) const | |||
21698 | { |
|
21931 | { | |
21699 | if (!mChannelFillGraph) |
|
21932 | if (!mChannelFillGraph) | |
21700 | return QPolygonF(); |
|
21933 | return QPolygonF(); | |
@@ -21715,55 +21948,35 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *lines) c | |||||
21715 | // fits, valueAxis will fit too, because it's always orthogonal to |
|
21948 | // fits, valueAxis will fit too, because it's always orthogonal to | |
21716 | // keyAxis) |
|
21949 | // keyAxis) | |
21717 |
|
21950 | |||
21718 |
if ( |
|
21951 | if (thisData->isEmpty()) | |
21719 | return QPolygonF(); |
|
21952 | return QPolygonF(); | |
21720 |
QVector<QPointF> |
|
21953 | QVector<QPointF> thisSegmentData(thisSegment.size()); | |
21721 | mChannelFillGraph.data()->getLines(&otherData, |
|
21954 | QVector<QPointF> otherSegmentData(otherSegment.size()); | |
21722 | QCPDataRange(0, mChannelFillGraph.data()->dataCount())); |
|
21955 | std::copy(thisData->constBegin() + thisSegment.begin(), | |
21723 | if (otherData.isEmpty()) |
|
21956 | thisData->constBegin() + thisSegment.end(), thisSegmentData.begin()); | |
21724 | return QPolygonF(); |
|
21957 | std::copy(otherData->constBegin() + otherSegment.begin(), | |
21725 | QVector<QPointF> thisData; |
|
21958 | otherData->constBegin() + otherSegment.end(), otherSegmentData.begin()); | |
21726 | thisData.reserve( |
|
|||
21727 | lines->size() |
|
|||
21728 | + otherData.size()); // because we will join both vectors at end of this function |
|
|||
21729 | for (int i = 0; i < lines->size(); ++i) // don't use the vector<<(vector), it squeezes |
|
|||
21730 | // internally, which ruins the performance tuning with |
|
|||
21731 | // reserve() |
|
|||
21732 | thisData << lines->at(i); |
|
|||
21733 |
|
||||
21734 | // pointers to be able to swap them, depending which data range needs cropping: |
|
21959 | // pointers to be able to swap them, depending which data range needs cropping: | |
21735 | QVector<QPointF> *staticData = &thisData; |
|
21960 | QVector<QPointF> *staticData = &thisSegmentData; | |
21736 | QVector<QPointF> *croppedData = &otherData; |
|
21961 | QVector<QPointF> *croppedData = &otherSegmentData; | |
21737 |
|
21962 | |||
21738 | // crop both vectors to ranges in which the keys overlap (which coord is key, depends on |
|
21963 | // crop both vectors to ranges in which the keys overlap (which coord is key, depends on | |
21739 | // axisType): |
|
21964 | // axisType): | |
21740 | if (keyAxis->orientation() == Qt::Horizontal) { |
|
21965 | if (keyAxis->orientation() == Qt::Horizontal) { | |
21741 | // x is key |
|
21966 | // x is key | |
21742 | // if an axis range is reversed, the data point keys will be descending. Reverse them, since |
|
|||
21743 | // following algorithm assumes ascending keys: |
|
|||
21744 | if (staticData->first().x() > staticData->last().x()) { |
|
|||
21745 | int size = staticData->size(); |
|
|||
21746 | for (int i = 0; i < size / 2; ++i) |
|
|||
21747 | qSwap((*staticData)[i], (*staticData)[size - 1 - i]); |
|
|||
21748 | } |
|
|||
21749 | if (croppedData->first().x() > croppedData->last().x()) { |
|
|||
21750 | int size = croppedData->size(); |
|
|||
21751 | for (int i = 0; i < size / 2; ++i) |
|
|||
21752 | qSwap((*croppedData)[i], (*croppedData)[size - 1 - i]); |
|
|||
21753 | } |
|
|||
21754 | // crop lower bound: |
|
21967 | // crop lower bound: | |
21755 | if (staticData->first().x() < croppedData->first().x()) // other one must be cropped |
|
21968 | if (staticData->first().x() < croppedData->first().x()) // other one must be cropped | |
21756 | qSwap(staticData, croppedData); |
|
21969 | qSwap(staticData, croppedData); | |
21757 | int lowBound = findIndexBelowX(croppedData, staticData->first().x()); |
|
21970 | const int lowBound = findIndexBelowX(croppedData, staticData->first().x()); | |
21758 | if (lowBound == -1) |
|
21971 | if (lowBound == -1) | |
21759 | return QPolygonF(); // key ranges have no overlap |
|
21972 | return QPolygonF(); // key ranges have no overlap | |
21760 | croppedData->remove(0, lowBound); |
|
21973 | croppedData->remove(0, lowBound); | |
21761 | // set lowest point of cropped data to fit exactly key position of first static data |
|
21974 | // set lowest point of cropped data to fit exactly key position of first static data point | |
21762 |
// |
|
21975 | // via linear interpolation: | |
21763 | if (croppedData->size() < 2) |
|
21976 | if (croppedData->size() < 2) | |
21764 | return QPolygonF(); // need at least two points for interpolation |
|
21977 | return QPolygonF(); // need at least two points for interpolation | |
21765 | double slope; |
|
21978 | double slope; | |
21766 |
if (croppedData->at(1).x() |
|
21979 | if (!qFuzzyCompare(croppedData->at(1).x(), croppedData->at(0).x())) | |
21767 | slope = (croppedData->at(1).y() - croppedData->at(0).y()) |
|
21980 | slope = (croppedData->at(1).y() - croppedData->at(0).y()) | |
21768 | / (croppedData->at(1).x() - croppedData->at(0).x()); |
|
21981 | / (croppedData->at(1).x() - croppedData->at(0).x()); | |
21769 | else |
|
21982 | else | |
@@ -21779,12 +21992,12 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *lines) c | |||||
21779 | if (highBound == -1) |
|
21992 | if (highBound == -1) | |
21780 | return QPolygonF(); // key ranges have no overlap |
|
21993 | return QPolygonF(); // key ranges have no overlap | |
21781 | croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1)); |
|
21994 | croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1)); | |
21782 | // set highest point of cropped data to fit exactly key position of last static data |
|
21995 | // set highest point of cropped data to fit exactly key position of last static data point | |
21783 |
// |
|
21996 | // via linear interpolation: | |
21784 | if (croppedData->size() < 2) |
|
21997 | if (croppedData->size() < 2) | |
21785 | return QPolygonF(); // need at least two points for interpolation |
|
21998 | return QPolygonF(); // need at least two points for interpolation | |
21786 | int li = croppedData->size() - 1; // last index |
|
21999 | const int li = croppedData->size() - 1; // last index | |
21787 |
if (croppedData->at(li).x() |
|
22000 | if (!qFuzzyCompare(croppedData->at(li).x(), croppedData->at(li - 1).x())) | |
21788 | slope = (croppedData->at(li).y() - croppedData->at(li - 1).y()) |
|
22001 | slope = (croppedData->at(li).y() - croppedData->at(li - 1).y()) | |
21789 | / (croppedData->at(li).x() - croppedData->at(li - 1).x()); |
|
22002 | / (croppedData->at(li).x() - croppedData->at(li - 1).x()); | |
21790 | else |
|
22003 | else | |
@@ -21796,36 +22009,20 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *lines) c | |||||
21796 | else // mKeyAxis->orientation() == Qt::Vertical |
|
22009 | else // mKeyAxis->orientation() == Qt::Vertical | |
21797 | { |
|
22010 | { | |
21798 | // y is key |
|
22011 | // y is key | |
21799 | // similar to "x is key" but switched x,y. Further, lower/upper meaning is inverted compared |
|
|||
21800 | // to x, |
|
|||
21801 | // because in pixel coordinates, y increases from top to bottom, not bottom to top like data |
|
|||
21802 | // coordinate. |
|
|||
21803 | // if an axis range is reversed, the data point keys will be descending. Reverse them, since |
|
|||
21804 | // following algorithm assumes ascending keys: |
|
|||
21805 | if (staticData->first().y() < staticData->last().y()) { |
|
|||
21806 | int size = staticData->size(); |
|
|||
21807 | for (int i = 0; i < size / 2; ++i) |
|
|||
21808 | qSwap((*staticData)[i], (*staticData)[size - 1 - i]); |
|
|||
21809 | } |
|
|||
21810 | if (croppedData->first().y() < croppedData->last().y()) { |
|
|||
21811 | int size = croppedData->size(); |
|
|||
21812 | for (int i = 0; i < size / 2; ++i) |
|
|||
21813 | qSwap((*croppedData)[i], (*croppedData)[size - 1 - i]); |
|
|||
21814 | } |
|
|||
21815 | // crop lower bound: |
|
22012 | // crop lower bound: | |
21816 |
if (staticData->first().y() |
|
22013 | if (staticData->first().y() < croppedData->first().y()) // other one must be cropped | |
21817 | qSwap(staticData, croppedData); |
|
22014 | qSwap(staticData, croppedData); | |
21818 |
int lowBound = findIndex |
|
22015 | int lowBound = findIndexBelowY(croppedData, staticData->first().y()); | |
21819 | if (lowBound == -1) |
|
22016 | if (lowBound == -1) | |
21820 | return QPolygonF(); // key ranges have no overlap |
|
22017 | return QPolygonF(); // key ranges have no overlap | |
21821 | croppedData->remove(0, lowBound); |
|
22018 | croppedData->remove(0, lowBound); | |
21822 | // set lowest point of cropped data to fit exactly key position of first static data |
|
22019 | // set lowest point of cropped data to fit exactly key position of first static data point | |
21823 |
// |
|
22020 | // via linear interpolation: | |
21824 | if (croppedData->size() < 2) |
|
22021 | if (croppedData->size() < 2) | |
21825 | return QPolygonF(); // need at least two points for interpolation |
|
22022 | return QPolygonF(); // need at least two points for interpolation | |
21826 | double slope; |
|
22023 | double slope; | |
21827 |
if (croppedData->at(1).y() |
|
22024 | if (!qFuzzyCompare(croppedData->at(1).y(), | |
21828 |
|
|
22025 | croppedData->at(0).y())) // avoid division by zero in step plots | |
21829 | slope = (croppedData->at(1).x() - croppedData->at(0).x()) |
|
22026 | slope = (croppedData->at(1).x() - croppedData->at(0).x()) | |
21830 | / (croppedData->at(1).y() - croppedData->at(0).y()); |
|
22027 | / (croppedData->at(1).y() - croppedData->at(0).y()); | |
21831 | else |
|
22028 | else | |
@@ -21835,19 +22032,19 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *lines) c | |||||
21835 | (*croppedData)[0].setY(staticData->first().y()); |
|
22032 | (*croppedData)[0].setY(staticData->first().y()); | |
21836 |
|
22033 | |||
21837 | // crop upper bound: |
|
22034 | // crop upper bound: | |
21838 |
if (staticData->last().y() |
|
22035 | if (staticData->last().y() > croppedData->last().y()) // other one must be cropped | |
21839 | qSwap(staticData, croppedData); |
|
22036 | qSwap(staticData, croppedData); | |
21840 |
int highBound = findIndex |
|
22037 | int highBound = findIndexAboveY(croppedData, staticData->last().y()); | |
21841 | if (highBound == -1) |
|
22038 | if (highBound == -1) | |
21842 | return QPolygonF(); // key ranges have no overlap |
|
22039 | return QPolygonF(); // key ranges have no overlap | |
21843 | croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1)); |
|
22040 | croppedData->remove(highBound + 1, croppedData->size() - (highBound + 1)); | |
21844 | // set highest point of cropped data to fit exactly key position of last static data |
|
22041 | // set highest point of cropped data to fit exactly key position of last static data point | |
21845 |
// |
|
22042 | // via linear interpolation: | |
21846 | if (croppedData->size() < 2) |
|
22043 | if (croppedData->size() < 2) | |
21847 | return QPolygonF(); // need at least two points for interpolation |
|
22044 | return QPolygonF(); // need at least two points for interpolation | |
21848 | int li = croppedData->size() - 1; // last index |
|
22045 | int li = croppedData->size() - 1; // last index | |
21849 |
if (croppedData->at(li).y() |
|
22046 | if (!qFuzzyCompare(croppedData->at(li).y(), | |
21850 |
|
|
22047 | croppedData->at(li - 1).y())) // avoid division by zero in step plots | |
21851 | slope = (croppedData->at(li).x() - croppedData->at(li - 1).x()) |
|
22048 | slope = (croppedData->at(li).x() - croppedData->at(li - 1).x()) | |
21852 | / (croppedData->at(li).y() - croppedData->at(li - 1).y()); |
|
22049 | / (croppedData->at(li).y() - croppedData->at(li - 1).y()); | |
21853 | else |
|
22050 | else | |
@@ -21858,16 +22055,17 const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *lines) c | |||||
21858 | } |
|
22055 | } | |
21859 |
|
22056 | |||
21860 | // return joined: |
|
22057 | // return joined: | |
21861 | for (int i = otherData.size() - 1; i >= 0; |
|
22058 | for (int i = otherSegmentData.size() - 1; i >= 0; | |
21862 | --i) // insert reversed, otherwise the polygon will be twisted |
|
22059 | --i) // insert reversed, otherwise the polygon will be twisted | |
21863 | thisData << otherData.at(i); |
|
22060 | thisSegmentData << otherSegmentData.at(i); | |
21864 | return QPolygonF(thisData); |
|
22061 | return QPolygonF(thisSegmentData); | |
21865 | } |
|
22062 | } | |
21866 |
|
22063 | |||
21867 | /*! \internal |
|
22064 | /*! \internal | |
21868 |
|
22065 | |||
21869 | Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in |
|
22066 | Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in | |
21870 | \a data points are ordered ascending, as is the case when plotting with horizontal key axis. |
|
22067 | \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key | |
|
22068 | axis is horizontal. | |||
21871 |
|
22069 | |||
21872 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. |
|
22070 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. | |
21873 | */ |
|
22071 | */ | |
@@ -21887,7 +22085,8 int QCPGraph::findIndexAboveX(const QVector<QPointF> *data, double x) const | |||||
21887 | /*! \internal |
|
22085 | /*! \internal | |
21888 |
|
22086 | |||
21889 | Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in |
|
22087 | Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in | |
21890 | \a data points are ordered ascending, as is the case when plotting with horizontal key axis. |
|
22088 | \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key | |
|
22089 | axis is horizontal. | |||
21891 |
|
22090 | |||
21892 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. |
|
22091 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. | |
21893 | */ |
|
22092 | */ | |
@@ -21907,18 +22106,19 int QCPGraph::findIndexBelowX(const QVector<QPointF> *data, double x) const | |||||
21907 | /*! \internal |
|
22106 | /*! \internal | |
21908 |
|
22107 | |||
21909 | Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in |
|
22108 | Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in | |
21910 | \a data points are ordered descending, as is the case when plotting with vertical key axis. |
|
22109 | \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key | |
|
22110 | axis is vertical. | |||
21911 |
|
22111 | |||
21912 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. |
|
22112 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. | |
21913 | */ |
|
22113 | */ | |
21914 | int QCPGraph::findIndexAboveY(const QVector<QPointF> *data, double y) const |
|
22114 | int QCPGraph::findIndexAboveY(const QVector<QPointF> *data, double y) const | |
21915 | { |
|
22115 | { | |
21916 |
for (int i = |
|
22116 | for (int i = data->size() - 1; i >= 0; --i) { | |
21917 | if (data->at(i).y() < y) { |
|
22117 | if (data->at(i).y() < y) { | |
21918 |
if (i > |
|
22118 | if (i < data->size() - 1) | |
21919 |
return i |
|
22119 | return i + 1; | |
21920 | else |
|
22120 | else | |
21921 |
return |
|
22121 | return data->size() - 1; | |
21922 | } |
|
22122 | } | |
21923 | } |
|
22123 | } | |
21924 | return -1; |
|
22124 | return -1; | |
@@ -21994,19 +22194,19 double QCPGraph::pointDistance(const QPointF &pixelPoint, | |||||
21994 | /*! \internal |
|
22194 | /*! \internal | |
21995 |
|
22195 | |||
21996 | Finds the highest index of \a data, whose points y value is just below \a y. Assumes y values in |
|
22196 | Finds the highest index of \a data, whose points y value is just below \a y. Assumes y values in | |
21997 | \a data points are ordered descending, as is the case when plotting with vertical key axis (since |
|
22197 | \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key | |
21998 | keys are ordered ascending). |
|
22198 | axis is vertical. | |
21999 |
|
22199 | |||
22000 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. |
|
22200 | Used to calculate the channel fill polygon, see \ref getChannelFillPolygon. | |
22001 | */ |
|
22201 | */ | |
22002 | int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const |
|
22202 | int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const | |
22003 | { |
|
22203 | { | |
22004 |
for (int i = data->size() |
|
22204 | for (int i = 0; i < data->size(); ++i) { | |
22005 | if (data->at(i).y() > y) { |
|
22205 | if (data->at(i).y() > y) { | |
22006 |
if (i |
|
22206 | if (i > 0) | |
22007 |
return i |
|
22207 | return i - 1; | |
22008 | else |
|
22208 | else | |
22009 |
return |
|
22209 | return 0; | |
22010 | } |
|
22210 | } | |
22011 | } |
|
22211 | } | |
22012 | return -1; |
|
22212 | return -1; | |
@@ -22014,8 +22214,8 int QCPGraph::findIndexBelowY(const QVector<QPointF> *data, double y) const | |||||
22014 | /* end of 'src/plottables/plottable-graph.cpp' */ |
|
22214 | /* end of 'src/plottables/plottable-graph.cpp' */ | |
22015 |
|
22215 | |||
22016 |
|
22216 | |||
22017 |
/* including file 'src/plottables/plottable-curve.cpp', size 6 |
|
22217 | /* including file 'src/plottables/plottable-curve.cpp', size 63527 */ | |
22018 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
22218 | /* commit 63bcca79007f7f56dce5dd035560f2e871d1dfc1 2017-07-20 18:02:21 +0200 */ | |
22019 |
|
22219 | |||
22020 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
22220 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
22021 | //////////////////// QCPCurveData |
|
22221 | //////////////////// QCPCurveData | |
@@ -22179,6 +22379,7 QCPCurve::QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis) | |||||
22179 |
|
22379 | |||
22180 | setScatterStyle(QCPScatterStyle()); |
|
22380 | setScatterStyle(QCPScatterStyle()); | |
22181 | setLineStyle(lsLine); |
|
22381 | setLineStyle(lsLine); | |
|
22382 | setScatterSkip(0); | |||
22182 | } |
|
22383 | } | |
22183 |
|
22384 | |||
22184 | QCPCurve::~QCPCurve() |
|
22385 | QCPCurve::~QCPCurve() | |
@@ -22881,54 +23082,74 QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth | |||||
22881 | double value, double keyMin, double valueMax, double keyMax, |
|
23082 | double value, double keyMin, double valueMax, double keyMax, | |
22882 | double valueMin) const |
|
23083 | double valueMin) const | |
22883 | { |
|
23084 | { | |
22884 | double intersectKey = keyMin; // initial value is just fail-safe |
|
23085 | // The intersection point interpolation here is done in pixel coordinates, so we don't need to | |
22885 | double intersectValue = valueMax; // initial value is just fail-safe |
|
23086 | // differentiate between different axis scale types. Note that the nomenclature | |
|
23087 | // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be | |||
|
23088 | // different in pixel coordinates (horz/vert key axes, reversed ranges) | |||
|
23089 | ||||
|
23090 | const double keyMinPx = mKeyAxis->coordToPixel(keyMin); | |||
|
23091 | const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); | |||
|
23092 | const double valueMinPx = mValueAxis->coordToPixel(valueMin); | |||
|
23093 | const double valueMaxPx = mValueAxis->coordToPixel(valueMax); | |||
|
23094 | const double otherValuePx = mValueAxis->coordToPixel(otherValue); | |||
|
23095 | const double valuePx = mValueAxis->coordToPixel(value); | |||
|
23096 | const double otherKeyPx = mKeyAxis->coordToPixel(otherKey); | |||
|
23097 | const double keyPx = mKeyAxis->coordToPixel(key); | |||
|
23098 | double intersectKeyPx = keyMinPx; // initial key just a fail-safe | |||
|
23099 | double intersectValuePx = valueMinPx; // initial value just a fail-safe | |||
22886 | switch (otherRegion) { |
|
23100 | switch (otherRegion) { | |
22887 | case 1: // top and left edge |
|
23101 | case 1: // top and left edge | |
22888 | { |
|
23102 | { | |
22889 | intersectValue = valueMax; |
|
23103 | intersectValuePx = valueMaxPx; | |
22890 | intersectKey |
|
23104 | intersectKeyPx = otherKeyPx | |
22891 | = otherKey |
|
23105 | + (keyPx - otherKeyPx) / (valuePx - otherValuePx) | |
22892 |
|
|
23106 | * (intersectValuePx - otherValuePx); | |
22893 | if (intersectKey < keyMin |
|
23107 | if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) | |
22894 | || intersectKey > keyMax) // doesn't intersect, so must intersect other: |
|
23108 | || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not | |
|
23109 | // intersected, then it must be left | |||
|
23110 | // edge (qMin/qMax necessary since | |||
|
23111 | // axes may be reversed) | |||
22895 | { |
|
23112 | { | |
22896 | intersectKey = keyMin; |
|
23113 | intersectKeyPx = keyMinPx; | |
22897 | intersectValue |
|
23114 | intersectValuePx = otherValuePx | |
22898 | = otherValue |
|
23115 | + (valuePx - otherValuePx) / (keyPx - otherKeyPx) | |
22899 |
|
|
23116 | * (intersectKeyPx - otherKeyPx); | |
22900 | } |
|
23117 | } | |
22901 | break; |
|
23118 | break; | |
22902 | } |
|
23119 | } | |
22903 | case 2: // left edge |
|
23120 | case 2: // left edge | |
22904 | { |
|
23121 | { | |
22905 | intersectKey = keyMin; |
|
23122 | intersectKeyPx = keyMinPx; | |
22906 | intersectValue |
|
23123 | intersectValuePx | |
22907 | = otherValue + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey); |
|
23124 | = otherValuePx | |
|
23125 | + (valuePx - otherValuePx) / (keyPx - otherKeyPx) * (intersectKeyPx - otherKeyPx); | |||
22908 | break; |
|
23126 | break; | |
22909 | } |
|
23127 | } | |
22910 | case 3: // bottom and left edge |
|
23128 | case 3: // bottom and left edge | |
22911 | { |
|
23129 | { | |
22912 | intersectValue = valueMin; |
|
23130 | intersectValuePx = valueMinPx; | |
22913 | intersectKey |
|
23131 | intersectKeyPx = otherKeyPx | |
22914 | = otherKey |
|
23132 | + (keyPx - otherKeyPx) / (valuePx - otherValuePx) | |
22915 |
|
|
23133 | * (intersectValuePx - otherValuePx); | |
22916 | if (intersectKey < keyMin |
|
23134 | if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) | |
22917 | || intersectKey > keyMax) // doesn't intersect, so must intersect other: |
|
23135 | || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not | |
|
23136 | // intersected, then it must be left | |||
|
23137 | // edge (qMin/qMax necessary since | |||
|
23138 | // axes may be reversed) | |||
22918 | { |
|
23139 | { | |
22919 | intersectKey = keyMin; |
|
23140 | intersectKeyPx = keyMinPx; | |
22920 | intersectValue |
|
23141 | intersectValuePx = otherValuePx | |
22921 | = otherValue |
|
23142 | + (valuePx - otherValuePx) / (keyPx - otherKeyPx) | |
22922 |
|
|
23143 | * (intersectKeyPx - otherKeyPx); | |
22923 | } |
|
23144 | } | |
22924 | break; |
|
23145 | break; | |
22925 | } |
|
23146 | } | |
22926 | case 4: // top edge |
|
23147 | case 4: // top edge | |
22927 | { |
|
23148 | { | |
22928 | intersectValue = valueMax; |
|
23149 | intersectValuePx = valueMaxPx; | |
22929 | intersectKey |
|
23150 | intersectKeyPx = otherKeyPx | |
22930 | = otherKey |
|
23151 | + (keyPx - otherKeyPx) / (valuePx - otherValuePx) | |
22931 |
|
|
23152 | * (intersectValuePx - otherValuePx); | |
22932 | break; |
|
23153 | break; | |
22933 | } |
|
23154 | } | |
22934 | case 5: { |
|
23155 | case 5: { | |
@@ -22937,53 +23158,63 QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double oth | |||||
22937 | } |
|
23158 | } | |
22938 | case 6: // bottom edge |
|
23159 | case 6: // bottom edge | |
22939 | { |
|
23160 | { | |
22940 | intersectValue = valueMin; |
|
23161 | intersectValuePx = valueMinPx; | |
22941 | intersectKey |
|
23162 | intersectKeyPx = otherKeyPx | |
22942 | = otherKey |
|
23163 | + (keyPx - otherKeyPx) / (valuePx - otherValuePx) | |
22943 |
|
|
23164 | * (intersectValuePx - otherValuePx); | |
22944 | break; |
|
23165 | break; | |
22945 | } |
|
23166 | } | |
22946 | case 7: // top and right edge |
|
23167 | case 7: // top and right edge | |
22947 | { |
|
23168 | { | |
22948 | intersectValue = valueMax; |
|
23169 | intersectValuePx = valueMaxPx; | |
22949 | intersectKey |
|
23170 | intersectKeyPx = otherKeyPx | |
22950 | = otherKey |
|
23171 | + (keyPx - otherKeyPx) / (valuePx - otherValuePx) | |
22951 |
|
|
23172 | * (intersectValuePx - otherValuePx); | |
22952 | if (intersectKey < keyMin |
|
23173 | if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) | |
22953 | || intersectKey > keyMax) // doesn't intersect, so must intersect other: |
|
23174 | || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not | |
|
23175 | // intersected, then it must be right | |||
|
23176 | // edge (qMin/qMax necessary since | |||
|
23177 | // axes may be reversed) | |||
22954 | { |
|
23178 | { | |
22955 | intersectKey = keyMax; |
|
23179 | intersectKeyPx = keyMaxPx; | |
22956 | intersectValue |
|
23180 | intersectValuePx = otherValuePx | |
22957 | = otherValue |
|
23181 | + (valuePx - otherValuePx) / (keyPx - otherKeyPx) | |
22958 |
|
|
23182 | * (intersectKeyPx - otherKeyPx); | |
22959 | } |
|
23183 | } | |
22960 | break; |
|
23184 | break; | |
22961 | } |
|
23185 | } | |
22962 | case 8: // right edge |
|
23186 | case 8: // right edge | |
22963 | { |
|
23187 | { | |
22964 | intersectKey = keyMax; |
|
23188 | intersectKeyPx = keyMaxPx; | |
22965 | intersectValue |
|
23189 | intersectValuePx | |
22966 | = otherValue + (value - otherValue) / (key - otherKey) * (intersectKey - otherKey); |
|
23190 | = otherValuePx | |
|
23191 | + (valuePx - otherValuePx) / (keyPx - otherKeyPx) * (intersectKeyPx - otherKeyPx); | |||
22967 | break; |
|
23192 | break; | |
22968 | } |
|
23193 | } | |
22969 | case 9: // bottom and right edge |
|
23194 | case 9: // bottom and right edge | |
22970 | { |
|
23195 | { | |
22971 | intersectValue = valueMin; |
|
23196 | intersectValuePx = valueMinPx; | |
22972 | intersectKey |
|
23197 | intersectKeyPx = otherKeyPx | |
22973 | = otherKey |
|
23198 | + (keyPx - otherKeyPx) / (valuePx - otherValuePx) | |
22974 |
|
|
23199 | * (intersectValuePx - otherValuePx); | |
22975 | if (intersectKey < keyMin |
|
23200 | if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) | |
22976 | || intersectKey > keyMax) // doesn't intersect, so must intersect other: |
|
23201 | || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not | |
|
23202 | // intersected, then it must be right | |||
|
23203 | // edge (qMin/qMax necessary since | |||
|
23204 | // axes may be reversed) | |||
22977 | { |
|
23205 | { | |
22978 | intersectKey = keyMax; |
|
23206 | intersectKeyPx = keyMaxPx; | |
22979 | intersectValue |
|
23207 | intersectValuePx = otherValuePx | |
22980 | = otherValue |
|
23208 | + (valuePx - otherValuePx) / (keyPx - otherKeyPx) | |
22981 |
|
|
23209 | * (intersectKeyPx - otherKeyPx); | |
22982 | } |
|
23210 | } | |
22983 | break; |
|
23211 | break; | |
22984 | } |
|
23212 | } | |
22985 | } |
|
23213 | } | |
22986 | return coordsToPixels(intersectKey, intersectValue); |
|
23214 | if (mKeyAxis->orientation() == Qt::Horizontal) | |
|
23215 | return QPointF(intersectKeyPx, intersectValuePx); | |||
|
23216 | else | |||
|
23217 | return QPointF(intersectValuePx, intersectKeyPx); | |||
22987 | } |
|
23218 | } | |
22988 |
|
23219 | |||
22989 | /*! \internal |
|
23220 | /*! \internal | |
@@ -23496,44 +23727,79 bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double | |||||
23496 | double keyMin, double valueMax, double keyMax, double valueMin, |
|
23727 | double keyMin, double valueMax, double keyMax, double valueMin, | |
23497 | QPointF &crossA, QPointF &crossB) const |
|
23728 | QPointF &crossA, QPointF &crossB) const | |
23498 | { |
|
23729 | { | |
23499 | QList<QPointF> intersections; // x of QPointF corresponds to key and y to value |
|
23730 | // The intersection point interpolation here is done in pixel coordinates, so we don't need to | |
|
23731 | // differentiate between different axis scale types. Note that the nomenclature | |||
|
23732 | // top/left/bottom/right/min/max is with respect to the rect in plot coordinates, wich may be | |||
|
23733 | // different in pixel coordinates (horz/vert key axes, reversed ranges) | |||
|
23734 | ||||
|
23735 | QList<QPointF> intersections; | |||
|
23736 | const double valueMinPx = mValueAxis->coordToPixel(valueMin); | |||
|
23737 | const double valueMaxPx = mValueAxis->coordToPixel(valueMax); | |||
|
23738 | const double keyMinPx = mKeyAxis->coordToPixel(keyMin); | |||
|
23739 | const double keyMaxPx = mKeyAxis->coordToPixel(keyMax); | |||
|
23740 | const double keyPx = mKeyAxis->coordToPixel(key); | |||
|
23741 | const double valuePx = mValueAxis->coordToPixel(value); | |||
|
23742 | const double prevKeyPx = mKeyAxis->coordToPixel(prevKey); | |||
|
23743 | const double prevValuePx = mValueAxis->coordToPixel(prevValue); | |||
23500 | if (qFuzzyIsNull(key - prevKey)) // line is parallel to value axis |
|
23744 | if (qFuzzyIsNull(key - prevKey)) // line is parallel to value axis | |
23501 | { |
|
23745 | { | |
23502 |
// due to region filter in mayTraverse |
|
23746 | // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 | |
23503 | // traversed here |
|
23747 | // is traversed here | |
23504 | intersections.append( |
|
23748 | intersections.append( | |
23505 | QPointF(key, valueMin)); // direction will be taken care of at end of method |
|
23749 | mKeyAxis->orientation() == Qt::Horizontal | |
23506 |
|
|
23750 | ? QPointF(keyPx, valueMinPx) | |
|
23751 | : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method | |||
|
23752 | intersections.append(mKeyAxis->orientation() == Qt::Horizontal | |||
|
23753 | ? QPointF(keyPx, valueMaxPx) | |||
|
23754 | : QPointF(valueMaxPx, keyPx)); | |||
23507 | } |
|
23755 | } | |
23508 | else if (qFuzzyIsNull(value - prevValue)) // line is parallel to key axis |
|
23756 | else if (qFuzzyIsNull(value - prevValue)) // line is parallel to key axis | |
23509 | { |
|
23757 | { | |
23510 |
// due to region filter in mayTraverse |
|
23758 | // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 | |
23511 | // traversed here |
|
23759 | // is traversed here | |
23512 | intersections.append( |
|
23760 | intersections.append( | |
23513 | QPointF(keyMin, value)); // direction will be taken care of at end of method |
|
23761 | mKeyAxis->orientation() == Qt::Horizontal | |
23514 |
|
|
23762 | ? QPointF(keyMinPx, valuePx) | |
|
23763 | : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method | |||
|
23764 | intersections.append(mKeyAxis->orientation() == Qt::Horizontal | |||
|
23765 | ? QPointF(keyMaxPx, valuePx) | |||
|
23766 | : QPointF(valuePx, keyMaxPx)); | |||
23515 | } |
|
23767 | } | |
23516 | else // line is skewed |
|
23768 | else // line is skewed | |
23517 | { |
|
23769 | { | |
23518 | double gamma; |
|
23770 | double gamma; | |
23519 | double keyPerValue = (key - prevKey) / (value - prevValue); |
|
23771 | double keyPerValuePx = (keyPx - prevKeyPx) / (valuePx - prevValuePx); | |
23520 | // check top of rect: |
|
23772 | // check top of rect: | |
23521 | gamma = prevKey + (valueMax - prevValue) * keyPerValue; |
|
23773 | gamma = prevKeyPx + (valueMaxPx - prevValuePx) * keyPerValuePx; | |
23522 |
if (gamma >= keyMin |
|
23774 | if (gamma >= qMin(keyMinPx, keyMaxPx) | |
23523 | intersections.append(QPointF(gamma, valueMax)); |
|
23775 | && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed | |
|
23776 | intersections.append(mKeyAxis->orientation() == Qt::Horizontal | |||
|
23777 | ? QPointF(gamma, valueMaxPx) | |||
|
23778 | : QPointF(valueMaxPx, gamma)); | |||
23524 | // check bottom of rect: |
|
23779 | // check bottom of rect: | |
23525 | gamma = prevKey + (valueMin - prevValue) * keyPerValue; |
|
23780 | gamma = prevKeyPx + (valueMinPx - prevValuePx) * keyPerValuePx; | |
23526 |
if (gamma >= keyMin |
|
23781 | if (gamma >= qMin(keyMinPx, keyMaxPx) | |
23527 | intersections.append(QPointF(gamma, valueMin)); |
|
23782 | && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed | |
23528 | double valuePerKey = 1.0 / keyPerValue; |
|
23783 | intersections.append(mKeyAxis->orientation() == Qt::Horizontal | |
|
23784 | ? QPointF(gamma, valueMinPx) | |||
|
23785 | : QPointF(valueMinPx, gamma)); | |||
|
23786 | const double valuePerKeyPx = 1.0 / keyPerValuePx; | |||
23529 | // check left of rect: |
|
23787 | // check left of rect: | |
23530 | gamma = prevValue + (keyMin - prevKey) * valuePerKey; |
|
23788 | gamma = prevValuePx + (keyMinPx - prevKeyPx) * valuePerKeyPx; | |
23531 |
if (gamma >= valueMin |
|
23789 | if (gamma >= qMin(valueMinPx, valueMaxPx) | |
23532 | intersections.append(QPointF(keyMin, gamma)); |
|
23790 | && gamma <= qMax(valueMinPx, | |
|
23791 | valueMaxPx)) // qMin/qMax necessary since axes may be reversed | |||
|
23792 | intersections.append(mKeyAxis->orientation() == Qt::Horizontal | |||
|
23793 | ? QPointF(keyMinPx, gamma) | |||
|
23794 | : QPointF(gamma, keyMinPx)); | |||
23533 | // check right of rect: |
|
23795 | // check right of rect: | |
23534 | gamma = prevValue + (keyMax - prevKey) * valuePerKey; |
|
23796 | gamma = prevValuePx + (keyMaxPx - prevKeyPx) * valuePerKeyPx; | |
23535 |
if (gamma >= valueMin |
|
23797 | if (gamma >= qMin(valueMinPx, valueMaxPx) | |
23536 | intersections.append(QPointF(keyMax, gamma)); |
|
23798 | && gamma <= qMax(valueMinPx, | |
|
23799 | valueMaxPx)) // qMin/qMax necessary since axes may be reversed | |||
|
23800 | intersections.append(mKeyAxis->orientation() == Qt::Horizontal | |||
|
23801 | ? QPointF(keyMaxPx, gamma) | |||
|
23802 | : QPointF(gamma, keyMaxPx)); | |||
23537 | } |
|
23803 | } | |
23538 |
|
23804 | |||
23539 | // handle cases where found points isn't exactly 2: |
|
23805 | // handle cases where found points isn't exactly 2: | |
@@ -23562,12 +23828,16 bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double | |||||
23562 | } |
|
23828 | } | |
23563 |
|
23829 | |||
23564 | // possibly re-sort points so optimized point segment has same direction as original segment: |
|
23830 | // possibly re-sort points so optimized point segment has same direction as original segment: | |
23565 | if ((key - prevKey) * (intersections.at(1).x() - intersections.at(0).x()) |
|
23831 | double xDelta = keyPx - prevKeyPx; | |
23566 | + (value - prevValue) * (intersections.at(1).y() - intersections.at(0).y()) |
|
23832 | double yDelta = valuePx - prevValuePx; | |
|
23833 | if (mKeyAxis->orientation() != Qt::Horizontal) | |||
|
23834 | qSwap(xDelta, yDelta); | |||
|
23835 | if (xDelta * (intersections.at(1).x() - intersections.at(0).x()) | |||
|
23836 | + yDelta * (intersections.at(1).y() - intersections.at(0).y()) | |||
23567 | < 0) // scalar product of both segments < 0 -> opposite direction |
|
23837 | < 0) // scalar product of both segments < 0 -> opposite direction | |
23568 | intersections.move(0, 1); |
|
23838 | intersections.move(0, 1); | |
23569 |
crossA = |
|
23839 | crossA = intersections.at(0); | |
23570 |
crossB = |
|
23840 | crossB = intersections.at(1); | |
23571 | return true; |
|
23841 | return true; | |
23572 | } |
|
23842 | } | |
23573 |
|
23843 | |||
@@ -25678,8 +25948,8 QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iter | |||||
25678 | /* end of 'src/plottables/plottable-statisticalbox.cpp' */ |
|
25948 | /* end of 'src/plottables/plottable-statisticalbox.cpp' */ | |
25679 |
|
25949 | |||
25680 |
|
25950 | |||
25681 |
/* including file 'src/plottables/plottable-colormap.cpp', size 47 |
|
25951 | /* including file 'src/plottables/plottable-colormap.cpp', size 47881 */ | |
25682 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
25952 | /* commit 83a770151292397b3ba4984108d7ed167a9aec65 2017-08-13 16:22:21 +0200 */ | |
25683 |
|
25953 | |||
25684 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
25954 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
25685 | //////////////////// QCPColorMapData |
|
25955 | //////////////////// QCPColorMapData | |
@@ -26350,6 +26620,7 QCPColorMap::QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis) | |||||
26350 | : QCPAbstractPlottable(keyAxis, valueAxis), |
|
26620 | : QCPAbstractPlottable(keyAxis, valueAxis), | |
26351 | mDataScaleType(QCPAxis::stLinear), |
|
26621 | mDataScaleType(QCPAxis::stLinear), | |
26352 | mMapData(new QCPColorMapData(10, 10, QCPRange(0, 5), QCPRange(0, 5))), |
|
26622 | mMapData(new QCPColorMapData(10, 10, QCPRange(0, 5), QCPRange(0, 5))), | |
|
26623 | mGradient(QCPColorGradient::gpCold), | |||
26353 | mInterpolate(true), |
|
26624 | mInterpolate(true), | |
26354 | mTightBoundary(false), |
|
26625 | mTightBoundary(false), | |
26355 | mMapImageInvalidated(true) |
|
26626 | mMapImageInvalidated(true) | |
@@ -26709,73 +26980,81 void QCPColorMap::updateMapImage() | |||||
26709 | mMapImage = QImage( |
|
26980 | mMapImage = QImage( | |
26710 | QSize(valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor), format); |
|
26981 | QSize(valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor), format); | |
26711 |
|
26982 | |||
26712 | QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. |
|
26983 | if (mMapImage.isNull()) { | |
26713 | // Either the final mMapImage, or if we need oversampling, |
|
26984 | qDebug() << Q_FUNC_INFO << "Couldn't create map image (possibly too large for memory)"; | |
26714 | // mUndersampledMapImage |
|
26985 | mMapImage = QImage(QSize(10, 10), format); | |
26715 | if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) { |
|
26986 | mMapImage.fill(Qt::black); | |
26716 | // resize undersampled map image to actual key/value cell sizes: |
|
|||
26717 | if (keyAxis->orientation() == Qt::Horizontal |
|
|||
26718 | && (mUndersampledMapImage.width() != keySize |
|
|||
26719 | || mUndersampledMapImage.height() != valueSize)) |
|
|||
26720 | mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); |
|
|||
26721 | else if (keyAxis->orientation() == Qt::Vertical |
|
|||
26722 | && (mUndersampledMapImage.width() != valueSize |
|
|||
26723 | || mUndersampledMapImage.height() != keySize)) |
|
|||
26724 | mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); |
|
|||
26725 | localMapImage |
|
|||
26726 | = &mUndersampledMapImage; // make the colorization run on the undersampled image |
|
|||
26727 | } |
|
|||
26728 | else if (!mUndersampledMapImage.isNull()) |
|
|||
26729 | mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has |
|
|||
26730 | // changed) but mUndersampledMapImage still has nonzero |
|
|||
26731 | // size, free it |
|
|||
26732 |
|
||||
26733 | const double *rawData = mMapData->mData; |
|
|||
26734 | const unsigned char *rawAlpha = mMapData->mAlpha; |
|
|||
26735 | if (keyAxis->orientation() == Qt::Horizontal) { |
|
|||
26736 | const int lineCount = valueSize; |
|
|||
26737 | const int rowCount = keySize; |
|
|||
26738 | for (int line = 0; line < lineCount; ++line) { |
|
|||
26739 | QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine( |
|
|||
26740 | lineCount - 1 - line)); // invert scanline index because QImage counts scanlines |
|
|||
26741 | // from top, but our vertical index counts from bottom |
|
|||
26742 | // (mathematical coordinate system) |
|
|||
26743 | if (rawAlpha) |
|
|||
26744 | mGradient.colorize(rawData + line * rowCount, rawAlpha + line * rowCount, |
|
|||
26745 | mDataRange, pixels, rowCount, 1, |
|
|||
26746 | mDataScaleType == QCPAxis::stLogarithmic); |
|
|||
26747 | else |
|
|||
26748 | mGradient.colorize(rawData + line * rowCount, mDataRange, pixels, rowCount, 1, |
|
|||
26749 | mDataScaleType == QCPAxis::stLogarithmic); |
|
|||
26750 | } |
|
|||
26751 | } |
|
26987 | } | |
26752 | else // keyAxis->orientation() == Qt::Vertical |
|
26988 | else { | |
26753 | { |
|
26989 | QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. | |
26754 | const int lineCount = keySize; |
|
26990 | // Either the final mMapImage, or if we need | |
26755 | const int rowCount = valueSize; |
|
26991 | // oversampling, mUndersampledMapImage | |
26756 | for (int line = 0; line < lineCount; ++line) { |
|
26992 | if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) { | |
26757 | QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine( |
|
26993 | // resize undersampled map image to actual key/value cell sizes: | |
26758 | lineCount - 1 - line)); // invert scanline index because QImage counts scanlines |
|
26994 | if (keyAxis->orientation() == Qt::Horizontal | |
26759 | // from top, but our vertical index counts from bottom |
|
26995 | && (mUndersampledMapImage.width() != keySize | |
26760 | // (mathematical coordinate system) |
|
26996 | || mUndersampledMapImage.height() != valueSize)) | |
26761 | if (rawAlpha) |
|
26997 | mUndersampledMapImage = QImage(QSize(keySize, valueSize), format); | |
26762 | mGradient.colorize(rawData + line, rawAlpha + line, mDataRange, pixels, rowCount, |
|
26998 | else if (keyAxis->orientation() == Qt::Vertical | |
26763 | lineCount, mDataScaleType == QCPAxis::stLogarithmic); |
|
26999 | && (mUndersampledMapImage.width() != valueSize | |
26764 | else |
|
27000 | || mUndersampledMapImage.height() != keySize)) | |
26765 | mGradient.colorize(rawData + line, mDataRange, pixels, rowCount, lineCount, |
|
27001 | mUndersampledMapImage = QImage(QSize(valueSize, keySize), format); | |
26766 | mDataScaleType == QCPAxis::stLogarithmic); |
|
27002 | localMapImage | |
|
27003 | = &mUndersampledMapImage; // make the colorization run on the undersampled image | |||
|
27004 | } | |||
|
27005 | else if (!mUndersampledMapImage.isNull()) | |||
|
27006 | mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size | |||
|
27007 | // has changed) but mUndersampledMapImage still has | |||
|
27008 | // nonzero size, free it | |||
|
27009 | ||||
|
27010 | const double *rawData = mMapData->mData; | |||
|
27011 | const unsigned char *rawAlpha = mMapData->mAlpha; | |||
|
27012 | if (keyAxis->orientation() == Qt::Horizontal) { | |||
|
27013 | const int lineCount = valueSize; | |||
|
27014 | const int rowCount = keySize; | |||
|
27015 | for (int line = 0; line < lineCount; ++line) { | |||
|
27016 | QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine( | |||
|
27017 | lineCount - 1 - line)); // invert scanline index because QImage counts scanlines | |||
|
27018 | // from top, but our vertical index counts from bottom | |||
|
27019 | // (mathematical coordinate system) | |||
|
27020 | if (rawAlpha) | |||
|
27021 | mGradient.colorize(rawData + line * rowCount, rawAlpha + line * rowCount, | |||
|
27022 | mDataRange, pixels, rowCount, 1, | |||
|
27023 | mDataScaleType == QCPAxis::stLogarithmic); | |||
|
27024 | else | |||
|
27025 | mGradient.colorize(rawData + line * rowCount, mDataRange, pixels, rowCount, 1, | |||
|
27026 | mDataScaleType == QCPAxis::stLogarithmic); | |||
|
27027 | } | |||
|
27028 | } | |||
|
27029 | else // keyAxis->orientation() == Qt::Vertical | |||
|
27030 | { | |||
|
27031 | const int lineCount = keySize; | |||
|
27032 | const int rowCount = valueSize; | |||
|
27033 | for (int line = 0; line < lineCount; ++line) { | |||
|
27034 | QRgb *pixels = reinterpret_cast<QRgb *>(localMapImage->scanLine( | |||
|
27035 | lineCount - 1 - line)); // invert scanline index because QImage counts scanlines | |||
|
27036 | // from top, but our vertical index counts from bottom | |||
|
27037 | // (mathematical coordinate system) | |||
|
27038 | if (rawAlpha) | |||
|
27039 | mGradient.colorize(rawData + line, rawAlpha + line, mDataRange, pixels, | |||
|
27040 | rowCount, lineCount, | |||
|
27041 | mDataScaleType == QCPAxis::stLogarithmic); | |||
|
27042 | else | |||
|
27043 | mGradient.colorize(rawData + line, mDataRange, pixels, rowCount, lineCount, | |||
|
27044 | mDataScaleType == QCPAxis::stLogarithmic); | |||
|
27045 | } | |||
26767 | } |
|
27046 | } | |
26768 | } |
|
|||
26769 |
|
27047 | |||
26770 | if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) { |
|
27048 | if (keyOversamplingFactor > 1 || valueOversamplingFactor > 1) { | |
26771 | if (keyAxis->orientation() == Qt::Horizontal) |
|
27049 | if (keyAxis->orientation() == Qt::Horizontal) | |
26772 |
mMapImage = mUndersampledMapImage.scaled( |
|
27050 | mMapImage = mUndersampledMapImage.scaled( | |
26773 |
|
|
27051 | keySize * keyOversamplingFactor, valueSize * valueOversamplingFactor, | |
26774 |
|
|
27052 | Qt::IgnoreAspectRatio, Qt::FastTransformation); | |
26775 | else |
|
27053 | else | |
26776 |
mMapImage = mUndersampledMapImage.scaled( |
|
27054 | mMapImage = mUndersampledMapImage.scaled( | |
26777 |
|
|
27055 | valueSize * valueOversamplingFactor, keySize * keyOversamplingFactor, | |
26778 |
|
|
27056 | Qt::IgnoreAspectRatio, Qt::FastTransformation); | |
|
27057 | } | |||
26779 | } |
|
27058 | } | |
26780 | mMapData->mDataModified = false; |
|
27059 | mMapData->mDataModified = false; | |
26781 | mMapImageInvalidated = false; |
|
27060 | mMapImageInvalidated = false; | |
@@ -27939,8 +28218,8 QRectF QCPFinancial::selectionHitBox(QCPFinancialDataContainer::const_iterator i | |||||
27939 | /* end of 'src/plottables/plottable-financial.cpp' */ |
|
28218 | /* end of 'src/plottables/plottable-financial.cpp' */ | |
27940 |
|
28219 | |||
27941 |
|
28220 | |||
27942 |
/* including file 'src/plottables/plottable-errorbar.cpp', size 37 |
|
28221 | /* including file 'src/plottables/plottable-errorbar.cpp', size 37355 */ | |
27943 | /* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ |
|
28222 | /* commit 6f159843e9ec9ea6431b26591937aea13a9f2751 2017-07-25 11:13:32 +0200 */ | |
27944 |
|
28223 | |||
27945 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
|
28224 | //////////////////////////////////////////////////////////////////////////////////////////////////// | |
27946 | //////////////////// QCPErrorBarsData |
|
28225 | //////////////////// QCPErrorBarsData | |
@@ -28671,8 +28950,8 void QCPErrorBars::getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it | |||||
28671 | QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); |
|
28950 | QPointF centerPixel = mDataPlottable->interface1D()->dataPixelPosition(index); | |
28672 | if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) |
|
28951 | if (qIsNaN(centerPixel.x()) || qIsNaN(centerPixel.y())) | |
28673 | return; |
|
28952 | return; | |
28674 | QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis : mKeyAxis; |
|
28953 | QCPAxis *errorAxis = mErrorType == etValueError ? mValueAxis.data() : mKeyAxis.data(); | |
28675 | QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis : mValueAxis; |
|
28954 | QCPAxis *orthoAxis = mErrorType == etValueError ? mKeyAxis.data() : mValueAxis.data(); | |
28676 | const double centerErrorAxisPixel |
|
28955 | const double centerErrorAxisPixel | |
28677 | = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); |
|
28956 | = errorAxis->orientation() == Qt::Horizontal ? centerPixel.x() : centerPixel.y(); | |
28678 | const double centerOrthoAxisPixel |
|
28957 | const double centerOrthoAxisPixel | |
@@ -28806,6 +29085,10 double QCPErrorBars::pointDistance(const QPointF &pixelPoint, | |||||
28806 | closestData = mDataContainer->constEnd(); |
|
29085 | closestData = mDataContainer->constEnd(); | |
28807 | if (!mDataPlottable || mDataContainer->isEmpty()) |
|
29086 | if (!mDataPlottable || mDataContainer->isEmpty()) | |
28808 | return -1.0; |
|
29087 | return -1.0; | |
|
29088 | if (!mKeyAxis || !mValueAxis) { | |||
|
29089 | qDebug() << Q_FUNC_INFO << "invalid key or value axis"; | |||
|
29090 | return -1.0; | |||
|
29091 | } | |||
28809 |
|
29092 | |||
28810 | QCPErrorBarsDataContainer::const_iterator begin, end; |
|
29093 | QCPErrorBarsDataContainer::const_iterator begin, end; | |
28811 | getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); |
|
29094 | getVisibleDataBounds(begin, end, QCPDataRange(0, dataCount())); |
General Comments 0
You need to be logged in to leave comments.
Login now