##// END OF EJS Templates
Log domains zoomin, zoomout and move added
Marek Rosa -
r2280:75ed5c985850
parent child
Show More
@@ -1,407 +1,410
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "chartdataset_p.h"
22 22 #include "chartpresenter_p.h"
23 23 #include "qchart.h"
24 24 #include "qchart_p.h"
25 25 #include "qvalueaxis.h"
26 26 #include "qbarcategoryaxis.h"
27 27 #include "qvalueaxis_p.h"
28 28 #include "qcategoryaxis.h"
29 29 #include "qabstractseries_p.h"
30 30 #include "qabstractbarseries.h"
31 31 #include "qstackedbarseries.h"
32 32 #include "qpercentbarseries.h"
33 33 #include "qpieseries.h"
34 34 #include "chartitem_p.h"
35 35 #include "xydomain_p.h"
36 #include "xlogydomain_p.h"
37 #include "logxydomain_p.h"
38 #include "logxlogydomain_p.h"
36 39
37 40 #ifndef QT_ON_ARM
38 41 #include "qdatetimeaxis.h"
39 42 #endif
40 43
41 44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
42 45
43 46 ChartDataSet::ChartDataSet(QChart *chart)
44 47 : QObject(chart),
45 48 m_chart(chart)
46 49 {
47 50
48 51 }
49 52
50 53 ChartDataSet::~ChartDataSet()
51 54 {
52 55 removeAllSeries();
53 56 removeAllAxes();
54 57 }
55 58
56 59 /*
57 60 * This method adds series to chartdataset, series ownership is taken from caller.
58 61 */
59 62 void ChartDataSet::addSeries(QAbstractSeries *series)
60 63 {
61 64 if (m_seriesList.contains(series)) {
62 65 qWarning() << QObject::tr("Can not add series. Series already on the chart.");
63 66 return;
64 67 }
65 68
66 69 series->d_ptr->initializeDomain();
67 70 m_seriesList.append(series);
68 71
69 72 series->setParent(this); // take ownership
70 73 series->d_ptr->m_chart = m_chart;
71 74
72 75 emit seriesAdded(series);
73 76 }
74 77
75 78 /*
76 79 * This method adds axis to chartdataset, axis ownership is taken from caller.
77 80 */
78 81 void ChartDataSet::addAxis(QAbstractAxis *axis,Qt::Alignment aligment)
79 82 {
80 83 if (m_axisList.contains(axis)) {
81 84 qWarning() << QObject::tr("Can not add axis. Axis already on the chart.");
82 85 return;
83 86 }
84 87
85 88 axis->d_ptr->setAlignment(aligment);
86 89
87 90 if(!axis->alignment()) {
88 91 qWarning()<< QObject::tr("No alignment specified !");
89 92 return;
90 93 };
91 94
92 95 QSharedPointer<AbstractDomain> domain(new XYDomain());
93 96 axis->d_ptr->initializeDomain(domain.data());
94 97
95 98 axis->setParent(this);
96 99 axis->d_ptr->m_chart = m_chart;
97 100 m_axisList.append(axis);
98 101
99 102 emit axisAdded(axis);
100 103 }
101 104
102 105 /*
103 106 * This method removes series form chartdataset, series ownership is passed back to caller.
104 107 */
105 108 void ChartDataSet::removeSeries(QAbstractSeries *series)
106 109 {
107 110
108 111 if (! m_seriesList.contains(series)) {
109 112 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
110 113 return;
111 114 }
112 115
113 116 emit seriesRemoved(series);
114 117 m_seriesList.removeAll(series);
115 118
116 119 series->setParent(0);
117 120 series->d_ptr->m_chart = 0;
118 121 series->d_ptr->m_domain.clear();
119 122
120 123 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
121 124
122 125 foreach(QAbstractAxis* axis, axes) {
123 126 axis->d_ptr->m_series.removeAll(series);
124 127 series->d_ptr->m_axes.removeAll(axis);
125 128 }
126 129 }
127 130
128 131 /*
129 132 * This method removes axis form chartdataset, series ownership is passed back to caller.
130 133 */
131 134 void ChartDataSet::removeAxis(QAbstractAxis *axis)
132 135 {
133 136 if (! m_axisList.contains(axis)) {
134 137 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
135 138 return;
136 139 }
137 140
138 141 emit axisRemoved(axis);
139 142 m_axisList.removeAll(axis);
140 143
141 144 axis->setParent(0);
142 145 axis->d_ptr->m_chart = 0;
143 146
144 147 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
145 148
146 149 foreach(QAbstractSeries* s, series) {
147 150 s->d_ptr->m_axes.removeAll(axis);
148 151 axis->d_ptr->m_series.removeAll(s);
149 152 }
150 153 }
151 154
152 155 /*
153 156 * This method attach axis to series, return true if success.
154 157 */
155 158 bool ChartDataSet::attachAxis(QAbstractSeries* series,QAbstractAxis *axis)
156 159 {
157 160 Q_ASSERT(series);
158 161 Q_ASSERT(axis);
159 162
160 163 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
161 164 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
162 165 QSharedPointer<AbstractDomain> domain = series->d_ptr->m_domain;
163 166
164 167 if (!m_seriesList.contains(series)) {
165 168 qWarning() << QObject::tr("Can not find series on the chart.");
166 169 return false;
167 170 }
168 171
169 172 if (axis && !m_axisList.contains(axis)) {
170 173 qWarning() << QObject::tr("Can not find axis on the chart.");
171 174 return false;
172 175 }
173 176
174 177 if (attachedAxisList.contains(axis)) {
175 178 qWarning() << QObject::tr("Axis already attached to series.");
176 179 return false;
177 180 }
178 181
179 182 Q_ASSERT(!attachedSeriesList.contains(series));
180 183 Q_ASSERT(!domain.isNull());
181 184
182 185 if(attachedSeriesList.isEmpty()){
183 186
184 187 }else{
185 188 domain = attachedSeriesList.first()->d_ptr->domain();
186 189 Q_ASSERT(!domain.isNull());
187 190 series->d_ptr->setDomain(domain);
188 191 }
189 192
190 193 series->d_ptr->m_axes<<axis;
191 194 axis->d_ptr->m_series<<series;
192 195
193 196 series->d_ptr->initializeAxes();
194 197 axis->d_ptr->initializeDomain(domain.data());
195 198
196 199 if(axis->orientation()==Qt::Vertical){
197 200 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), domain.data(), SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
198 201 QObject::connect(domain.data(), SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
199 202 }
200 203
201 204 if(axis->orientation()==Qt::Horizontal){
202 205 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), domain.data(), SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
203 206 QObject::connect(domain.data(), SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
204 207 }
205 208
206 209 return true;
207 210 }
208 211
209 212 /*
210 213 * This method detach axis to series, return true if success.
211 214 */
212 215 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
213 216 {
214 217 Q_ASSERT(series);
215 218 Q_ASSERT(axis);
216 219
217 220 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
218 221 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
219 222 QSharedPointer<AbstractDomain> domain = series->d_ptr->m_domain;
220 223
221 224 if (!m_seriesList.contains(series)) {
222 225 qWarning() << QObject::tr("Can not find series on the chart.");
223 226 return false;
224 227 }
225 228
226 229 if (axis && !m_axisList.contains(axis)) {
227 230 qWarning() << QObject::tr("Can not find axis on the chart.");
228 231 return false;
229 232 }
230 233
231 234 if (!attachedAxisList.contains(axis)) {
232 235 qWarning() << QObject::tr("Axis not attached to series.");
233 236 return false;
234 237 }
235 238
236 239 Q_ASSERT(axis->d_ptr->m_series.contains(series));
237 240
238 241 series->d_ptr->m_axes.removeAll(axis);
239 242 axis->d_ptr->m_series.removeAll(series);
240 243
241 244 if(axis->orientation()==Qt::Vertical){
242 245 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), domain.data(), SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
243 246 QObject::disconnect(domain.data(), SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
244 247 }
245 248
246 249 if(axis->orientation()==Qt::Horizontal){
247 250 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), domain.data(), SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
248 251 QObject::disconnect(domain.data(), SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
249 252 }
250 253
251 254 return true;
252 255 }
253 256
254 257 void ChartDataSet::createDefaultAxes()
255 258 {
256 259 if (m_seriesList.isEmpty())
257 260 return;
258 261
259 262 QAbstractAxis::AxisTypes typeX(0);
260 263 QAbstractAxis::AxisTypes typeY(0);
261 264
262 265 // Remove possibly existing axes
263 266 removeAllAxes();
264 267
265 268 Q_ASSERT(m_axisList.isEmpty());
266 269
267 270 // Select the required axis x and axis y types based on the types of the current series
268 271 foreach(QAbstractSeries* s, m_seriesList) {
269 272 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
270 273 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
271 274 }
272 275
273 276 // Create the axes of the types selected
274 277 createAxes(typeX, Qt::Horizontal);
275 278 createAxes(typeY, Qt::Vertical);
276 279
277 280 }
278 281
279 282 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
280 283 {
281 284 QAbstractAxis *axis = 0;
282 285 //decide what axis should be created
283 286
284 287 switch (type) {
285 288 case QAbstractAxis::AxisTypeValue:
286 289 axis = new QValueAxis(this);
287 290 break;
288 291 case QAbstractAxis::AxisTypeBarCategory:
289 292 axis = new QBarCategoryAxis(this);
290 293 break;
291 294 case QAbstractAxis::AxisTypeCategory:
292 295 axis = new QCategoryAxis(this);
293 296 break;
294 297 #ifndef Q_WS_QWS
295 298 case QAbstractAxis::AxisTypeDateTime:
296 299 axis = new QDateTimeAxis(this);
297 300 break;
298 301 #endif
299 302 default:
300 303 axis = 0;
301 304 break;
302 305 }
303 306
304 307 if (axis) {
305 308 //create one axis for all
306 309
307 310 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
308 311
309 312 foreach(QAbstractSeries *s, m_seriesList) {
310 313 attachAxis(s,axis);
311 314 }
312 315
313 316 }
314 317 else if (!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
315 318 //create separate axis
316 319 foreach(QAbstractSeries *s, m_seriesList) {
317 320 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
318 321 if(axis) {
319 322 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
320 323 attachAxis(s,axis);
321 324 }
322 325 }
323 326 }
324 327 }
325 328
326 329 void ChartDataSet::removeAllSeries()
327 330 {
328 331 foreach (QAbstractSeries *s , m_seriesList)
329 332 removeSeries(s);
330 333
331 334 Q_ASSERT(m_seriesList.count() == 0);
332 335 qDeleteAll(m_seriesList);
333 336 }
334 337
335 338 void ChartDataSet::removeAllAxes()
336 339 {
337 340 foreach (QAbstractAxis *a , m_axisList)
338 341 removeAxis(a);
339 342
340 343 Q_ASSERT(m_axisList.count() == 0);
341 344 qDeleteAll(m_axisList);
342 345 }
343 346
344 347 void ChartDataSet::zoomInDomain(const QRectF &rect)
345 348 {
346 349 QList<AbstractDomain*> domains;
347 350 foreach(QAbstractSeries *s, m_seriesList) {
348 351 AbstractDomain* domain = s->d_ptr->m_domain.data();
349 352 if(domains.contains(domain)) continue;
350 353 s->d_ptr->m_domain->blockAxisSignals(true);
351 354 domains<<domain;
352 355 }
353 356
354 357 foreach(AbstractDomain *domain, domains)
355 358 domain->zoomIn(rect);
356 359
357 360 foreach(AbstractDomain *domain, domains)
358 361 domain->blockAxisSignals(false);
359 362 }
360 363
361 364 void ChartDataSet::zoomOutDomain(const QRectF &rect)
362 365 {
363 366 QList<AbstractDomain*> domains;
364 367 foreach(QAbstractSeries *s, m_seriesList) {
365 368 AbstractDomain* domain = s->d_ptr->m_domain.data();
366 369 if(domains.contains(domain)) continue;
367 370 s->d_ptr->m_domain->blockAxisSignals(true);
368 371 domains<<domain;
369 372 }
370 373
371 374 foreach(AbstractDomain *domain, domains)
372 375 domain->zoomOut(rect);
373 376
374 377 foreach(AbstractDomain *domain, domains)
375 378 domain->blockAxisSignals(false);
376 379 }
377 380
378 381 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
379 382 {
380 383 QList<AbstractDomain*> domains;
381 384 foreach(QAbstractSeries *s, m_seriesList) {
382 385 AbstractDomain* domain = s->d_ptr->m_domain.data();
383 386 if(domains.contains(domain)) continue;
384 387 s->d_ptr->m_domain->blockAxisSignals(true);
385 388 domains<<domain;
386 389 }
387 390
388 391 foreach(AbstractDomain *domain, domains)
389 392 domain->move(dx, dy);
390 393
391 394 foreach(AbstractDomain *domain, domains)
392 395 domain->blockAxisSignals(false);
393 396 }
394 397
395 398 QList<QAbstractAxis*> ChartDataSet::axes() const
396 399 {
397 400 return m_axisList;
398 401 }
399 402
400 403 QList<QAbstractSeries *> ChartDataSet::series() const
401 404 {
402 405 return m_seriesList;
403 406 }
404 407
405 408 #include "moc_chartdataset_p.cpp"
406 409
407 410 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,296 +1,190
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "abstractdomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include <qmath.h>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 AbstractDomain::AbstractDomain(QObject *parent)
28 28 : QObject(parent),
29 29 m_minX(0),
30 30 m_maxX(0),
31 31 m_minY(0),
32 32 m_maxY(0),
33 33 m_axisSignalsBlocked(false)
34 34 {
35 35 }
36 36
37 37 AbstractDomain::~AbstractDomain()
38 38 {
39 39 }
40 40
41 41 void AbstractDomain::setSize(const QSizeF& size)
42 42 {
43 43 if(m_size!=size)
44 44 {
45 45 m_size=size;
46 46 emit updated();
47 47 }
48 48 }
49 49
50 50 QSizeF AbstractDomain::size() const
51 51 {
52 52 return m_size;
53 53 }
54 54
55 //void AbstractDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
56 //{
57 // bool axisXChanged = false;
58 // bool axisYChanged = false;
59
60 // if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
61 // m_minX = minX;
62 // m_maxX = maxX;
63 // axisXChanged = true;
64 // emit rangeHorizontalChanged(m_minX, m_maxX);
65 // }
66
67 // if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
68 // m_minY = minY;
69 // m_maxY = maxY;
70 // axisYChanged = true;
71 // emit rangeVerticalChanged(m_minY, m_maxY);
72 // }
73
74 // if (axisXChanged || axisYChanged)
75 // emit updated();
76 //}
77
78 55 void AbstractDomain::setRangeX(qreal min, qreal max)
79 56 {
80 57 setRange(min, max, m_minY, m_maxY);
81 58 }
82 59
83 60 void AbstractDomain::setRangeY(qreal min, qreal max)
84 61 {
85 62 setRange(m_minX, m_maxX, min, max);
86 63 }
87 64
88 65 void AbstractDomain::setMinX(qreal min)
89 66 {
90 67 setRange(min, m_maxX, m_minY, m_maxY);
91 68 }
92 69
93 70 void AbstractDomain::setMaxX(qreal max)
94 71 {
95 72 setRange(m_minX, max, m_minY, m_maxY);
96 73 }
97 74
98 75 void AbstractDomain::setMinY(qreal min)
99 76 {
100 77 setRange(m_minX, m_maxX, min, m_maxY);
101 78 }
102 79
103 80 void AbstractDomain::setMaxY(qreal max)
104 81 {
105 82 setRange(m_minX, m_maxX, m_minY, max);
106 83 }
107 84
108 85 qreal AbstractDomain::spanX() const
109 86 {
110 87 Q_ASSERT(m_maxX >= m_minX);
111 88 return m_maxX - m_minX;
112 89 }
113 90
114 91 qreal AbstractDomain::spanY() const
115 92 {
116 93 Q_ASSERT(m_maxY >= m_minY);
117 94 return m_maxY - m_minY;
118 95 }
119 96
120 97 bool AbstractDomain::isEmpty() const
121 98 {
122 99 return qFuzzyIsNull(spanX()) || qFuzzyIsNull(spanY()) || m_size.isEmpty() ;
123 100 }
124 101
125 void AbstractDomain::zoomIn(const QRectF &rect)
126 {
127 qreal dx = spanX() / m_size.width();
128 qreal dy = spanY() / m_size.height();
129
130 qreal maxX = m_maxX;
131 qreal minX = m_minX;
132 qreal minY = m_minY;
133 qreal maxY = m_maxY;
134
135 maxX = minX + dx * rect.right();
136 minX = minX + dx * rect.left();
137 minY = maxY - dy * rect.bottom();
138 maxY = maxY - dy * rect.top();
139
140 setRange(minX, maxX, minY, maxY);
141 }
142
143 void AbstractDomain::zoomOut(const QRectF &rect)
144 {
145 qreal dx = spanX() / rect.width();
146 qreal dy = spanY() / rect.height();
147
148 qreal maxX = m_maxX;
149 qreal minX = m_minX;
150 qreal minY = m_minY;
151 qreal maxY = m_maxY;
152
153 minX = maxX - dx * rect.right();
154 maxX = minX + dx * m_size.width();
155 maxY = minY + dy * rect.bottom();
156 minY = maxY - dy * m_size.height();
157
158 setRange(minX, maxX, minY, maxY);
159 }
160
161 void AbstractDomain::move(qreal dx, qreal dy)
162 {
163 qreal x = spanX() / m_size.width();
164 qreal y = spanY() / m_size.height();
165
166 qreal maxX = m_maxX;
167 qreal minX = m_minX;
168 qreal minY = m_minY;
169 qreal maxY = m_maxY;
170
171 if (dx != 0) {
172 minX = minX + x * dx;
173 maxX = maxX + x * dx;
174 }
175 if (dy != 0) {
176 minY = minY + y * dy;
177 maxY = maxY + y * dy;
178 }
179 setRange(minX, maxX, minY, maxY);
180 }
181
182 //QPointF AbstractDomain::calculateGeometryPoint(const QPointF &point) const
183 //{
184 // const qreal deltaX = m_size.width() / (m_maxX - m_minX);
185 // const qreal deltaY = m_size.height() / (m_maxY - m_minY);
186 // qreal x = (point.x() - m_minX) * deltaX;
187 // qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
188 // return QPointF(x, y);
189 //}
190
191 //QVector<QPointF> AbstractDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
192 //{
193 // const qreal deltaX = m_size.width() / (m_maxX - m_minX);
194 // const qreal deltaY = m_size.height() / (m_maxY - m_minY);
195
196 // QVector<QPointF> result;
197 // result.resize(vector.count());
198
199 // for (int i = 0; i < vector.count(); ++i) {
200 // qreal x = (vector[i].x() - m_minX) * deltaX;
201 // qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
202 // result[i].setX(x);
203 // result[i].setY(y);
204 // }
205 // return result;
206 //}
207
208 102 QPointF AbstractDomain::calculateDomainPoint(const QPointF &point) const
209 103 {
210 104 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
211 105 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
212 106 qreal x = point.x() / deltaX + m_minX;
213 107 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
214 108 return QPointF(x, y);
215 109 }
216 110
217 111 // handlers
218 112
219 113 void AbstractDomain::handleVerticalAxisRangeChanged(qreal min, qreal max)
220 114 {
221 115 if(!m_axisSignalsBlocked)
222 116 setRangeY(min, max);
223 117 }
224 118
225 119 void AbstractDomain::handleHorizontalAxisRangeChanged(qreal min, qreal max)
226 120 {
227 121 if(!m_axisSignalsBlocked)
228 122 setRangeX(min, max);
229 123 }
230 124
231 125 void AbstractDomain::blockAxisSignals(bool block)
232 126 {
233 127 m_axisSignalsBlocked=block;
234 128 }
235 129
236 130 //algorithm defined by Paul S.Heckbert GraphicalGems I
237 131
238 132 void AbstractDomain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
239 133 {
240 134 qreal range = niceNumber(max - min, true); //range with ceiling
241 135 qreal step = niceNumber(range / (ticksCount - 1), false);
242 136 min = qFloor(min / step);
243 137 max = qCeil(max / step);
244 138 ticksCount = int(max - min) + 1;
245 139 min *= step;
246 140 max *= step;
247 141 }
248 142
249 143 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
250 144
251 145 qreal AbstractDomain::niceNumber(qreal x, bool ceiling)
252 146 {
253 147 qreal z = qPow(10, qFloor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
254 148 qreal q = x / z; //q<10 && q>=1;
255 149
256 150 if (ceiling) {
257 151 if (q <= 1.0) q = 1;
258 152 else if (q <= 2.0) q = 2;
259 153 else if (q <= 5.0) q = 5;
260 154 else q = 10;
261 155 } else {
262 156 if (q < 1.5) q = 1;
263 157 else if (q < 3.0) q = 2;
264 158 else if (q < 7.0) q = 5;
265 159 else q = 10;
266 160 }
267 161 return q * z;
268 162 }
269 163
270 164
271 165 // operators
272 166
273 167 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2)
274 168 {
275 169 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
276 170 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
277 171 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
278 172 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
279 173 }
280 174
281 175
282 176 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2)
283 177 {
284 178 return !(domain1 == domain2);
285 179 }
286 180
287 181
288 182 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain)
289 183 {
290 184 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
291 185 return dbg.maybeSpace();
292 186 }
293 187
294 188 #include "moc_abstractdomain_p.cpp"
295 189
296 190 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,106 +1,106
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 // W A R N I N G
22 22 // -------------
23 23 //
24 24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 25 // implementation detail. This header file may change from version to
26 26 // version without notice, or even be removed.
27 27 //
28 28 // We mean it.
29 29
30 30 #ifndef ABSTRACTDOMAIN_H
31 31 #define ABSTRACTDOMAIN_H
32 32 #include "qchartglobal.h"
33 33 #include <QRectF>
34 34 #include <QSizeF>
35 35 #include <QDebug>
36 36
37 37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38 38
39 39 class QTCOMMERCIALCHART_AUTOTEST_EXPORT AbstractDomain: public QObject
40 40 {
41 41 Q_OBJECT
42 42 public:
43 43 explicit AbstractDomain(QObject *object = 0);
44 44 virtual ~AbstractDomain();
45 45
46 46 void setSize(const QSizeF& size);
47 47 QSizeF size() const;
48 48
49 49 virtual void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) = 0;
50 50 void setRangeX(qreal min, qreal max);
51 51 void setRangeY(qreal min, qreal max);
52 52 void setMinX(qreal min);
53 53 void setMaxX(qreal max);
54 54 void setMinY(qreal min);
55 55 void setMaxY(qreal max);
56 56
57 57 qreal minX() const { return m_minX; }
58 58 qreal maxX() const { return m_maxX; }
59 59 qreal minY() const { return m_minY; }
60 60 qreal maxY() const { return m_maxY; }
61 61
62 62 qreal spanX() const;
63 63 qreal spanY() const;
64 64 bool isEmpty() const;
65 65
66 66
67 67 void blockAxisSignals(bool block);
68 68 bool axisSignalsBlocked() const { return m_axisSignalsBlocked; }
69 69
70 70
71 71 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2);
72 72 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2);
73 73 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain);
74 74
75 void zoomIn(const QRectF &rect);
76 void zoomOut(const QRectF &rect);
77 void move(qreal dx, qreal dy);
75 virtual void zoomIn(const QRectF &rect) = 0;
76 virtual void zoomOut(const QRectF &rect) = 0;
77 virtual void move(qreal dx, qreal dy) = 0;
78 78
79 79 virtual QPointF calculateGeometryPoint(const QPointF &point) const = 0;
80 80 virtual QPointF calculateDomainPoint(const QPointF &point) const = 0;
81 81 virtual QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const = 0;
82 82
83 83 static void looseNiceNumbers(qreal &min, qreal &max, int &ticksCount);
84 84 static qreal niceNumber(qreal x, bool ceiling);
85 85
86 86 Q_SIGNALS:
87 87 void updated();
88 88 void rangeHorizontalChanged(qreal min, qreal max);
89 89 void rangeVerticalChanged(qreal min, qreal max);
90 90
91 91 public Q_SLOTS:
92 92 void handleVerticalAxisRangeChanged(qreal min,qreal max);
93 93 void handleHorizontalAxisRangeChanged(qreal min,qreal max);
94 94
95 95 protected:
96 96 qreal m_minX;
97 97 qreal m_maxX;
98 98 qreal m_minY;
99 99 qreal m_maxY;
100 100 QSizeF m_size;
101 101 bool m_axisSignalsBlocked;
102 102 };
103 103
104 104 QTCOMMERCIALCHART_END_NAMESPACE
105 105
106 106 #endif // ABSTRACTDOMAIN_H
@@ -1,190 +1,178
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "logxlogydomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include <qmath.h>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 LogXLogYDomain::LogXLogYDomain(QObject *parent)
28 28 : AbstractDomain(parent),
29 29 m_logMinX(0),
30 30 m_logMaxX(1),
31 31 m_logBaseX(10),
32 32 m_logMinY(0),
33 33 m_logMaxY(1),
34 34 m_logBaseY(10)
35 35 {
36 36 }
37 37
38 38 LogXLogYDomain::~LogXLogYDomain()
39 39 {
40 40 }
41 41
42 42 void LogXLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
43 43 {
44 44 bool axisXChanged = false;
45 45 bool axisYChanged = false;
46 46
47 47 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
48 48 m_minX = minX;
49 49 m_maxX = maxX;
50 50 axisXChanged = true;
51 51 m_logMinX = log10(m_minX) / log10(m_logBaseX);
52 52 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
53 53 emit rangeHorizontalChanged(m_minX, m_maxX);
54 54 }
55 55
56 56 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
57 57 m_minY = minY;
58 58 m_maxY = maxY;
59 59 axisYChanged = true;
60 60 m_logMinY = log10(m_minY) / log10(m_logBaseY);
61 61 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
62 62 emit rangeVerticalChanged(m_minY, m_maxY);
63 63 }
64 64
65 65 if (axisXChanged || axisYChanged)
66 66 emit updated();
67 67 }
68 68
69 69 void LogXLogYDomain::zoomIn(const QRectF &rect)
70 70 {
71 qreal dx = spanX() / m_size.width();
72 qreal dy = spanY() / m_size.height();
71 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
72 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
73 qreal minX = qPow(m_logBaseX, newLogMinX);
74 qreal maxX = qPow(m_logBaseX, newLogMaxX);
73 75
74 qreal maxX = m_maxX;
75 qreal minX = m_minX;
76 qreal minY = m_minY;
77 qreal maxY = m_maxY;
78
79 maxX = minX + dx * rect.right();
80 minX = minX + dx * rect.left();
81 minY = maxY - dy * rect.bottom();
82 maxY = maxY - dy * rect.top();
76 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
78 qreal minY = qPow(m_logBaseY, newLogMinY);
79 qreal maxY = qPow(m_logBaseY, newLogMaxY);
83 80
84 81 setRange(minX, maxX, minY, maxY);
85 82 }
86 83
87 84 void LogXLogYDomain::zoomOut(const QRectF &rect)
88 85 {
89 qreal dx = spanX() / rect.width();
90 qreal dy = spanY() / rect.height();
91
92 qreal maxX = m_maxX;
93 qreal minX = m_minX;
94 qreal minY = m_minY;
95 qreal maxY = m_maxY;
96
97 minX = maxX - dx * rect.right();
98 maxX = minX + dx * m_size.width();
99 maxY = minY + dy * rect.bottom();
100 minY = maxY - dy * m_size.height();
86 qreal ratioX = m_size.width()/rect.width();
87 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
88 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
89 qreal minX = qPow(m_logBaseX, newLogMinX);
90 qreal maxX = qPow(m_logBaseX, newLogMaxX);
91
92 qreal ratioY = m_size.height()/rect.height();
93 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
94 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
95 qreal minY = qPow(m_logBaseY, newLogMinY);
96 qreal maxY = qPow(m_logBaseY, newLogMaxY);
101 97
102 98 setRange(minX, maxX, minY, maxY);
103 99 }
104 100
105 101 void LogXLogYDomain::move(qreal dx, qreal dy)
106 102 {
107 qreal x = spanX() / m_size.width();
108 qreal y = spanY() / m_size.height();
103 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
104 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
105 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
109 106
110 qreal maxX = m_maxX;
111 qreal minX = m_minX;
112 qreal minY = m_minY;
113 qreal maxY = m_maxY;
107 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
108 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
109 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
114 110
115 if (dx != 0) {
116 minX = minX + x * dx;
117 maxX = maxX + x * dx;
118 }
119 if (dy != 0) {
120 minY = minY + y * dy;
121 maxY = maxY + y * dy;
122 }
123 111 setRange(minX, maxX, minY, maxY);
124 112 }
125 113
126 114 QPointF LogXLogYDomain::calculateGeometryPoint(const QPointF &point) const
127 115 {
128 116 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
129 117 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
130 118 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
131 119 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
132 120 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
133 121 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
134 122 return QPointF(x, y);
135 123 }
136 124
137 125 QVector<QPointF> LogXLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
138 126 {
139 127 const qreal leftEdgeX= m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
140 128 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
141 129 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
142 130 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
143 131
144 132 QVector<QPointF> result;
145 133 result.resize(vector.count());
146 134
147 135 for (int i = 0; i < vector.count(); ++i) {
148 136 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdgeX * deltaX;
149 137 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdgeY * -deltaY + m_size.height();
150 138 result[i].setX(x);
151 139 result[i].setY(y);
152 140 }
153 141 return result;
154 142 }
155 143
156 144 QPointF LogXLogYDomain::calculateDomainPoint(const QPointF &point) const
157 145 {
158 146 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
159 147 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
160 148 qreal x = point.x() / deltaX + m_minX;
161 149 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
162 150 return QPointF(x, y);
163 151 }
164 152
165 153 // operators
166 154
167 155 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
168 156 {
169 157 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
170 158 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
171 159 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
172 160 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
173 161 }
174 162
175 163
176 164 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXLogYDomain &domain1, const LogXLogYDomain &domain2)
177 165 {
178 166 return !(domain1 == domain2);
179 167 }
180 168
181 169
182 170 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXLogYDomain &domain)
183 171 {
184 172 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
185 173 return dbg.maybeSpace();
186 174 }
187 175
188 176 #include "moc_logxlogydomain_p.cpp"
189 177
190 178 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,185 +1,180
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "logxydomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include <qmath.h>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 LogXYDomain::LogXYDomain(QObject *parent)
28 28 : AbstractDomain(parent),
29 29 m_logMinX(0),
30 30 m_logMaxX(1),
31 31 m_logBaseX(10)
32 32 {
33 33 }
34 34
35 35 LogXYDomain::~LogXYDomain()
36 36 {
37 37 }
38 38
39 39 void LogXYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 40 {
41 41 bool axisXChanged = false;
42 42 bool axisYChanged = false;
43 43
44 44 if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) {
45 45 m_minX = minX;
46 46 m_maxX = maxX;
47 47 axisXChanged = true;
48 48 m_logMinX = log10(m_minX) / log10(m_logBaseX);
49 49 m_logMaxX = log10(m_maxX) / log10(m_logBaseX);
50 50
51 51 emit rangeHorizontalChanged(m_minX, m_maxX);
52 52 }
53 53
54 54 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
55 55 m_minY = minY;
56 56 m_maxY = maxY;
57 57 axisYChanged = true;
58 58 emit rangeVerticalChanged(m_minY, m_maxY);
59 59 }
60 60
61 61 if (axisXChanged || axisYChanged)
62 62 emit updated();
63 63 }
64 64
65 65 void LogXYDomain::zoomIn(const QRectF &rect)
66 66 {
67 qreal dx = spanX() / m_size.width();
68 qreal dy = spanY() / m_size.height();
67 qreal newLogMinX = rect.left() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
68 qreal newLogMaxX = rect.right() * (m_logMaxX - m_logMinX) / m_size.width() + m_logMinX;
69 qreal minX = qPow(m_logBaseX, newLogMinX);
70 qreal maxX = qPow(m_logBaseX, newLogMaxX);
69 71
70 qreal maxX = m_maxX;
71 qreal minX = m_minX;
72 qreal dy = spanY() / m_size.height();
72 73 qreal minY = m_minY;
73 74 qreal maxY = m_maxY;
74 75
75 maxX = minX + dx * rect.right();
76 minX = minX + dx * rect.left();
77 76 minY = maxY - dy * rect.bottom();
78 77 maxY = maxY - dy * rect.top();
79 78
80 79 setRange(minX, maxX, minY, maxY);
81 80 }
82 81
83 82 void LogXYDomain::zoomOut(const QRectF &rect)
84 83 {
85 qreal dx = spanX() / rect.width();
86 qreal dy = spanY() / rect.height();
84 qreal ratioX = m_size.width()/rect.width();
85 qreal newLogMinX = m_logMinX - (m_logMaxX - m_logMinX) / ratioX;
86 qreal newLogMaxX = m_logMaxX + (m_logMaxX - m_logMinX) / ratioX;
87 qreal minX = qPow(m_logBaseX, newLogMinX);
88 qreal maxX = qPow(m_logBaseX, newLogMaxX);
87 89
88 qreal maxX = m_maxX;
89 qreal minX = m_minX;
90 qreal dy = spanY() / rect.height();
90 91 qreal minY = m_minY;
91 92 qreal maxY = m_maxY;
92 93
93 minX = maxX - dx * rect.right();
94 maxX = minX + dx * m_size.width();
95 94 maxY = minY + dy * rect.bottom();
96 95 minY = maxY - dy * m_size.height();
97 96
98 97 setRange(minX, maxX, minY, maxY);
99 98 }
100 99
101 100 void LogXYDomain::move(qreal dx, qreal dy)
102 101 {
103 qreal x = spanX() / m_size.width();
104 qreal y = spanY() / m_size.height();
102 qreal stepX = dx * qAbs(m_logMaxX - m_logMinX) / m_size.width();
103 qreal minX = qPow(m_logBaseX, m_logMinX + stepX);
104 qreal maxX = qPow(m_logBaseX, m_logMaxX + stepX);
105 105
106 qreal maxX = m_maxX;
107 qreal minX = m_minX;
106 qreal y = spanY() / m_size.height();
108 107 qreal minY = m_minY;
109 108 qreal maxY = m_maxY;
110 109
111 if (dx != 0) {
112 minX = minX + x * dx;
113 maxX = maxX + x * dx;
114 }
115 110 if (dy != 0) {
116 111 minY = minY + y * dy;
117 112 maxY = maxY + y * dy;
118 113 }
119 114 setRange(minX, maxX, minY, maxY);
120 115 }
121 116
122 117 QPointF LogXYDomain::calculateGeometryPoint(const QPointF &point) const
123 118 {
124 119 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
125 120 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
126 121 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
127 122
128 123 qreal x = (log10(point.x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
129 124 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
130 125 return QPointF(x, y);
131 126 }
132 127
133 128 QVector<QPointF> LogXYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
134 129 {
135 130 const qreal leftEdge = m_logMinX < m_logMaxX ? m_logMinX : m_logMaxX;
136 131 const qreal deltaX = m_size.width() / qAbs(m_logMaxX - m_logMinX);
137 132 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
138 133
139 134 QVector<QPointF> result;
140 135 result.resize(vector.count());
141 136
142 137 for (int i = 0; i < vector.count(); ++i) {
143 138 qreal x = (log10(vector[i].x()) / log10(m_logBaseX)) * deltaX - leftEdge * deltaX;
144 139 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
145 140 result[i].setX(x);
146 141 result[i].setY(y);
147 142 }
148 143 return result;
149 144 }
150 145
151 146 QPointF LogXYDomain::calculateDomainPoint(const QPointF &point) const
152 147 {
153 148 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
154 149 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
155 150 qreal x = point.x() / deltaX + m_minX;
156 151 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
157 152 return QPointF(x, y);
158 153 }
159 154
160 155 // operators
161 156
162 157 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const LogXYDomain &domain1, const LogXYDomain &domain2)
163 158 {
164 159 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
165 160 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
166 161 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
167 162 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
168 163 }
169 164
170 165
171 166 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const LogXYDomain &domain1, const LogXYDomain &domain2)
172 167 {
173 168 return !(domain1 == domain2);
174 169 }
175 170
176 171
177 172 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const LogXYDomain &domain)
178 173 {
179 174 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
180 175 return dbg.maybeSpace();
181 176 }
182 177
183 178 #include "moc_logxydomain_p.cpp"
184 179
185 180 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,184 +1,180
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "xlogydomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include <qmath.h>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 XLogYDomain::XLogYDomain(QObject *parent)
28 28 : AbstractDomain(parent),
29 29 m_logMinY(0),
30 30 m_logMaxY(1),
31 31 m_logBaseY(10)
32 32 {
33 33 }
34 34
35 35 XLogYDomain::~XLogYDomain()
36 36 {
37 37 }
38 38
39 39 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 40 {
41 41 bool axisXChanged = false;
42 42 bool axisYChanged = false;
43 43
44 44 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
45 45 m_minX = minX;
46 46 m_maxX = maxX;
47 47 axisXChanged = true;
48 48 emit rangeHorizontalChanged(m_minX, m_maxX);
49 49 }
50 50
51 51 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
52 52 m_minY = minY;
53 53 m_maxY = maxY;
54 54 axisYChanged = true;
55 55 m_logMinY = log10(m_minY) / log10(m_logBaseY);
56 56 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
57 57 emit rangeVerticalChanged(m_minY, m_maxY);
58 58 }
59 59
60 60 if (axisXChanged || axisYChanged)
61 61 emit updated();
62 62 }
63 63
64 64 void XLogYDomain::zoomIn(const QRectF &rect)
65 65 {
66 66 qreal dx = spanX() / m_size.width();
67 qreal dy = spanY() / m_size.height();
68
69 67 qreal maxX = m_maxX;
70 68 qreal minX = m_minX;
71 qreal minY = m_minY;
72 qreal maxY = m_maxY;
73 69
74 70 maxX = minX + dx * rect.right();
75 71 minX = minX + dx * rect.left();
76 minY = maxY - dy * rect.bottom();
77 maxY = maxY - dy * rect.top();
72
73 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
74 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
75 qreal minY = qPow(m_logBaseY, newLogMinY);
76 qreal maxY = qPow(m_logBaseY, newLogMaxY);
78 77
79 78 setRange(minX, maxX, minY, maxY);
80 79 }
81 80
82 81 void XLogYDomain::zoomOut(const QRectF &rect)
83 82 {
84 83 qreal dx = spanX() / rect.width();
85 qreal dy = spanY() / rect.height();
86
87 84 qreal maxX = m_maxX;
88 85 qreal minX = m_minX;
89 qreal minY = m_minY;
90 qreal maxY = m_maxY;
91 86
92 87 minX = maxX - dx * rect.right();
93 88 maxX = minX + dx * m_size.width();
94 maxY = minY + dy * rect.bottom();
95 minY = maxY - dy * m_size.height();
89
90 qreal ratioY = m_size.height()/rect.height();
91 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
92 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
93 qreal minY = qPow(m_logBaseY, newLogMinY);
94 qreal maxY = qPow(m_logBaseY, newLogMaxY);
96 95
97 96 setRange(minX, maxX, minY, maxY);
98 97 }
99 98
100 99 void XLogYDomain::move(qreal dx, qreal dy)
101 100 {
102 101 qreal x = spanX() / m_size.width();
103 qreal y = spanY() / m_size.height();
104
105 102 qreal maxX = m_maxX;
106 103 qreal minX = m_minX;
107 qreal minY = m_minY;
108 qreal maxY = m_maxY;
109 104
110 105 if (dx != 0) {
111 106 minX = minX + x * dx;
112 107 maxX = maxX + x * dx;
113 108 }
114 if (dy != 0) {
115 minY = minY + y * dy;
116 maxY = maxY + y * dy;
117 }
109
110 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
111 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
112 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
113
118 114 setRange(minX, maxX, minY, maxY);
119 115 }
120 116
121 117 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
122 118 {
123 119 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
124 120 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
125 121 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
126 122
127 123 qreal x = (point.x() - m_minX) * deltaX;
128 124 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
129 125 return QPointF(x, y);
130 126 }
131 127
132 128 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
133 129 {
134 130 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
135 131 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
136 132 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
137 133
138 134 QVector<QPointF> result;
139 135 result.resize(vector.count());
140 136
141 137 for (int i = 0; i < vector.count(); ++i) {
142 138 qreal x = (vector[i].x() - m_minX) * deltaX;
143 139 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
144 140 result[i].setX(x);
145 141 result[i].setY(y);
146 142 }
147 143 return result;
148 144 }
149 145
150 146 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
151 147 {
152 148 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
153 149 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
154 150 qreal x = point.x() / deltaX + m_minX;
155 151 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
156 152 return QPointF(x, y);
157 153 }
158 154
159 155 // operators
160 156
161 157 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
162 158 {
163 159 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
164 160 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
165 161 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
166 162 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
167 163 }
168 164
169 165
170 166 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
171 167 {
172 168 return !(domain1 == domain2);
173 169 }
174 170
175 171
176 172 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
177 173 {
178 174 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
179 175 return dbg.maybeSpace();
180 176 }
181 177
182 178 #include "moc_xlogydomain_p.cpp"
183 179
184 180 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now