##// END OF EJS Templates
Added attach/dettach axis domain implementations
Marek Rosa -
r2290:f089818f996f
parent child
Show More
@@ -1,318 +1,318
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 "qlogvalueaxis.h"
21 #include "qlogvalueaxis.h"
22 #include "qlogvalueaxis_p.h"
22 #include "qlogvalueaxis_p.h"
23 #include "chartlogvalueaxisx_p.h"
23 #include "chartlogvalueaxisx_p.h"
24 #include "chartlogvalueaxisy_p.h"
24 #include "chartlogvalueaxisy_p.h"
25 #include "abstractdomain_p.h"
25 #include "abstractdomain_p.h"
26 #include <float.h>
26 #include <float.h>
27 #include <cmath>
27 #include <cmath>
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 /*!
30 /*!
31 \class QLogValueAxis
31 \class QLogValueAxis
32 \brief The QLogValueAxis class is used for manipulating chart's axis.
32 \brief The QLogValueAxis class is used for manipulating chart's axis.
33 \mainclass
33 \mainclass
34 */
34 */
35
35
36 /*!
36 /*!
37 \qmlclass DateTimeAxis QLogValueAxis
37 \qmlclass DateTimeAxis QLogValueAxis
38 \brief The DateTimeAxis element is used for manipulating chart's axes
38 \brief The DateTimeAxis element is used for manipulating chart's axes
39 \inherits AbstractAxis
39 \inherits AbstractAxis
40 */
40 */
41
41
42 /*!
42 /*!
43 \property QLogValueAxis::min
43 \property QLogValueAxis::min
44 Defines the minimum value on the axis.
44 Defines the minimum value on the axis.
45 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
45 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
46 */
46 */
47 /*!
47 /*!
48 \qmlproperty real ValuesAxis::min
48 \qmlproperty real ValuesAxis::min
49 Defines the minimum value on the axis.
49 Defines the minimum value on the axis.
50 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
50 When setting this property the max is adjusted if necessary, to ensure that the range remains valid.
51 */
51 */
52
52
53 /*!
53 /*!
54 \property QLogValueAxis::max
54 \property QLogValueAxis::max
55 Defines the maximum value on the axis.
55 Defines the maximum value on the axis.
56 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
56 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
57 */
57 */
58 /*!
58 /*!
59 \qmlproperty real ValuesAxis::max
59 \qmlproperty real ValuesAxis::max
60 Defines the maximum value on the axis.
60 Defines the maximum value on the axis.
61 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
61 When setting this property the min is adjusted if necessary, to ensure that the range remains valid.
62 */
62 */
63
63
64 /*!
64 /*!
65 \fn void QLogValueAxis::minChanged(qreal min)
65 \fn void QLogValueAxis::minChanged(qreal min)
66 Axis emits signal when \a min of axis has changed.
66 Axis emits signal when \a min of axis has changed.
67 */
67 */
68 /*!
68 /*!
69 \qmlsignal ValuesAxis::onMinChanged(qreal min)
69 \qmlsignal ValuesAxis::onMinChanged(qreal min)
70 Axis emits signal when \a min of axis has changed.
70 Axis emits signal when \a min of axis has changed.
71 */
71 */
72
72
73 /*!
73 /*!
74 \fn void QLogValueAxis::maxChanged(qreal max)
74 \fn void QLogValueAxis::maxChanged(qreal max)
75 Axis emits signal when \a max of axis has changed.
75 Axis emits signal when \a max of axis has changed.
76 */
76 */
77 /*!
77 /*!
78 \qmlsignal ValuesAxis::onMaxChanged(qreal max)
78 \qmlsignal ValuesAxis::onMaxChanged(qreal max)
79 Axis emits signal when \a max of axis has changed.
79 Axis emits signal when \a max of axis has changed.
80 */
80 */
81
81
82 /*!
82 /*!
83 \fn void QLogValueAxis::rangeChanged(qreal min, qreal max)
83 \fn void QLogValueAxis::rangeChanged(qreal min, qreal max)
84 Axis emits signal when \a min or \a max of axis has changed.
84 Axis emits signal when \a min or \a max of axis has changed.
85 */
85 */
86
86
87 /*!
87 /*!
88 Constructs an axis object which is a child of \a parent.
88 Constructs an axis object which is a child of \a parent.
89 */
89 */
90 QLogValueAxis::QLogValueAxis(QObject *parent) :
90 QLogValueAxis::QLogValueAxis(QObject *parent) :
91 QAbstractAxis(*new QLogValueAxisPrivate(this), parent)
91 QAbstractAxis(*new QLogValueAxisPrivate(this), parent)
92 {
92 {
93
93
94 }
94 }
95
95
96 /*!
96 /*!
97 \internal
97 \internal
98 */
98 */
99 QLogValueAxis::QLogValueAxis(QLogValueAxisPrivate &d, QObject *parent) : QAbstractAxis(d, parent)
99 QLogValueAxis::QLogValueAxis(QLogValueAxisPrivate &d, QObject *parent) : QAbstractAxis(d, parent)
100 {
100 {
101
101
102 }
102 }
103
103
104 /*!
104 /*!
105 Destroys the object
105 Destroys the object
106 */
106 */
107 QLogValueAxis::~QLogValueAxis()
107 QLogValueAxis::~QLogValueAxis()
108 {
108 {
109
109
110 }
110 }
111
111
112 void QLogValueAxis::setMin(qreal min)
112 void QLogValueAxis::setMin(qreal min)
113 {
113 {
114 Q_D(QLogValueAxis);
114 Q_D(QLogValueAxis);
115 setRange(min, qMax(d->m_max, min));
115 setRange(min, qMax(d->m_max, min));
116 }
116 }
117
117
118 qreal QLogValueAxis::min() const
118 qreal QLogValueAxis::min() const
119 {
119 {
120 Q_D(const QLogValueAxis);
120 Q_D(const QLogValueAxis);
121 return d->m_min;
121 return d->m_min;
122 }
122 }
123
123
124 void QLogValueAxis::setMax(qreal max)
124 void QLogValueAxis::setMax(qreal max)
125 {
125 {
126 Q_D(QLogValueAxis);
126 Q_D(QLogValueAxis);
127 setRange(qMin(d->m_min, max), max);
127 setRange(qMin(d->m_min, max), max);
128 }
128 }
129
129
130 qreal QLogValueAxis::max() const
130 qreal QLogValueAxis::max() const
131 {
131 {
132 Q_D(const QLogValueAxis);
132 Q_D(const QLogValueAxis);
133 return d->m_max;
133 return d->m_max;
134 }
134 }
135
135
136 /*!
136 /*!
137 Sets range from \a min to \a max on the axis.
137 Sets range from \a min to \a max on the axis.
138 If min is greater than max then this function returns without making any changes.
138 If min is greater than max then this function returns without making any changes.
139 */
139 */
140 void QLogValueAxis::setRange(qreal min, qreal max)
140 void QLogValueAxis::setRange(qreal min, qreal max)
141 {
141 {
142 Q_D(QLogValueAxis);
142 Q_D(QLogValueAxis);
143 bool changed = false;
143 bool changed = false;
144
144
145 if (min > max)
145 if (min > max)
146 return;
146 return;
147
147
148 if (min > 0) {
148 if (min > 0) {
149 if (!qFuzzyCompare(d->m_min, min)) {
149 if (!qFuzzyCompare(d->m_min, min)) {
150 d->m_min = min;
150 d->m_min = min;
151 changed = true;
151 changed = true;
152 emit minChanged(min);
152 emit minChanged(min);
153 }
153 }
154
154
155 if (!qFuzzyCompare(d->m_max, max)) {
155 if (!qFuzzyCompare(d->m_max, max)) {
156 d->m_max = max;
156 d->m_max = max;
157 changed = true;
157 changed = true;
158 emit maxChanged(max);
158 emit maxChanged(max);
159 }
159 }
160
160
161 if (changed) {
161 if (changed) {
162 emit rangeChanged(min, max);
162 emit rangeChanged(min, max);
163 emit d->rangeChanged(min,max);
163 emit d->rangeChanged(min,max);
164 }
164 }
165 }
165 }
166 }
166 }
167
167
168 void QLogValueAxis::setLabelFormat(const QString &format)
168 void QLogValueAxis::setLabelFormat(const QString &format)
169 {
169 {
170 Q_D(QLogValueAxis);
170 Q_D(QLogValueAxis);
171 d->m_format = format;
171 d->m_format = format;
172 }
172 }
173
173
174 QString QLogValueAxis::labelFormat() const
174 QString QLogValueAxis::labelFormat() const
175 {
175 {
176 Q_D(const QLogValueAxis);
176 Q_D(const QLogValueAxis);
177 return d->m_format;
177 return d->m_format;
178 }
178 }
179
179
180 void QLogValueAxis::setBase(qreal base)
180 void QLogValueAxis::setBase(qreal base)
181 {
181 {
182 // check if base is correct
182 // check if base is correct
183 if (qFuzzyCompare(base, 1))
183 if (qFuzzyCompare(base, 1))
184 return;
184 return;
185
185
186 if (base > 0) {
186 if (base > 0) {
187 Q_D(QLogValueAxis);
187 Q_D(QLogValueAxis);
188 d->m_base = base;
188 d->m_base = base;
189 emit d->baseChanged(base);
189 emit baseChanged(base);
190 }
190 }
191 }
191 }
192
192
193 qreal QLogValueAxis::base() const
193 qreal QLogValueAxis::base() const
194 {
194 {
195 Q_D(const QLogValueAxis);
195 Q_D(const QLogValueAxis);
196 return d->m_base;
196 return d->m_base;
197 }
197 }
198
198
199 /*!
199 /*!
200 Returns the type of the axis
200 Returns the type of the axis
201 */
201 */
202 QAbstractAxis::AxisType QLogValueAxis::type() const
202 QAbstractAxis::AxisType QLogValueAxis::type() const
203 {
203 {
204 return AxisTypeLogValue;
204 return AxisTypeLogValue;
205 }
205 }
206
206
207 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
207 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
208
208
209 QLogValueAxisPrivate::QLogValueAxisPrivate(QLogValueAxis *q)
209 QLogValueAxisPrivate::QLogValueAxisPrivate(QLogValueAxis *q)
210 : QAbstractAxisPrivate(q),
210 : QAbstractAxisPrivate(q),
211 m_min(1),
211 m_min(1),
212 m_max(10),
212 m_max(10),
213 m_base(10),
213 m_base(10),
214 m_format(QString::null)
214 m_format(QString::null)
215 {
215 {
216 }
216 }
217
217
218 QLogValueAxisPrivate::~QLogValueAxisPrivate()
218 QLogValueAxisPrivate::~QLogValueAxisPrivate()
219 {
219 {
220
220
221 }
221 }
222
222
223 void QLogValueAxisPrivate::setMin(const QVariant &min)
223 void QLogValueAxisPrivate::setMin(const QVariant &min)
224 {
224 {
225 Q_Q(QLogValueAxis);
225 Q_Q(QLogValueAxis);
226 bool ok;
226 bool ok;
227 qreal value = min.toReal(&ok);
227 qreal value = min.toReal(&ok);
228 if (ok)
228 if (ok)
229 q->setMin(value);
229 q->setMin(value);
230 }
230 }
231
231
232 void QLogValueAxisPrivate::setMax(const QVariant &max)
232 void QLogValueAxisPrivate::setMax(const QVariant &max)
233 {
233 {
234
234
235 Q_Q(QLogValueAxis);
235 Q_Q(QLogValueAxis);
236 bool ok;
236 bool ok;
237 qreal value = max.toReal(&ok);
237 qreal value = max.toReal(&ok);
238 if (ok)
238 if (ok)
239 q->setMax(value);
239 q->setMax(value);
240 }
240 }
241
241
242 void QLogValueAxisPrivate::setRange(const QVariant &min, const QVariant &max)
242 void QLogValueAxisPrivate::setRange(const QVariant &min, const QVariant &max)
243 {
243 {
244 Q_Q(QLogValueAxis);
244 Q_Q(QLogValueAxis);
245 bool ok1;
245 bool ok1;
246 bool ok2;
246 bool ok2;
247 qreal value1 = min.toReal(&ok1);
247 qreal value1 = min.toReal(&ok1);
248 qreal value2 = max.toReal(&ok2);
248 qreal value2 = max.toReal(&ok2);
249 if (ok1 && ok2)
249 if (ok1 && ok2)
250 q->setRange(value1, value2);
250 q->setRange(value1, value2);
251 }
251 }
252
252
253 void QLogValueAxisPrivate::setRange(qreal min, qreal max)
253 void QLogValueAxisPrivate::setRange(qreal min, qreal max)
254 {
254 {
255 Q_Q(QLogValueAxis);
255 Q_Q(QLogValueAxis);
256 bool changed = false;
256 bool changed = false;
257
257
258 if (min > max)
258 if (min > max)
259 return;
259 return;
260
260
261 if (min > 0) {
261 if (min > 0) {
262 if (!qFuzzyCompare(m_min, min)) {
262 if (!qFuzzyCompare(m_min, min)) {
263 m_min = min;
263 m_min = min;
264 changed = true;
264 changed = true;
265 emit q->minChanged(min);
265 emit q->minChanged(min);
266 }
266 }
267
267
268 if (!qFuzzyCompare(m_max, max)) {
268 if (!qFuzzyCompare(m_max, max)) {
269 m_max = max;
269 m_max = max;
270 changed = true;
270 changed = true;
271 emit q->maxChanged(max);
271 emit q->maxChanged(max);
272 }
272 }
273
273
274 if (changed) {
274 if (changed) {
275 emit q->rangeChanged(min, max);
275 emit q->rangeChanged(min, max);
276 emit rangeChanged(min,max);
276 emit rangeChanged(min,max);
277 }
277 }
278 }
278 }
279 }
279 }
280
280
281 void QLogValueAxisPrivate::initializeGraphics(QGraphicsItem* parent)
281 void QLogValueAxisPrivate::initializeGraphics(QGraphicsItem* parent)
282 {
282 {
283 Q_Q(QLogValueAxis);
283 Q_Q(QLogValueAxis);
284 ChartAxis* axis(0);
284 ChartAxis* axis(0);
285 if (orientation() == Qt::Vertical)
285 if (orientation() == Qt::Vertical)
286 axis = new ChartLogValueAxisY(q,parent);
286 axis = new ChartLogValueAxisY(q,parent);
287 if (orientation() == Qt::Horizontal)
287 if (orientation() == Qt::Horizontal)
288 axis = new ChartLogValueAxisX(q,parent);
288 axis = new ChartLogValueAxisX(q,parent);
289
289
290 m_item.reset(axis);
290 m_item.reset(axis);
291 QAbstractAxisPrivate::initializeGraphics(parent);
291 QAbstractAxisPrivate::initializeGraphics(parent);
292 }
292 }
293
293
294
294
295 void QLogValueAxisPrivate::initializeDomain(AbstractDomain *domain)
295 void QLogValueAxisPrivate::initializeDomain(AbstractDomain *domain)
296 {
296 {
297 if (orientation() == Qt::Vertical) {
297 if (orientation() == Qt::Vertical) {
298 if(!qFuzzyCompare(m_max, m_min)) {
298 if(!qFuzzyCompare(m_max, m_min)) {
299 domain->setRangeY(m_min, m_max);
299 domain->setRangeY(m_min, m_max);
300 }
300 }
301 else {
301 else {
302 setRange(domain->minY() + 1, domain->maxY());
302 setRange(domain->minY() + 1, domain->maxY());
303 }
303 }
304 }
304 }
305 if (orientation() == Qt::Horizontal) {
305 if (orientation() == Qt::Horizontal) {
306 if(!qFuzzyCompare(m_max, m_min)) {
306 if(!qFuzzyCompare(m_max, m_min)) {
307 domain->setRangeX(m_min, m_max);
307 domain->setRangeX(m_min, m_max);
308 }
308 }
309 else {
309 else {
310 setRange(domain->minX() + 1, domain->maxX());
310 setRange(domain->minX() + 1, domain->maxX());
311 }
311 }
312 }
312 }
313 }
313 }
314
314
315 #include "moc_qlogvalueaxis.cpp"
315 #include "moc_qlogvalueaxis.cpp"
316 #include "moc_qlogvalueaxis_p.cpp"
316 #include "moc_qlogvalueaxis_p.cpp"
317
317
318 QTCOMMERCIALCHART_END_NAMESPACE
318 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,74 +1,75
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 #ifndef QLOGVALUEAXIS_H
21 #ifndef QLOGVALUEAXIS_H
22 #define QLOGVALUEAXIS_H
22 #define QLOGVALUEAXIS_H
23
23
24 #include "qabstractaxis.h"
24 #include "qabstractaxis.h"
25
25
26 class QDateTime;
26 class QDateTime;
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 class QLogValueAxisPrivate;
30 class QLogValueAxisPrivate;
31
31
32 class QTCOMMERCIALCHART_EXPORT QLogValueAxis : public QAbstractAxis
32 class QTCOMMERCIALCHART_EXPORT QLogValueAxis : public QAbstractAxis
33 {
33 {
34 Q_OBJECT
34 Q_OBJECT
35 Q_PROPERTY(qreal min READ min WRITE setMin NOTIFY minChanged)
35 Q_PROPERTY(qreal min READ min WRITE setMin NOTIFY minChanged)
36 Q_PROPERTY(qreal max READ max WRITE setMax NOTIFY maxChanged)
36 Q_PROPERTY(qreal max READ max WRITE setMax NOTIFY maxChanged)
37 Q_PROPERTY(QString labelFormat READ labelFormat WRITE setLabelFormat)
37 Q_PROPERTY(QString labelFormat READ labelFormat WRITE setLabelFormat)
38
38
39 public:
39 public:
40 explicit QLogValueAxis(QObject *parent = 0);
40 explicit QLogValueAxis(QObject *parent = 0);
41 ~QLogValueAxis();
41 ~QLogValueAxis();
42
42
43 protected:
43 protected:
44 QLogValueAxis(QLogValueAxisPrivate &d, QObject *parent = 0);
44 QLogValueAxis(QLogValueAxisPrivate &d, QObject *parent = 0);
45
45
46 public:
46 public:
47 AxisType type() const;
47 AxisType type() const;
48
48
49 //range handling
49 //range handling
50 void setMin(qreal min);
50 void setMin(qreal min);
51 qreal min() const;
51 qreal min() const;
52 void setMax(qreal max);
52 void setMax(qreal max);
53 qreal max() const;
53 qreal max() const;
54 void setRange(qreal min, qreal max);
54 void setRange(qreal min, qreal max);
55
55
56 void setLabelFormat(const QString &format);
56 void setLabelFormat(const QString &format);
57 QString labelFormat() const;
57 QString labelFormat() const;
58
58
59 void setBase(qreal base);
59 void setBase(qreal base);
60 qreal base() const;
60 qreal base() const;
61
61
62 Q_SIGNALS:
62 Q_SIGNALS:
63 void minChanged(qreal min);
63 void minChanged(qreal min);
64 void maxChanged(qreal max);
64 void maxChanged(qreal max);
65 void rangeChanged(qreal min, qreal max);
65 void rangeChanged(qreal min, qreal max);
66 void baseChanged(qreal base);
66
67
67 private:
68 private:
68 Q_DECLARE_PRIVATE(QLogValueAxis)
69 Q_DECLARE_PRIVATE(QLogValueAxis)
69 Q_DISABLE_COPY(QLogValueAxis)
70 Q_DISABLE_COPY(QLogValueAxis)
70 };
71 };
71
72
72 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
73
74
74 #endif // QLOGVALUEAXIS_H
75 #endif // QLOGVALUEAXIS_H
@@ -1,72 +1,69
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QLOGVALUEAXIS_P_H
30 #ifndef QLOGVALUEAXIS_P_H
31 #define QLOGVALUEAXIS_P_H
31 #define QLOGVALUEAXIS_P_H
32
32
33 #include "qlogvalueaxis.h"
33 #include "qlogvalueaxis.h"
34 #include "qabstractaxis_p.h"
34 #include "qabstractaxis_p.h"
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37
37
38 class QLogValueAxisPrivate : public QAbstractAxisPrivate
38 class QLogValueAxisPrivate : public QAbstractAxisPrivate
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 QLogValueAxisPrivate(QLogValueAxis *q);
42 QLogValueAxisPrivate(QLogValueAxis *q);
43 ~QLogValueAxisPrivate();
43 ~QLogValueAxisPrivate();
44
44
45 public:
45 public:
46 void initializeGraphics(QGraphicsItem* parent);
46 void initializeGraphics(QGraphicsItem* parent);
47 void initializeDomain(AbstractDomain *domain);
47 void initializeDomain(AbstractDomain *domain);
48
48
49 qreal min() { return m_min; }
49 qreal min() { return m_min; }
50 qreal max() { return m_max; }
50 qreal max() { return m_max; }
51 void setRange(qreal min,qreal max);
51 void setRange(qreal min,qreal max);
52
52
53 protected:
53 protected:
54 void setMin(const QVariant &min);
54 void setMin(const QVariant &min);
55 void setMax(const QVariant &max);
55 void setMax(const QVariant &max);
56 void setRange(const QVariant &min, const QVariant &max);
56 void setRange(const QVariant &min, const QVariant &max);
57 int tickCount() const;
57 int tickCount() const;
58
58
59 Q_SIGNALS:
60 void baseChanged(qreal base);
61
62 protected:
59 protected:
63 qreal m_min;
60 qreal m_min;
64 qreal m_max;
61 qreal m_max;
65 qreal m_base;
62 qreal m_base;
66 QString m_format;
63 QString m_format;
67 Q_DECLARE_PUBLIC(QLogValueAxis)
64 Q_DECLARE_PUBLIC(QLogValueAxis)
68 };
65 };
69
66
70 QTCOMMERCIALCHART_END_NAMESPACE
67 QTCOMMERCIALCHART_END_NAMESPACE
71
68
72 #endif // QLOGVALUEAXIS_P_H
69 #endif // QLOGVALUEAXIS_P_H
@@ -1,182 +1,221
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 "logxlogydomain_p.h"
21 #include "logxlogydomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "qlogvalueaxis.h"
23 #include <qmath.h>
24 #include <qmath.h>
24
25
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
27
27 LogXLogYDomain::LogXLogYDomain(QObject *parent)
28 LogXLogYDomain::LogXLogYDomain(QObject *parent)
28 : AbstractDomain(parent),
29 : AbstractDomain(parent),
29 m_logMinX(0),
30 m_logMinX(0),
30 m_logMaxX(1),
31 m_logMaxX(1),
31 m_logBaseX(10),
32 m_logBaseX(10),
32 m_logMinY(0),
33 m_logMinY(0),
33 m_logMaxY(1),
34 m_logMaxY(1),
34 m_logBaseY(10)
35 m_logBaseY(10)
35 {
36 {
36 }
37 }
37
38
38 LogXLogYDomain::~LogXLogYDomain()
39 LogXLogYDomain::~LogXLogYDomain()
39 {
40 {
40 }
41 }
41
42
42 void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
43 void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
43 {
44 {
44 bool axisXChanged = false;
45 bool axisXChanged = false;
45 bool axisYChanged = false;
46 bool axisYChanged = false;
46
47
47 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
48 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
48 m_minX = minX;
49 m_minX = minX;
49 m_maxX = maxX;
50 m_maxX = maxX;
50 axisXChanged = true;
51 axisXChanged = true;
51 m_logMinX = log10(m_minX) / log10(m_logBaseX);
52 m_logMinX = log10(m_minX) / log10(m_logBaseX);
52 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
53 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
53 if(!m_signalsBlocked)
54 if(!m_signalsBlocked)
54 emit rangeHorizontalChanged(m_minX, m_maxX);
55 emit rangeHorizontalChanged(m_minX, m_maxX);
55 }
56 }
56
57
57 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
58 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
58 m_minY = minY;
59 m_minY = minY;
59 m_maxY = maxY;
60 m_maxY = maxY;
60 axisYChanged = true;
61 axisYChanged = true;
61 m_logMinY = log10(m_minY) / log10(m_logBaseY);
62 m_logMinY = log10(m_minY) / log10(m_logBaseY);
62 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
63 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
63 if(!m_signalsBlocked)
64 if(!m_signalsBlocked)
64 emit rangeVerticalChanged(m_minY, m_maxY);
65 emit rangeVerticalChanged(m_minY, m_maxY);
65 }
66 }
66
67
67 if (axisXChanged || axisYChanged)
68 if (axisXChanged || axisYChanged)
68 emit updated();
69 emit updated();
69 }
70 }
70
71
71 void LogXLogYDomain::zoomIn(const QRectF &rect)
72 void LogXLogYDomain::zoomIn(const QRectF &rect)
72 {
73 {
73 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
74 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
74 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
75 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
75 qreal minX = qPow(m_logBaseX, newLogMinX);
76 qreal minX = qPow(m_logBaseX, newLogMinX);
76 qreal maxX = qPow(m_logBaseX, newLogMaxX);
77 qreal maxX = qPow(m_logBaseX, newLogMaxX);
77
78
78 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
79 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
79 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
80 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
80 qreal minY = qPow(m_logBaseY, newLogMinY);
81 qreal minY = qPow(m_logBaseY, newLogMinY);
81 qreal maxY = qPow(m_logBaseY, newLogMaxY);
82 qreal maxY = qPow(m_logBaseY, newLogMaxY);
82
83
83 setRange(minX, maxX, minY, maxY);
84 setRange(minX, maxX, minY, maxY);
84 }
85 }
85
86
86 void LogXLogYDomain::zoomOut(const QRectF &rect)
87 void LogXLogYDomain::zoomOut(const QRectF &rect)
87 {
88 {
88 qreal ratioX = m_size.width()/rect.width();
89 qreal ratioX = m_size.width()/rect.width();
89 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
90 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
90 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
91 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
91 qreal minX = qPow(m_logBaseX, newLogMinX);
92 qreal minX = qPow(m_logBaseX, newLogMinX);
92 qreal maxX = qPow(m_logBaseX, newLogMaxX);
93 qreal maxX = qPow(m_logBaseX, newLogMaxX);
93
94
94 qreal ratioY = m_size.height()/rect.height();
95 qreal ratioY = m_size.height()/rect.height();
95 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
96 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
96 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
97 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
97 qreal minY = qPow(m_logBaseY, newLogMinY);
98 qreal minY = qPow(m_logBaseY, newLogMinY);
98 qreal maxY = qPow(m_logBaseY, newLogMaxY);
99 qreal maxY = qPow(m_logBaseY, newLogMaxY);
99
100
100 setRange(minX, maxX, minY, maxY);
101 setRange(minX, maxX, minY, maxY);
101 }
102 }
102
103
103 void LogXLogYDomain::move(qreal dx, qreal dy)
104 void LogXLogYDomain::move(qreal dx, qreal dy)
104 {
105 {
105 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
106 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
106 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
107 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
107 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
108 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
108
109
109 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
110 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
110 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
111 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
111 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
112 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
112
113
113 setRange(minX, maxX, minY, maxY);
114 setRange(minX, maxX, minY, maxY);
114 }
115 }
115
116
116 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point) const
117 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point) const
117 {
118 {
118 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
119 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
119 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
120 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
120 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
121 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
121 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
122 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
122 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
123 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
123 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
124 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
124 return QPointF(x, y);
125 return QPointF(x, y);
125 }
126 }
126
127
127 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
128 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
128 {
129 {
129 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
130 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
130 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
131 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
131 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
132 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
132 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
133 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
133
134
134 QVector<QPointF> result;
135 QVector<QPointF> result;
135 result.resize(vector.count());
136 result.resize(vector.count());
136
137
137 for (int i = 0; i < vector.count(); ++i) {
138 for (int i = 0; i < vector.count(); ++i) {
138 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
139 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
139 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
140 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
140 result[i].setX(x);
141 result[i].setX(x);
141 result[i].setY(y);
142 result[i].setY(y);
142 }
143 }
143 return result;
144 return result;
144 }
145 }
145
146
146 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
147 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
147 {
148 {
148 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
149 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
149 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
150 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
150 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
151 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
152 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
152 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
153 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
154 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
154 return QPointF(x, y);
155 return QPointF(x, y);
155 }
156 }
156
157
158 bool LogXLogYDomain::attachAxis(QAbstractAxis* axis)
159 {
160 AbstractDomain::attachAxis(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162
163 if(logAxis && logAxis->orientation()==Qt::Vertical)
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
165
166 if(logAxis && logAxis->orientation()==Qt::Horizontal)
167 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
168
169 return true;
170 }
171
172 bool LogXLogYDomain::detachAxis(QAbstractAxis* axis)
173 {
174 AbstractDomain::detachAxis(axis);
175 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
176
177 if(logAxis && logAxis->orientation()==Qt::Vertical)
178 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
179
180 if(logAxis && logAxis->orientation()==Qt::Horizontal)
181 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
182
183 return true;
184 }
185
186 void LogXLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
187 {
188 m_logBaseY = baseY;
189 }
190
191 void LogXLogYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
192 {
193 m_logBaseX = baseX;
194 }
195
157 // operators
196 // operators
158
197
159 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
198 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
160 {
199 {
161 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
200 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
162 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
201 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
163 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
202 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
164 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
203 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
165 }
204 }
166
205
167
206
168 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
207 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
169 {
208 {
170 return !(domain1 == domain2);
209 return !(domain1 == domain2);
171 }
210 }
172
211
173
212
174 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
213 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
175 {
214 {
176 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
215 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
177 return dbg.maybeSpace();
216 return dbg.maybeSpace();
178 }
217 }
179
218
180 #include "moc_logxlogydomain_p.cpp"
219 #include "moc_logxlogydomain_p.cpp"
181
220
182 QTCOMMERCIALCHART_END_NAMESPACE
221 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,72 +1,79
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef LOGXLOGYDOMAIN_H
30 #ifndef LOGXLOGYDOMAIN_H
31 #define LOGXLOGYDOMAIN_H
31 #define LOGXLOGYDOMAIN_H
32 #include "abstractdomain_p.h"
32 #include "abstractdomain_p.h"
33 #include <QRectF>
33 #include <QRectF>
34 #include <QSizeF>
34 #include <QSizeF>
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37
37
38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT LogXLogYDomain: public AbstractDomain
38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT LogXLogYDomain: public AbstractDomain
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 explicit LogXLogYDomain(QObject *object = 0);
42 explicit LogXLogYDomain(QObject *object = 0);
43 virtual ~LogXLogYDomain();
43 virtual ~LogXLogYDomain();
44
44
45 DomainType type(){ return AbstractDomain::LogXLogYDomain;}
45 DomainType type(){ return AbstractDomain::LogXLogYDomain;}
46
46
47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
48
48
49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2);
49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2);
50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2);
50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2);
51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain);
51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain);
52
52
53 void zoomIn(const QRectF &rect);
53 void zoomIn(const QRectF &rect);
54 void zoomOut(const QRectF &rect);
54 void zoomOut(const QRectF &rect);
55 void move(qreal dx, qreal dy);
55 void move(qreal dx, qreal dy);
56
56
57 QPointF calculateGeometryPoint(const QPointF &point) const;
57 QPointF calculateGeometryPoint(const QPointF &point) const;
58 QPointF calculateDomainPoint(const QPointF &point) const;
58 QPointF calculateDomainPoint(const QPointF &point) const;
59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
60
60
61 bool attachAxis(QAbstractAxis* axis);
62 bool detachAxis(QAbstractAxis* axis);
63
64 public Q_SLOTS:
65 void handleVerticalAxisBaseChanged(qreal baseY);
66 void handleHorizontalAxisBaseChanged(qreal baseX);
67
61 private:
68 private:
62 qreal m_logMinX;
69 qreal m_logMinX;
63 qreal m_logMaxX;
70 qreal m_logMaxX;
64 qreal m_logBaseX;
71 qreal m_logBaseX;
65 qreal m_logMinY;
72 qreal m_logMinY;
66 qreal m_logMaxY;
73 qreal m_logMaxY;
67 qreal m_logBaseY;
74 qreal m_logBaseY;
68 };
75 };
69
76
70 QTCOMMERCIALCHART_END_NAMESPACE
77 QTCOMMERCIALCHART_END_NAMESPACE
71
78
72 #endif // LOGXLOGYDOMAIN_H
79 #endif // LOGXLOGYDOMAIN_H
@@ -1,182 +1,210
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 "logxydomain_p.h"
21 #include "logxydomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "qlogvalueaxis.h"
23 #include <qmath.h>
24 #include <qmath.h>
24
25
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
27
27 LogXYDomain::LogXYDomain(QObject *parent)
28 LogXYDomain::LogXYDomain(QObject *parent)
28 : AbstractDomain(parent),
29 : AbstractDomain(parent),
29 m_logMinX(0),
30 m_logMinX(0),
30 m_logMaxX(1),
31 m_logMaxX(1),
31 m_logBaseX(10)
32 m_logBaseX(10)
32 {
33 {
33 }
34 }
34
35
35 LogXYDomain::~LogXYDomain()
36 LogXYDomain::~LogXYDomain()
36 {
37 {
37 }
38 }
38
39
39 void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 {
41 {
41 bool axisXChanged = false;
42 bool axisXChanged = false;
42 bool axisYChanged = false;
43 bool axisYChanged = false;
43
44
44 if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) {
45 if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) {
45 m_minX = minX;
46 m_minX = minX;
46 m_maxX = maxX;
47 m_maxX = maxX;
47 axisXChanged = true;
48 axisXChanged = true;
48 m_logMinX = log10(m_minX) / log10(m_logBaseX);
49 m_logMinX = log10(m_minX) / log10(m_logBaseX);
49 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
50 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
50 if(!m_signalsBlocked)
51 if(!m_signalsBlocked)
51 emit rangeHorizontalChanged(m_minX, m_maxX);
52 emit rangeHorizontalChanged(m_minX, m_maxX);
52 }
53 }
53
54
54 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
55 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
55 m_minY = minY;
56 m_minY = minY;
56 m_maxY = maxY;
57 m_maxY = maxY;
57 axisYChanged = true;
58 axisYChanged = true;
58 if(!m_signalsBlocked)
59 if(!m_signalsBlocked)
59 emit rangeVerticalChanged(m_minY, m_maxY);
60 emit rangeVerticalChanged(m_minY, m_maxY);
60 }
61 }
61
62
62 if (axisXChanged || axisYChanged)
63 if (axisXChanged || axisYChanged)
63 emit updated();
64 emit updated();
64 }
65 }
65
66
66 void LogXYDomain::zoomIn(const QRectF &rect)
67 void LogXYDomain::zoomIn(const QRectF &rect)
67 {
68 {
68 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
69 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
69 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
70 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
70 qreal minX = qPow(m_logBaseX, newLogMinX);
71 qreal minX = qPow(m_logBaseX, newLogMinX);
71 qreal maxX = qPow(m_logBaseX, newLogMaxX);
72 qreal maxX = qPow(m_logBaseX, newLogMaxX);
72
73
73 qreal dy = spanY() / m_size.height();
74 qreal dy = spanY() / m_size.height();
74 qreal minY = m_minY;
75 qreal minY = m_minY;
75 qreal maxY = m_maxY;
76 qreal maxY = m_maxY;
76
77
77 minY = maxY - dy * rect.bottom();
78 minY = maxY - dy * rect.bottom();
78 maxY = maxY - dy * rect.top();
79 maxY = maxY - dy * rect.top();
79
80
80 setRange(minX, maxX, minY, maxY);
81 setRange(minX, maxX, minY, maxY);
81 }
82 }
82
83
83 void LogXYDomain::zoomOut(const QRectF &rect)
84 void LogXYDomain::zoomOut(const QRectF &rect)
84 {
85 {
85 qreal ratioX = m_size.width()/rect.width();
86 qreal ratioX = m_size.width()/rect.width();
86 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
87 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
87 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
88 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
88 qreal minX = qPow(m_logBaseX, newLogMinX);
89 qreal minX = qPow(m_logBaseX, newLogMinX);
89 qreal maxX = qPow(m_logBaseX, newLogMaxX);
90 qreal maxX = qPow(m_logBaseX, newLogMaxX);
90
91
91 qreal dy = spanY() / rect.height();
92 qreal dy = spanY() / rect.height();
92 qreal minY = m_minY;
93 qreal minY = m_minY;
93 qreal maxY = m_maxY;
94 qreal maxY = m_maxY;
94
95
95 maxY = minY + dy * rect.bottom();
96 maxY = minY + dy * rect.bottom();
96 minY = maxY - dy * m_size.height();
97 minY = maxY - dy * m_size.height();
97
98
98 setRange(minX, maxX, minY, maxY);
99 setRange(minX, maxX, minY, maxY);
99 }
100 }
100
101
101 void LogXYDomain::move(qreal dx, qreal dy)
102 void LogXYDomain::move(qreal dx, qreal dy)
102 {
103 {
103 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
104 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
104 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
105 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
105 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
106 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
106
107
107 qreal y = spanY() / m_size.height();
108 qreal y = spanY() / m_size.height();
108 qreal minY = m_minY;
109 qreal minY = m_minY;
109 qreal maxY = m_maxY;
110 qreal maxY = m_maxY;
110
111
111 if (dy != 0) {
112 if (dy != 0) {
112 minY = minY + y * dy;
113 minY = minY + y * dy;
113 maxY = maxY + y * dy;
114 maxY = maxY + y * dy;
114 }
115 }
115 setRange(minX, maxX, minY, maxY);
116 setRange(minX, maxX, minY, maxY);
116 }
117 }
117
118
118 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point) const
119 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point) const
119 {
120 {
120 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
121 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
121 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
122 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
122 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
123 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
123
124
124 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
125 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
125 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
126 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
126 return QPointF(x, y);
127 return QPointF(x, y);
127 }
128 }
128
129
129 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
130 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
130 {
131 {
131 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
132 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
132 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
133 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
133 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
134 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
134
135
135 QVector<QPointF> result;
136 QVector<QPointF> result;
136 result.resize(vector.count());
137 result.resize(vector.count());
137
138
138 for (int i = 0; i < vector.count(); ++i) {
139 for (int i = 0; i < vector.count(); ++i) {
139 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
140 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
140 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
141 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
141 result[i].setX(x);
142 result[i].setX(x);
142 result[i].setY(y);
143 result[i].setY(y);
143 }
144 }
144 return result;
145 return result;
145 }
146 }
146
147
147 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
148 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
148 {
149 {
149 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
150 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
150 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
151 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
151 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
152 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
152 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
153 qreal x = qPow(m_logBaseX, leftEdgeX + point.x() / deltaX);
153 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
154 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
154 return QPointF(x, y);
155 return QPointF(x, y);
155 }
156 }
156
157
158 bool LogXYDomain::attachAxis(QAbstractAxis* axis)
159 {
160 AbstractDomain::attachAxis(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
162
163 if(logAxis && logAxis->orientation()==Qt::Horizontal)
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
165
166 return true;
167 }
168
169 bool LogXYDomain::detachAxis(QAbstractAxis* axis)
170 {
171 AbstractDomain::detachAxis(axis);
172 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
173
174 if(logAxis && logAxis->orientation()==Qt::Horizontal)
175 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
176
177 return true;
178 }
179
180 void LogXYDomain::handleHorizontalAxisBaseChanged(qreal baseX)
181 {
182 m_logBaseX = baseX;
183 }
184
157 // operators
185 // operators
158
186
159 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
187 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
160 {
188 {
161 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
189 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
162 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
190 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
163 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
191 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
164 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
192 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
165 }
193 }
166
194
167
195
168 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
196 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
169 {
197 {
170 return !(domain1 == domain2);
198 return !(domain1 == domain2);
171 }
199 }
172
200
173
201
174 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
202 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
175 {
203 {
176 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
204 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
177 return dbg.maybeSpace();
205 return dbg.maybeSpace();
178 }
206 }
179
207
180 #include "moc_logxydomain_p.cpp"
208 #include "moc_logxydomain_p.cpp"
181
209
182 QTCOMMERCIALCHART_END_NAMESPACE
210 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,69 +1,75
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef LOGXYDOMAIN_H
30 #ifndef LOGXYDOMAIN_H
31 #define LOGXYDOMAIN_H
31 #define LOGXYDOMAIN_H
32 #include "abstractdomain_p.h"
32 #include "abstractdomain_p.h"
33 #include <QRectF>
33 #include <QRectF>
34 #include <QSizeF>
34 #include <QSizeF>
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37
37
38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT LogXYDomain: public AbstractDomain
38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT LogXYDomain: public AbstractDomain
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 explicit LogXYDomain(QObject *object = 0);
42 explicit LogXYDomain(QObject *object = 0);
43 virtual ~LogXYDomain();
43 virtual ~LogXYDomain();
44
44
45 DomainType type(){ return AbstractDomain::LogXYDomain;}
45 DomainType type(){ return AbstractDomain::LogXYDomain;}
46
46
47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
48
48
49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2);
49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2);
50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2);
50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2);
51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain);
51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain);
52
52
53 void zoomIn(const QRectF &rect);
53 void zoomIn(const QRectF &rect);
54 void zoomOut(const QRectF &rect);
54 void zoomOut(const QRectF &rect);
55 void move(qreal dx, qreal dy);
55 void move(qreal dx, qreal dy);
56
56
57 QPointF calculateGeometryPoint(const QPointF &point) const;
57 QPointF calculateGeometryPoint(const QPointF &point) const;
58 QPointF calculateDomainPoint(const QPointF &point) const;
58 QPointF calculateDomainPoint(const QPointF &point) const;
59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
60
60
61 bool attachAxis(QAbstractAxis* axis);
62 bool detachAxis(QAbstractAxis* axis);
63
64 public Q_SLOTS:
65 void handleHorizontalAxisBaseChanged(qreal baseX);
66
61 private:
67 private:
62 qreal m_logMinX;
68 qreal m_logMinX;
63 qreal m_logMaxX;
69 qreal m_logMaxX;
64 qreal m_logBaseX;
70 qreal m_logBaseX;
65 };
71 };
66
72
67 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
68
74
69 #endif // LOGXYDOMAIN_H
75 #endif // LOGXYDOMAIN_H
@@ -1,183 +1,211
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 "xlogydomain_p.h"
21 #include "xlogydomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "qlogvalueaxis.h"
23 #include <qmath.h>
24 #include <qmath.h>
24
25
25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26
27
27 XLogYDomain::XLogYDomain(QObject *parent)
28 XLogYDomain::XLogYDomain(QObject *parent)
28 : AbstractDomain(parent),
29 : AbstractDomain(parent),
29 m_logMinY(0),
30 m_logMinY(0),
30 m_logMaxY(1),
31 m_logMaxY(1),
31 m_logBaseY(10)
32 m_logBaseY(10)
32 {
33 {
33 }
34 }
34
35
35 XLogYDomain::~XLogYDomain()
36 XLogYDomain::~XLogYDomain()
36 {
37 {
37 }
38 }
38
39
39 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 {
41 {
41 bool axisXChanged = false;
42 bool axisXChanged = false;
42 bool axisYChanged = false;
43 bool axisYChanged = false;
43
44
44 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
45 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
45 m_minX = minX;
46 m_minX = minX;
46 m_maxX = maxX;
47 m_maxX = maxX;
47 axisXChanged = true;
48 axisXChanged = true;
48 if(!m_signalsBlocked)
49 if(!m_signalsBlocked)
49 emit rangeHorizontalChanged(m_minX, m_maxX);
50 emit rangeHorizontalChanged(m_minX, m_maxX);
50 }
51 }
51
52
52 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
53 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
53 m_minY = minY;
54 m_minY = minY;
54 m_maxY = maxY;
55 m_maxY = maxY;
55 axisYChanged = true;
56 axisYChanged = true;
56 m_logMinY = log10(m_minY) / log10(m_logBaseY);
57 m_logMinY = log10(m_minY) / log10(m_logBaseY);
57 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
58 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
58 if(!m_signalsBlocked)
59 if(!m_signalsBlocked)
59 emit rangeVerticalChanged(m_minY, m_maxY);
60 emit rangeVerticalChanged(m_minY, m_maxY);
60 }
61 }
61
62
62 if (axisXChanged || axisYChanged)
63 if (axisXChanged || axisYChanged)
63 emit updated();
64 emit updated();
64 }
65 }
65
66
66 void XLogYDomain::zoomIn(const QRectF &rect)
67 void XLogYDomain::zoomIn(const QRectF &rect)
67 {
68 {
68 qreal dx = spanX() / m_size.width();
69 qreal dx = spanX() / m_size.width();
69 qreal maxX = m_maxX;
70 qreal maxX = m_maxX;
70 qreal minX = m_minX;
71 qreal minX = m_minX;
71
72
72 maxX = minX + dx * rect.right();
73 maxX = minX + dx * rect.right();
73 minX = minX + dx * rect.left();
74 minX = minX + dx * rect.left();
74
75
75 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
76 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
76 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal minY = qPow(m_logBaseY, newLogMinY);
78 qreal minY = qPow(m_logBaseY, newLogMinY);
78 qreal maxY = qPow(m_logBaseY, newLogMaxY);
79 qreal maxY = qPow(m_logBaseY, newLogMaxY);
79
80
80 setRange(minX, maxX, minY, maxY);
81 setRange(minX, maxX, minY, maxY);
81 }
82 }
82
83
83 void XLogYDomain::zoomOut(const QRectF &rect)
84 void XLogYDomain::zoomOut(const QRectF &rect)
84 {
85 {
85 qreal dx = spanX() / rect.width();
86 qreal dx = spanX() / rect.width();
86 qreal maxX = m_maxX;
87 qreal maxX = m_maxX;
87 qreal minX = m_minX;
88 qreal minX = m_minX;
88
89
89 minX = maxX - dx * rect.right();
90 minX = maxX - dx * rect.right();
90 maxX = minX + dx * m_size.width();
91 maxX = minX + dx * m_size.width();
91
92
92 qreal ratioY = m_size.height()/rect.height();
93 qreal ratioY = m_size.height()/rect.height();
93 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
94 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
94 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
95 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
95 qreal minY = qPow(m_logBaseY, newLogMinY);
96 qreal minY = qPow(m_logBaseY, newLogMinY);
96 qreal maxY = qPow(m_logBaseY, newLogMaxY);
97 qreal maxY = qPow(m_logBaseY, newLogMaxY);
97
98
98 setRange(minX, maxX, minY, maxY);
99 setRange(minX, maxX, minY, maxY);
99 }
100 }
100
101
101 void XLogYDomain::move(qreal dx, qreal dy)
102 void XLogYDomain::move(qreal dx, qreal dy)
102 {
103 {
103 qreal x = spanX() / m_size.width();
104 qreal x = spanX() / m_size.width();
104 qreal maxX = m_maxX;
105 qreal maxX = m_maxX;
105 qreal minX = m_minX;
106 qreal minX = m_minX;
106
107
107 if (dx != 0) {
108 if (dx != 0) {
108 minX = minX + x * dx;
109 minX = minX + x * dx;
109 maxX = maxX + x * dx;
110 maxX = maxX + x * dx;
110 }
111 }
111
112
112 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
113 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
113 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
114 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
114 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
115 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
115
116
116 setRange(minX, maxX, minY, maxY);
117 setRange(minX, maxX, minY, maxY);
117 }
118 }
118
119
119 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
120 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
120 {
121 {
121 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
122 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
122 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
123 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
123 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
124 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
124
125
125 qreal x = (point.x() - m_minX) * deltaX;
126 qreal x = (point.x() - m_minX) * deltaX;
126 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
127 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
127 return QPointF(x, y);
128 return QPointF(x, y);
128 }
129 }
129
130
130 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
131 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
131 {
132 {
132 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
133 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
133 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
134 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
134 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
135 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
135
136
136 QVector<QPointF> result;
137 QVector<QPointF> result;
137 result.resize(vector.count());
138 result.resize(vector.count());
138
139
139 for (int i = 0; i < vector.count(); ++i) {
140 for (int i = 0; i < vector.count(); ++i) {
140 qreal x = (vector[i].x() - m_minX) * deltaX;
141 qreal x = (vector[i].x() - m_minX) * deltaX;
141 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
142 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
142 result[i].setX(x);
143 result[i].setX(x);
143 result[i].setY(y);
144 result[i].setY(y);
144 }
145 }
145 return result;
146 return result;
146 }
147 }
147
148
148 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
149 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
149 {
150 {
150 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
151 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
151 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
152 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
152 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
153 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
153 qreal x = point.x() / deltaX + m_minX;
154 qreal x = point.x() / deltaX + m_minX;
154 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
155 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
155 return QPointF(x, y);
156 return QPointF(x, y);
156 }
157 }
157
158
159 bool XLogYDomain::attachAxis(QAbstractAxis* axis)
160 {
161 AbstractDomain::attachAxis(axis);
162 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
163
164 if(logAxis && logAxis->orientation()==Qt::Vertical)
165 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
166
167 return true;
168 }
169
170 bool XLogYDomain::detachAxis(QAbstractAxis* axis)
171 {
172 AbstractDomain::detachAxis(axis);
173 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
174
175 if(logAxis && logAxis->orientation()==Qt::Vertical)
176 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
177
178 return true;
179 }
180
181 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
182 {
183 m_logBaseY = baseY;
184 }
185
158 // operators
186 // operators
159
187
160 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
188 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
161 {
189 {
162 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
190 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
163 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
191 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
164 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
192 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
165 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
193 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
166 }
194 }
167
195
168
196
169 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
197 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
170 {
198 {
171 return !(domain1 == domain2);
199 return !(domain1 == domain2);
172 }
200 }
173
201
174
202
175 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
203 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
176 {
204 {
177 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
205 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
178 return dbg.maybeSpace();
206 return dbg.maybeSpace();
179 }
207 }
180
208
181 #include "moc_xlogydomain_p.cpp"
209 #include "moc_xlogydomain_p.cpp"
182
210
183 QTCOMMERCIALCHART_END_NAMESPACE
211 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,69 +1,75
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 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 Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial 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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef XLOGYDOMAIN_H
30 #ifndef XLOGYDOMAIN_H
31 #define XLOGYDOMAIN_H
31 #define XLOGYDOMAIN_H
32 #include "abstractdomain_p.h"
32 #include "abstractdomain_p.h"
33 #include <QRectF>
33 #include <QRectF>
34 #include <QSizeF>
34 #include <QSizeF>
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37
37
38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT XLogYDomain: public AbstractDomain
38 class QTCOMMERCIALCHART_AUTOTEST_EXPORT XLogYDomain: public AbstractDomain
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 explicit XLogYDomain(QObject *object = 0);
42 explicit XLogYDomain(QObject *object = 0);
43 virtual ~XLogYDomain();
43 virtual ~XLogYDomain();
44
44
45 DomainType type(){ return AbstractDomain::XLogYDomain;};
45 DomainType type(){ return AbstractDomain::XLogYDomain;};
46
46
47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
47 void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY);
48
48
49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2);
49 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2);
50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2);
50 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2);
51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain);
51 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain);
52
52
53 void zoomIn(const QRectF &rect);
53 void zoomIn(const QRectF &rect);
54 void zoomOut(const QRectF &rect);
54 void zoomOut(const QRectF &rect);
55 void move(qreal dx, qreal dy);
55 void move(qreal dx, qreal dy);
56
56
57 QPointF calculateGeometryPoint(const QPointF &point) const;
57 QPointF calculateGeometryPoint(const QPointF &point) const;
58 QPointF calculateDomainPoint(const QPointF &point) const;
58 QPointF calculateDomainPoint(const QPointF &point) const;
59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
59 QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const;
60
60
61 bool attachAxis(QAbstractAxis* axis);
62 bool detachAxis(QAbstractAxis* axis);
63
64 public Q_SLOTS:
65 void handleVerticalAxisBaseChanged(qreal baseY);
66
61 private:
67 private:
62 qreal m_logMinY;
68 qreal m_logMinY;
63 qreal m_logMaxY;
69 qreal m_logMaxY;
64 qreal m_logBaseY;
70 qreal m_logBaseY;
65 };
71 };
66
72
67 QTCOMMERCIALCHART_END_NAMESPACE
73 QTCOMMERCIALCHART_END_NAMESPACE
68
74
69 #endif // XLOGYDOMAIN_H
75 #endif // XLOGYDOMAIN_H
General Comments 0
You need to be logged in to leave comments. Login now