##// END OF EJS Templates
Fix empty domain detection...
Titta Heikkala -
r2711:76339f714f08
parent child
Show More
@@ -1,266 +1,266
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2014 Digia Plc
3 ** Copyright (C) 2014 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Enterprise Charts Add-on.
7 ** This file is part of the Qt Enterprise Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
10 ** Licensees holding valid Qt Enterprise licenses may use this file in
11 ** accordance with the Qt Enterprise License Agreement provided with the
11 ** accordance with the Qt Enterprise License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "abstractdomain_p.h"
21 #include "abstractdomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include <qmath.h>
23 #include <qmath.h>
24
24
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
26
27 AbstractDomain::AbstractDomain(QObject *parent)
27 AbstractDomain::AbstractDomain(QObject *parent)
28 : QObject(parent),
28 : QObject(parent),
29 m_minX(0),
29 m_minX(0),
30 m_maxX(0),
30 m_maxX(0),
31 m_minY(0),
31 m_minY(0),
32 m_maxY(0),
32 m_maxY(0),
33 m_signalsBlocked(false),
33 m_signalsBlocked(false),
34 m_zoomed(false),
34 m_zoomed(false),
35 m_zoomResetMinX(0),
35 m_zoomResetMinX(0),
36 m_zoomResetMaxX(0),
36 m_zoomResetMaxX(0),
37 m_zoomResetMinY(0),
37 m_zoomResetMinY(0),
38 m_zoomResetMaxY(0)
38 m_zoomResetMaxY(0)
39
39
40 {
40 {
41 }
41 }
42
42
43 AbstractDomain::~AbstractDomain()
43 AbstractDomain::~AbstractDomain()
44 {
44 {
45 }
45 }
46
46
47 void AbstractDomain::setSize(const QSizeF &size)
47 void AbstractDomain::setSize(const QSizeF &size)
48 {
48 {
49 if(m_size!=size)
49 if(m_size!=size)
50 {
50 {
51 m_size=size;
51 m_size=size;
52 emit updated();
52 emit updated();
53 }
53 }
54 }
54 }
55
55
56 QSizeF AbstractDomain::size() const
56 QSizeF AbstractDomain::size() const
57 {
57 {
58 return m_size;
58 return m_size;
59 }
59 }
60
60
61 void AbstractDomain::setRangeX(qreal min, qreal max)
61 void AbstractDomain::setRangeX(qreal min, qreal max)
62 {
62 {
63 setRange(min, max, m_minY, m_maxY);
63 setRange(min, max, m_minY, m_maxY);
64 }
64 }
65
65
66 void AbstractDomain::setRangeY(qreal min, qreal max)
66 void AbstractDomain::setRangeY(qreal min, qreal max)
67 {
67 {
68 setRange(m_minX, m_maxX, min, max);
68 setRange(m_minX, m_maxX, min, max);
69 }
69 }
70
70
71 void AbstractDomain::setMinX(qreal min)
71 void AbstractDomain::setMinX(qreal min)
72 {
72 {
73 setRange(min, m_maxX, m_minY, m_maxY);
73 setRange(min, m_maxX, m_minY, m_maxY);
74 }
74 }
75
75
76 void AbstractDomain::setMaxX(qreal max)
76 void AbstractDomain::setMaxX(qreal max)
77 {
77 {
78 setRange(m_minX, max, m_minY, m_maxY);
78 setRange(m_minX, max, m_minY, m_maxY);
79 }
79 }
80
80
81 void AbstractDomain::setMinY(qreal min)
81 void AbstractDomain::setMinY(qreal min)
82 {
82 {
83 setRange(m_minX, m_maxX, min, m_maxY);
83 setRange(m_minX, m_maxX, min, m_maxY);
84 }
84 }
85
85
86 void AbstractDomain::setMaxY(qreal max)
86 void AbstractDomain::setMaxY(qreal max)
87 {
87 {
88 setRange(m_minX, m_maxX, m_minY, max);
88 setRange(m_minX, m_maxX, m_minY, max);
89 }
89 }
90
90
91 qreal AbstractDomain::spanX() const
91 qreal AbstractDomain::spanX() const
92 {
92 {
93 Q_ASSERT(m_maxX >= m_minX);
93 Q_ASSERT(m_maxX >= m_minX);
94 return m_maxX - m_minX;
94 return m_maxX - m_minX;
95 }
95 }
96
96
97 qreal AbstractDomain::spanY() const
97 qreal AbstractDomain::spanY() const
98 {
98 {
99 Q_ASSERT(m_maxY >= m_minY);
99 Q_ASSERT(m_maxY >= m_minY);
100 return m_maxY - m_minY;
100 return m_maxY - m_minY;
101 }
101 }
102
102
103 bool AbstractDomain::isEmpty() const
103 bool AbstractDomain::isEmpty() const
104 {
104 {
105 return qFuzzyIsNull(spanX()) || qFuzzyIsNull(spanY()) || m_size.isEmpty() ;
105 return qFuzzyCompare(spanX(), 0) || qFuzzyCompare(spanY(), 0) || m_size.isEmpty();
106 }
106 }
107
107
108 QPointF AbstractDomain::calculateDomainPoint(const QPointF &point) const
108 QPointF AbstractDomain::calculateDomainPoint(const QPointF &point) const
109 {
109 {
110 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
110 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
111 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
111 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
112 qreal x = point.x() / deltaX + m_minX;
112 qreal x = point.x() / deltaX + m_minX;
113 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
113 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
114 return QPointF(x, y);
114 return QPointF(x, y);
115 }
115 }
116
116
117 // handlers
117 // handlers
118
118
119 void AbstractDomain::handleVerticalAxisRangeChanged(qreal min, qreal max)
119 void AbstractDomain::handleVerticalAxisRangeChanged(qreal min, qreal max)
120 {
120 {
121 setRangeY(min, max);
121 setRangeY(min, max);
122 }
122 }
123
123
124 void AbstractDomain::handleHorizontalAxisRangeChanged(qreal min, qreal max)
124 void AbstractDomain::handleHorizontalAxisRangeChanged(qreal min, qreal max)
125 {
125 {
126 setRangeX(min, max);
126 setRangeX(min, max);
127 }
127 }
128
128
129 void AbstractDomain::blockRangeSignals(bool block)
129 void AbstractDomain::blockRangeSignals(bool block)
130 {
130 {
131 if (m_signalsBlocked!=block) {
131 if (m_signalsBlocked!=block) {
132 m_signalsBlocked=block;
132 m_signalsBlocked=block;
133 if (!block) {
133 if (!block) {
134 emit rangeHorizontalChanged(m_minX,m_maxX);
134 emit rangeHorizontalChanged(m_minX,m_maxX);
135 emit rangeVerticalChanged(m_minY,m_maxY);
135 emit rangeVerticalChanged(m_minY,m_maxY);
136 }
136 }
137 }
137 }
138 }
138 }
139
139
140 void AbstractDomain::zoomReset()
140 void AbstractDomain::zoomReset()
141 {
141 {
142 if (m_zoomed) {
142 if (m_zoomed) {
143 setRange(m_zoomResetMinX,
143 setRange(m_zoomResetMinX,
144 m_zoomResetMaxX,
144 m_zoomResetMaxX,
145 m_zoomResetMinY,
145 m_zoomResetMinY,
146 m_zoomResetMaxY);
146 m_zoomResetMaxY);
147 m_zoomed = false;
147 m_zoomed = false;
148 }
148 }
149 }
149 }
150
150
151 void AbstractDomain::storeZoomReset()
151 void AbstractDomain::storeZoomReset()
152 {
152 {
153 if (!m_zoomed) {
153 if (!m_zoomed) {
154 m_zoomed = true;
154 m_zoomed = true;
155 m_zoomResetMinX = m_minX;
155 m_zoomResetMinX = m_minX;
156 m_zoomResetMaxX = m_maxX;
156 m_zoomResetMaxX = m_maxX;
157 m_zoomResetMinY = m_minY;
157 m_zoomResetMinY = m_minY;
158 m_zoomResetMaxY = m_maxY;
158 m_zoomResetMaxY = m_maxY;
159 }
159 }
160 }
160 }
161
161
162 //algorithm defined by Paul S.Heckbert GraphicalGems I
162 //algorithm defined by Paul S.Heckbert GraphicalGems I
163
163
164 void AbstractDomain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
164 void AbstractDomain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
165 {
165 {
166 qreal range = niceNumber(max - min, true); //range with ceiling
166 qreal range = niceNumber(max - min, true); //range with ceiling
167 qreal step = niceNumber(range / (ticksCount - 1), false);
167 qreal step = niceNumber(range / (ticksCount - 1), false);
168 min = qFloor(min / step);
168 min = qFloor(min / step);
169 max = qCeil(max / step);
169 max = qCeil(max / step);
170 ticksCount = int(max - min) + 1;
170 ticksCount = int(max - min) + 1;
171 min *= step;
171 min *= step;
172 max *= step;
172 max *= step;
173 }
173 }
174
174
175 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
175 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
176
176
177 qreal AbstractDomain::niceNumber(qreal x, bool ceiling)
177 qreal AbstractDomain::niceNumber(qreal x, bool ceiling)
178 {
178 {
179 qreal z = qPow(10, qFloor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
179 qreal z = qPow(10, qFloor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
180 qreal q = x / z; //q<10 && q>=1;
180 qreal q = x / z; //q<10 && q>=1;
181
181
182 if (ceiling) {
182 if (ceiling) {
183 if (q <= 1.0) q = 1;
183 if (q <= 1.0) q = 1;
184 else if (q <= 2.0) q = 2;
184 else if (q <= 2.0) q = 2;
185 else if (q <= 5.0) q = 5;
185 else if (q <= 5.0) q = 5;
186 else q = 10;
186 else q = 10;
187 } else {
187 } else {
188 if (q < 1.5) q = 1;
188 if (q < 1.5) q = 1;
189 else if (q < 3.0) q = 2;
189 else if (q < 3.0) q = 2;
190 else if (q < 7.0) q = 5;
190 else if (q < 7.0) q = 5;
191 else q = 10;
191 else q = 10;
192 }
192 }
193 return q * z;
193 return q * z;
194 }
194 }
195
195
196 bool AbstractDomain::attachAxis(QAbstractAxis *axis)
196 bool AbstractDomain::attachAxis(QAbstractAxis *axis)
197 {
197 {
198 if (axis->orientation() == Qt::Vertical) {
198 if (axis->orientation() == Qt::Vertical) {
199 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
199 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
200 QObject::connect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
200 QObject::connect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
201 }
201 }
202
202
203 if (axis->orientation() == Qt::Horizontal) {
203 if (axis->orientation() == Qt::Horizontal) {
204 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
204 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
205 QObject::connect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
205 QObject::connect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
206 }
206 }
207
207
208 return true;
208 return true;
209 }
209 }
210
210
211 bool AbstractDomain::detachAxis(QAbstractAxis *axis)
211 bool AbstractDomain::detachAxis(QAbstractAxis *axis)
212 {
212 {
213 if (axis->orientation() == Qt::Vertical) {
213 if (axis->orientation() == Qt::Vertical) {
214 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
214 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
215 QObject::disconnect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
215 QObject::disconnect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
216 }
216 }
217
217
218 if (axis->orientation() == Qt::Horizontal) {
218 if (axis->orientation() == Qt::Horizontal) {
219 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
219 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
220 QObject::disconnect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
220 QObject::disconnect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
221 }
221 }
222
222
223 return true;
223 return true;
224 }
224 }
225
225
226 // operators
226 // operators
227
227
228 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2)
228 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2)
229 {
229 {
230 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX)
230 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX)
231 && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY)
231 && qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY)
232 && qFuzzyIsNull(domain1.m_minX - domain2.m_minX)
232 && qFuzzyIsNull(domain1.m_minX - domain2.m_minX)
233 && qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
233 && qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
234 }
234 }
235
235
236
236
237 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2)
237 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2)
238 {
238 {
239 return !(domain1 == domain2);
239 return !(domain1 == domain2);
240 }
240 }
241
241
242
242
243 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain)
243 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain)
244 {
244 {
245 #ifdef QT_NO_TEXTSTREAM
245 #ifdef QT_NO_TEXTSTREAM
246 Q_UNUSED(domain)
246 Q_UNUSED(domain)
247 #else
247 #else
248 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
248 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
249 #endif
249 #endif
250 return dbg.maybeSpace();
250 return dbg.maybeSpace();
251 }
251 }
252
252
253 // This function adjusts min/max ranges to failsafe values if negative/zero values are attempted.
253 // This function adjusts min/max ranges to failsafe values if negative/zero values are attempted.
254 void AbstractDomain::adjustLogDomainRanges(qreal &min, qreal &max)
254 void AbstractDomain::adjustLogDomainRanges(qreal &min, qreal &max)
255 {
255 {
256 if (min <= 0) {
256 if (min <= 0) {
257 min = 1.0;
257 min = 1.0;
258 if (max <= min)
258 if (max <= min)
259 max = min + 1.0;
259 max = min + 1.0;
260 }
260 }
261 }
261 }
262
262
263
263
264 #include "moc_abstractdomain_p.cpp"
264 #include "moc_abstractdomain_p.cpp"
265
265
266 QTCOMMERCIALCHART_END_NAMESPACE
266 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now