1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Charts module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 or (at your option) any later version
20** approved by the KDE Free Qt Foundation. The licenses are as published by
21** the Free Software Foundation and appearing in the file LICENSE.GPL3
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <private/logxypolardomain_p.h>
31#include <private/qabstractaxis_p.h>
32#include <QtCharts/QLogValueAxis>
33#include <QtCore/QtMath>
34#include <cmath>
35
36QT_CHARTS_BEGIN_NAMESPACE
37
38LogXYPolarDomain::LogXYPolarDomain(QObject *parent)
39 : PolarDomain(parent),
40 m_logLeftX(0),
41 m_logRightX(1),
42 m_logBaseX(10)
43{
44}
45
46LogXYPolarDomain::~LogXYPolarDomain()
47{
48}
49
50void LogXYPolarDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
51{
52 bool axisXChanged = false;
53 bool axisYChanged = false;
54
55 adjustLogDomainRanges(min&: minX, max&: maxX);
56
57 if (!qFuzzyCompare(p1: m_minX, p2: minX) || !qFuzzyCompare(p1: m_maxX, p2: maxX)) {
58 m_minX = minX;
59 m_maxX = maxX;
60 axisXChanged = true;
61 qreal logMinX = std::log10(x: m_minX) / std::log10(x: m_logBaseX);
62 qreal logMaxX = std::log10(x: m_maxX) / std::log10(x: m_logBaseX);
63 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
64 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
65 if (!m_signalsBlocked)
66 emit rangeHorizontalChanged(min: m_minX, max: m_maxX);
67 }
68
69 if (!qFuzzyIsNull(d: m_minY - minY) || !qFuzzyIsNull(d: m_maxY - maxY)) {
70 m_minY = minY;
71 m_maxY = maxY;
72 axisYChanged = true;
73 if (!m_signalsBlocked)
74 emit rangeVerticalChanged(min: m_minY, max: m_maxY);
75 }
76
77 if (axisXChanged || axisYChanged)
78 emit updated();
79}
80
81void LogXYPolarDomain::zoomIn(const QRectF &rect)
82{
83 storeZoomReset();
84 qreal logLeftX = rect.left() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
85 qreal logRightX = rect.right() * (m_logRightX - m_logLeftX) / m_size.width() + m_logLeftX;
86 qreal leftX = qPow(x: m_logBaseX, y: logLeftX);
87 qreal rightX = qPow(x: m_logBaseX, y: logRightX);
88 qreal minX = leftX < rightX ? leftX : rightX;
89 qreal maxX = leftX > rightX ? leftX : rightX;
90
91 qreal dy = spanY() / m_size.height();
92 qreal minY = m_minY;
93 qreal maxY = m_maxY;
94
95 minY = maxY - dy * rect.bottom();
96 maxY = maxY - dy * rect.top();
97
98 setRange(minX, maxX, minY, maxY);
99}
100
101void LogXYPolarDomain::zoomOut(const QRectF &rect)
102{
103 storeZoomReset();
104 const qreal factorX = m_size.width() / rect.width();
105
106 qreal logLeftX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 - factorX);
107 qreal logRIghtX = m_logLeftX + (m_logRightX - m_logLeftX) / 2.0 * (1.0 + factorX);
108 qreal leftX = qPow(x: m_logBaseX, y: logLeftX);
109 qreal rightX = qPow(x: m_logBaseX, y: logRIghtX);
110 qreal minX = leftX < rightX ? leftX : rightX;
111 qreal maxX = leftX > rightX ? leftX : rightX;
112
113 qreal dy = spanY() / rect.height();
114 qreal minY = m_minY;
115 qreal maxY = m_maxY;
116
117 maxY = minY + dy * rect.bottom();
118 minY = maxY - dy * m_size.height();
119
120 setRange(minX, maxX, minY, maxY);
121}
122
123void LogXYPolarDomain::move(qreal dx, qreal dy)
124{
125 qreal stepX = dx * (m_logRightX - m_logLeftX) / m_size.width();
126 qreal leftX = qPow(x: m_logBaseX, y: m_logLeftX + stepX);
127 qreal rightX = qPow(x: m_logBaseX, y: m_logRightX + stepX);
128 qreal minX = leftX < rightX ? leftX : rightX;
129 qreal maxX = leftX > rightX ? leftX : rightX;
130
131 qreal y = spanY() / m_radius;
132 qreal minY = m_minY;
133 qreal maxY = m_maxY;
134
135 if (dy != 0) {
136 minY = minY + y * dy;
137 maxY = maxY + y * dy;
138 }
139 setRange(minX, maxX, minY, maxY);
140}
141
142qreal LogXYPolarDomain::toAngularCoordinate(qreal value, bool &ok) const
143{
144 qreal retVal;
145 if (value <= 0) {
146 ok = false;
147 retVal = 0.0;
148 } else {
149 ok = true;
150 const qreal tickSpan = 360.0 / qAbs(t: m_logRightX - m_logLeftX);
151 const qreal logValue = std::log10(x: value) / std::log10(x: m_logBaseX);
152 const qreal valueDelta = logValue - m_logLeftX;
153
154 retVal = valueDelta * tickSpan;
155 }
156 return retVal;
157}
158
159qreal LogXYPolarDomain::toRadialCoordinate(qreal value, bool &ok) const
160{
161 ok = true;
162 if (value < m_minY)
163 value = m_minY;
164
165 // Dont limit the max. The drawing should clip the stuff that goes out of the grid
166 qreal f = (value - m_minY) / (m_maxY - m_minY);
167
168 return f * m_radius;
169}
170
171QPointF LogXYPolarDomain::calculateDomainPoint(const QPointF &point) const
172{
173 if (point == m_center)
174 return QPointF(0.0, m_minY);
175
176 QLineF line(m_center, point);
177 qreal a = 90.0 - line.angle();
178 if (a < 0.0)
179 a += 360.0;
180
181 const qreal deltaX = 360.0 / qAbs(t: m_logRightX - m_logLeftX);
182 a = qPow(x: m_logBaseX, y: m_logLeftX + (a / deltaX));
183
184 qreal r = m_minY + ((m_maxY - m_minY) * (line.length() / m_radius));
185
186 return QPointF(a, r);
187}
188
189bool LogXYPolarDomain::attachAxis(QAbstractAxis *axis)
190{
191 AbstractDomain::attachAxis(axis);
192 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(object: axis);
193
194 if (logAxis && logAxis->orientation() == Qt::Horizontal) {
195 QObject::connect(sender: logAxis, SIGNAL(baseChanged(qreal)), receiver: this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
196 handleHorizontalAxisBaseChanged(baseX: logAxis->base());
197 }
198
199 return true;
200}
201
202bool LogXYPolarDomain::detachAxis(QAbstractAxis *axis)
203{
204 AbstractDomain::detachAxis(axis);
205 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(object: axis);
206
207 if (logAxis && logAxis->orientation() == Qt::Horizontal)
208 QObject::disconnect(sender: logAxis, SIGNAL(baseChanged(qreal)), receiver: this, SLOT(handleHorizontalAxisBaseChanged(qreal)));
209
210 return true;
211}
212
213void LogXYPolarDomain::handleHorizontalAxisBaseChanged(qreal baseX)
214{
215 m_logBaseX = baseX;
216 qreal logMinX = std::log10(x: m_minX) / std::log10(x: m_logBaseX);
217 qreal logMaxX = std::log10(x: m_maxX) / std::log10(x: m_logBaseX);
218 m_logLeftX = logMinX < logMaxX ? logMinX : logMaxX;
219 m_logRightX = logMinX > logMaxX ? logMinX : logMaxX;
220 emit updated();
221}
222
223// operators
224
225bool Q_AUTOTEST_EXPORT operator== (const LogXYPolarDomain &domain1, const LogXYPolarDomain &domain2)
226{
227 return (qFuzzyIsNull(d: domain1.m_maxX - domain2.m_maxX)
228 && qFuzzyIsNull(d: domain1.m_maxY - domain2.m_maxY)
229 && qFuzzyIsNull(d: domain1.m_minX - domain2.m_minX)
230 && qFuzzyIsNull(d: domain1.m_minY - domain2.m_minY));
231}
232
233
234bool Q_AUTOTEST_EXPORT operator!= (const LogXYPolarDomain &domain1, const LogXYPolarDomain &domain2)
235{
236 return !(domain1 == domain2);
237}
238
239
240QDebug Q_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYPolarDomain &domain)
241{
242#ifdef QT_NO_TEXTSTREAM
243 Q_UNUSED(domain)
244#else
245 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
246#endif
247 return dbg.maybeSpace();
248}
249
250QT_CHARTS_END_NAMESPACE
251
252#include "moc_logxypolardomain_p.cpp"
253

source code of qtcharts/src/charts/domain/logxypolardomain.cpp