##// END OF EJS Templates
Bugfix resize event during zoomin
Michal Klocek -
r2289:d4cb0061d8bc
parent child
Show More
@@ -1,482 +1,481
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 36 #include "xlogydomain_p.h"
37 37 #include "logxydomain_p.h"
38 38 #include "logxlogydomain_p.h"
39 39
40 40 #ifndef QT_ON_ARM
41 41 #include "qdatetimeaxis.h"
42 42 #endif
43 43
44 44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
45 45
46 46 ChartDataSet::ChartDataSet(QChart *chart)
47 47 : QObject(chart),
48 48 m_chart(chart)
49 49 {
50 50
51 51 }
52 52
53 53 ChartDataSet::~ChartDataSet()
54 54 {
55 55 deleteAllSeries();
56 56 deleteAllAxes();
57 57 }
58 58
59 59 /*
60 60 * This method adds series to chartdataset, series ownership is taken from caller.
61 61 */
62 62 void ChartDataSet::addSeries(QAbstractSeries *series)
63 63 {
64 64 if (m_seriesList.contains(series)) {
65 65 qWarning() << QObject::tr("Can not add series. Series already on the chart.");
66 66 return;
67 67 }
68 68
69 69 series->d_ptr->initializeDomain();
70 70 m_seriesList.append(series);
71 71
72 72 series->setParent(this); // take ownership
73 73 series->d_ptr->m_chart = m_chart;
74 74
75 75 emit seriesAdded(series);
76 76 }
77 77
78 78 /*
79 79 * This method adds axis to chartdataset, axis ownership is taken from caller.
80 80 */
81 81 void ChartDataSet::addAxis(QAbstractAxis *axis,Qt::Alignment aligment)
82 82 {
83 83 if (m_axisList.contains(axis)) {
84 84 qWarning() << QObject::tr("Can not add axis. Axis already on the chart.");
85 85 return;
86 86 }
87 87
88 88 axis->d_ptr->setAlignment(aligment);
89 89
90 90 if(!axis->alignment()) {
91 91 qWarning()<< QObject::tr("No alignment specified !");
92 92 return;
93 93 };
94 94
95 95 QSharedPointer<AbstractDomain> domain(new XYDomain());
96 96 axis->d_ptr->initializeDomain(domain.data());
97 97
98 98 axis->setParent(this);
99 99 axis->d_ptr->m_chart = m_chart;
100 100 m_axisList.append(axis);
101 101
102 102 emit axisAdded(axis);
103 103 }
104 104
105 105 /*
106 106 * This method removes series form chartdataset, series ownership is passed back to caller.
107 107 */
108 108 void ChartDataSet::removeSeries(QAbstractSeries *series)
109 109 {
110 110
111 111 if (! m_seriesList.contains(series)) {
112 112 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
113 113 return;
114 114 }
115 115
116 116 emit seriesRemoved(series);
117 117 m_seriesList.removeAll(series);
118 118
119 119 series->setParent(0);
120 120 series->d_ptr->m_chart = 0;
121 121 series->d_ptr->m_domain.reset(0);
122 122
123 123 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
124 124
125 125 foreach(QAbstractAxis* axis, axes) {
126 126 axis->d_ptr->m_series.removeAll(series);
127 127 series->d_ptr->m_axes.removeAll(axis);
128 128 }
129 129
130 130 }
131 131
132 132 /*
133 133 * This method removes axis form chartdataset, series ownership is passed back to caller.
134 134 */
135 135 void ChartDataSet::removeAxis(QAbstractAxis *axis)
136 136 {
137 137 if (! m_axisList.contains(axis)) {
138 138 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
139 139 return;
140 140 }
141 141
142 142 emit axisRemoved(axis);
143 143 m_axisList.removeAll(axis);
144 144
145 145 axis->setParent(0);
146 146 axis->d_ptr->m_chart = 0;
147 147
148 148 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
149 149
150 150 foreach(QAbstractSeries* s, series) {
151 151 s->d_ptr->m_axes.removeAll(axis);
152 152 axis->d_ptr->m_series.removeAll(s);
153 153 }
154 154 }
155 155
156 156 /*
157 157 * This method attaches axis to series, return true if success.
158 158 */
159 159 bool ChartDataSet::attachAxis(QAbstractSeries* series,QAbstractAxis *axis)
160 160 {
161 161 Q_ASSERT(series);
162 162 Q_ASSERT(axis);
163 163
164 164 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
165 165 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
166 166
167 167 if (!m_seriesList.contains(series)) {
168 168 qWarning() << QObject::tr("Can not find series on the chart.");
169 169 return false;
170 170 }
171 171
172 172 if (axis && !m_axisList.contains(axis)) {
173 173 qWarning() << QObject::tr("Can not find axis on the chart.");
174 174 return false;
175 175 }
176 176
177 177 if (attachedAxisList.contains(axis)) {
178 178 qWarning() << QObject::tr("Axis already attached to series.");
179 179 return false;
180 180 }
181 181
182 182 if (attachedSeriesList.contains(series)) {
183 183 qWarning() << QObject::tr("Axis already attached to series.");
184 184 return false;
185 185 }
186 186
187 187 AbstractDomain* domain = series->d_ptr->domain();
188 188 AbstractDomain::DomainType type = selectDomain(attachedAxisList<<axis);
189 189
190 190 if(type == AbstractDomain::UndefinedDomain) return false;
191 191
192 192 if(domain->type()!=type){
193 193 domain = createDomain(type);
194 194 }
195 195
196 196 if(!domain) return false;
197 197
198 198 if(!domain->attachAxis(axis)) return false;
199 199
200 200 series->d_ptr->m_axes<<axis;
201 201 axis->d_ptr->m_series<<series;
202 202
203 203 if(domain!=series->d_ptr->domain()){
204 204 series->d_ptr->setDomain(domain);
205 205 series->d_ptr->initializeDomain();
206 206 }
207 207 series->d_ptr->initializeAxes();
208 208 axis->d_ptr->initializeDomain(domain);
209 209
210 210 return true;
211 211 }
212 212
213 213 /*
214 214 * This method detaches axis to series, return true if success.
215 215 */
216 216 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
217 217 {
218 218 Q_ASSERT(series);
219 219 Q_ASSERT(axis);
220 220
221 221 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
222 222 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
223 223 AbstractDomain* domain = series->d_ptr->domain();
224 224
225 225 if (!m_seriesList.contains(series)) {
226 226 qWarning() << QObject::tr("Can not find series on the chart.");
227 227 return false;
228 228 }
229 229
230 230 if (axis && !m_axisList.contains(axis)) {
231 231 qWarning() << QObject::tr("Can not find axis on the chart.");
232 232 return false;
233 233 }
234 234
235 235 if (!attachedAxisList.contains(axis)) {
236 236 qWarning() << QObject::tr("Axis not attached to series.");
237 237 return false;
238 238 }
239 239
240 240 Q_ASSERT(axis->d_ptr->m_series.contains(series));
241 241
242 242 domain->detachAxis(axis);
243 243 series->d_ptr->m_axes.removeAll(axis);
244 244 axis->d_ptr->m_series.removeAll(series);
245 245
246 246 return true;
247 247 }
248 248
249 249 void ChartDataSet::createDefaultAxes()
250 250 {
251 251 if (m_seriesList.isEmpty())
252 252 return;
253 253
254 254 QAbstractAxis::AxisTypes typeX(0);
255 255 QAbstractAxis::AxisTypes typeY(0);
256 256
257 257 // Remove possibly existing axes
258 258 deleteAllAxes();
259 259
260 260 Q_ASSERT(m_axisList.isEmpty());
261 261
262 262 // Select the required axis x and axis y types based on the types of the current series
263 263 foreach(QAbstractSeries* s, m_seriesList) {
264 264 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
265 265 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
266 266 }
267 267
268 268 // Create the axes of the types selected
269 269 createAxes(typeX, Qt::Horizontal);
270 270 createAxes(typeY, Qt::Vertical);
271 271
272 272 }
273 273
274 274 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
275 275 {
276 276 QAbstractAxis *axis = 0;
277 277 //decide what axis should be created
278 278
279 279 switch (type) {
280 280 case QAbstractAxis::AxisTypeValue:
281 281 axis = new QValueAxis(this);
282 282 break;
283 283 case QAbstractAxis::AxisTypeBarCategory:
284 284 axis = new QBarCategoryAxis(this);
285 285 break;
286 286 case QAbstractAxis::AxisTypeCategory:
287 287 axis = new QCategoryAxis(this);
288 288 break;
289 289 #ifndef Q_WS_QWS
290 290 case QAbstractAxis::AxisTypeDateTime:
291 291 axis = new QDateTimeAxis(this);
292 292 break;
293 293 #endif
294 294 default:
295 295 axis = 0;
296 296 break;
297 297 }
298 298
299 299 if (axis) {
300 300 //create one axis for all
301 301
302 302 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
303 303
304 304 foreach(QAbstractSeries *s, m_seriesList) {
305 305 attachAxis(s,axis);
306 306 }
307 307
308 308 }
309 309 else if (!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
310 310 //create separate axis
311 311 foreach(QAbstractSeries *s, m_seriesList) {
312 312 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
313 313 if(axis) {
314 314 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
315 315 attachAxis(s,axis);
316 316 }
317 317 }
318 318 }
319 319 }
320 320
321 321 void ChartDataSet::deleteAllSeries()
322 322 {
323 323 foreach (QAbstractSeries *s , m_seriesList){
324 324 removeSeries(s);
325 325 delete s;
326 326 }
327 327 Q_ASSERT(m_seriesList.count() == 0);
328 328 }
329 329
330 330 void ChartDataSet::deleteAllAxes()
331 331 {
332 332 foreach (QAbstractAxis *a , m_axisList){
333 333 removeAxis(a);
334 334 delete a;
335 335 }
336 336 Q_ASSERT(m_axisList.count() == 0);
337 337 }
338 338
339 339 void ChartDataSet::zoomInDomain(const QRectF &rect)
340 340 {
341 341 QList<AbstractDomain*> domains;
342 342 foreach(QAbstractSeries *s, m_seriesList) {
343 343 AbstractDomain* domain = s->d_ptr->domain();
344 s->d_ptr->m_domain->blockAxisSignals(true);
344 s->d_ptr->m_domain->blockRangeSignals(true);
345 345 domains<<domain;
346 346 }
347 347
348 348 foreach(AbstractDomain *domain, domains)
349 349 domain->zoomIn(rect);
350 350
351 351 foreach(AbstractDomain *domain, domains)
352 domain->blockAxisSignals(false);
352 domain->blockRangeSignals(false);
353 353 }
354 354
355 355 void ChartDataSet::zoomOutDomain(const QRectF &rect)
356 356 {
357 357 QList<AbstractDomain*> domains;
358 358 foreach(QAbstractSeries *s, m_seriesList) {
359 359 AbstractDomain* domain = s->d_ptr->domain();
360 s->d_ptr->m_domain->blockAxisSignals(true);
360 s->d_ptr->m_domain->blockRangeSignals(true);
361 361 domains<<domain;
362 362 }
363 363
364 364 foreach(AbstractDomain *domain, domains)
365 365 domain->zoomOut(rect);
366 366
367 367 foreach(AbstractDomain *domain, domains)
368 domain->blockAxisSignals(false);
368 domain->blockRangeSignals(false);
369 369 }
370 370
371 371 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
372 372 {
373 373 QList<AbstractDomain*> domains;
374 374 foreach(QAbstractSeries *s, m_seriesList) {
375 AbstractDomain* domain = s->d_ptr->m_domain.data();
376 if(domains.contains(domain)) continue;
377 s->d_ptr->m_domain->blockAxisSignals(true);
375 AbstractDomain* domain = s->d_ptr->domain();
376 s->d_ptr->m_domain->blockRangeSignals(true);
378 377 domains<<domain;
379 378 }
380 379
381 380 foreach(AbstractDomain *domain, domains)
382 381 domain->move(dx, dy);
383 382
384 383 foreach(AbstractDomain *domain, domains)
385 domain->blockAxisSignals(false);
384 domain->blockRangeSignals(false);
386 385 }
387 386
388 387 QList<QAbstractAxis*> ChartDataSet::axes() const
389 388 {
390 389 return m_axisList;
391 390 }
392 391
393 392 QList<QAbstractSeries *> ChartDataSet::series() const
394 393 {
395 394 return m_seriesList;
396 395 }
397 396
398 397 AbstractDomain::DomainType ChartDataSet::selectDomain(QList<QAbstractAxis*> axes)
399 398 {
400 399 enum Type {
401 400 Undefined = 0,
402 401 LogType = 0x1,
403 402 ValueType = 0x2
404 403 };
405 404
406 405 int horizontal(Undefined);
407 406 int vertical(Undefined);
408 407
409 408 foreach(QAbstractAxis* axis, axes)
410 409 {
411 410 switch(axis->type()) {
412 411 case QAbstractAxis::AxisTypeLogValue:
413 412
414 413 if(axis->orientation()==Qt::Horizontal) {
415 414 horizontal|=LogType;
416 415 }
417 416 if(axis->orientation()==Qt::Vertical) {
418 417 vertical|=LogType;
419 418 }
420 419
421 420 break;
422 421 case QAbstractAxis::AxisTypeValue:
423 422 case QAbstractAxis::AxisTypeBarCategory:
424 423 case QAbstractAxis::AxisTypeCategory:
425 424 case QAbstractAxis::AxisTypeDateTime:
426 425 if(axis->orientation()==Qt::Horizontal) {
427 426 horizontal|=ValueType;
428 427 }
429 428 if(axis->orientation()==Qt::Vertical) {
430 429 vertical|=ValueType;
431 430 }
432 431 break;
433 432 default:
434 433 qWarning()<<"Undefined type";
435 434 break;
436 435 }
437 436 }
438 437
439 438 if(vertical==Undefined) vertical=ValueType;
440 439 if(horizontal==Undefined) horizontal=ValueType;
441 440
442 441 if(vertical==ValueType && horizontal== ValueType) {
443 442 return AbstractDomain::XYDomain;
444 443 }
445 444
446 445 if(vertical==LogType && horizontal== ValueType) {
447 446 return AbstractDomain::XLogYDomain;
448 447 }
449 448
450 449 if(vertical==ValueType && horizontal== LogType) {
451 450 return AbstractDomain::LogXYDomain;
452 451 }
453 452
454 453 if(vertical==LogType && horizontal== LogType) {
455 454 return AbstractDomain::LogXLogYDomain;
456 455 }
457 456
458 457 return AbstractDomain::UndefinedDomain;
459 458 }
460 459
461 460
462 461 //refactor create factory
463 462 AbstractDomain* ChartDataSet::createDomain(AbstractDomain::DomainType type)
464 463 {
465 464 switch(type)
466 465 {
467 466 case AbstractDomain::LogXLogYDomain:
468 467 return new LogXLogYDomain();
469 468 case AbstractDomain::XYDomain:
470 469 return new XYDomain();
471 470 case AbstractDomain::XLogYDomain:
472 471 return new XLogYDomain();
473 472 case AbstractDomain::LogXYDomain:
474 473 return new LogXYDomain();
475 474 default:
476 475 return 0;
477 476 }
478 477 }
479 478
480 479 #include "moc_chartdataset_p.cpp"
481 480
482 481 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,219 +1,223
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 m_axisSignalsBlocked(false)
33 m_signalsBlocked(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 55 void AbstractDomain::setRangeX(qreal min, qreal max)
56 56 {
57 57 setRange(min, max, m_minY, m_maxY);
58 58 }
59 59
60 60 void AbstractDomain::setRangeY(qreal min, qreal max)
61 61 {
62 62 setRange(m_minX, m_maxX, min, max);
63 63 }
64 64
65 65 void AbstractDomain::setMinX(qreal min)
66 66 {
67 67 setRange(min, m_maxX, m_minY, m_maxY);
68 68 }
69 69
70 70 void AbstractDomain::setMaxX(qreal max)
71 71 {
72 72 setRange(m_minX, max, m_minY, m_maxY);
73 73 }
74 74
75 75 void AbstractDomain::setMinY(qreal min)
76 76 {
77 77 setRange(m_minX, m_maxX, min, m_maxY);
78 78 }
79 79
80 80 void AbstractDomain::setMaxY(qreal max)
81 81 {
82 82 setRange(m_minX, m_maxX, m_minY, max);
83 83 }
84 84
85 85 qreal AbstractDomain::spanX() const
86 86 {
87 87 Q_ASSERT(m_maxX >= m_minX);
88 88 return m_maxX - m_minX;
89 89 }
90 90
91 91 qreal AbstractDomain::spanY() const
92 92 {
93 93 Q_ASSERT(m_maxY >= m_minY);
94 94 return m_maxY - m_minY;
95 95 }
96 96
97 97 bool AbstractDomain::isEmpty() const
98 98 {
99 99 return qFuzzyIsNull(spanX()) || qFuzzyIsNull(spanY()) || m_size.isEmpty() ;
100 100 }
101 101
102 102 QPointF AbstractDomain::calculateDomainPoint(const QPointF &point) const
103 103 {
104 104 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
105 105 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
106 106 qreal x = point.x() / deltaX + m_minX;
107 107 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
108 108 return QPointF(x, y);
109 109 }
110 110
111 111 // handlers
112 112
113 113 void AbstractDomain::handleVerticalAxisRangeChanged(qreal min, qreal max)
114 114 {
115 if(!m_axisSignalsBlocked)
116 setRangeY(min, max);
115 setRangeY(min, max);
117 116 }
118 117
119 118 void AbstractDomain::handleHorizontalAxisRangeChanged(qreal min, qreal max)
120 119 {
121 if(!m_axisSignalsBlocked)
122 setRangeX(min, max);
120 setRangeX(min, max);
123 121 }
124 122
125 void AbstractDomain::blockAxisSignals(bool block)
123 void AbstractDomain::blockRangeSignals(bool block)
126 124 {
127 m_axisSignalsBlocked=block;
125 if(m_signalsBlocked!=block){
126 m_signalsBlocked=block;
127 if(!block) {
128 emit rangeHorizontalChanged(m_minX,m_maxX);
129 emit rangeVerticalChanged(m_minY,m_maxY);
130 }
131 }
128 132 }
129 133
130 134 //algorithm defined by Paul S.Heckbert GraphicalGems I
131 135
132 136 void AbstractDomain::looseNiceNumbers(qreal &min, qreal &max, int &ticksCount)
133 137 {
134 138 qreal range = niceNumber(max - min, true); //range with ceiling
135 139 qreal step = niceNumber(range / (ticksCount - 1), false);
136 140 min = qFloor(min / step);
137 141 max = qCeil(max / step);
138 142 ticksCount = int(max - min) + 1;
139 143 min *= step;
140 144 max *= step;
141 145 }
142 146
143 147 //nice numbers can be expressed as form of 1*10^n, 2* 10^n or 5*10^n
144 148
145 149 qreal AbstractDomain::niceNumber(qreal x, bool ceiling)
146 150 {
147 151 qreal z = qPow(10, qFloor(log10(x))); //find corresponding number of the form of 10^n than is smaller than x
148 152 qreal q = x / z; //q<10 && q>=1;
149 153
150 154 if (ceiling) {
151 155 if (q <= 1.0) q = 1;
152 156 else if (q <= 2.0) q = 2;
153 157 else if (q <= 5.0) q = 5;
154 158 else q = 10;
155 159 } else {
156 160 if (q < 1.5) q = 1;
157 161 else if (q < 3.0) q = 2;
158 162 else if (q < 7.0) q = 5;
159 163 else q = 10;
160 164 }
161 165 return q * z;
162 166 }
163 167
164 168 bool AbstractDomain::attachAxis(QAbstractAxis* axis)
165 169 {
166 170 if(axis->orientation()==Qt::Vertical) {
167 171 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
168 172 QObject::connect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
169 173 }
170 174
171 175 if(axis->orientation()==Qt::Horizontal) {
172 176 QObject::connect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
173 177 QObject::connect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
174 178 }
175 179
176 180 return true;
177 181 }
178 182
179 183 bool AbstractDomain::detachAxis(QAbstractAxis* axis)
180 184 {
181 185 if(axis->orientation()==Qt::Vertical) {
182 186 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleVerticalAxisRangeChanged(qreal,qreal)));
183 187 QObject::disconnect(this, SIGNAL(rangeVerticalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
184 188 }
185 189
186 190 if(axis->orientation()==Qt::Horizontal) {
187 191 QObject::disconnect(axis->d_ptr.data(), SIGNAL(rangeChanged(qreal,qreal)), this, SLOT(handleHorizontalAxisRangeChanged(qreal,qreal)));
188 192 QObject::disconnect(this, SIGNAL(rangeHorizontalChanged(qreal,qreal)), axis->d_ptr.data(), SLOT(handleRangeChanged(qreal,qreal)));
189 193 }
190 194
191 195 return true;
192 196 }
193 197
194 198 // operators
195 199
196 200 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2)
197 201 {
198 202 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
199 203 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
200 204 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
201 205 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
202 206 }
203 207
204 208
205 209 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2)
206 210 {
207 211 return !(domain1 == domain2);
208 212 }
209 213
210 214
211 215 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain)
212 216 {
213 217 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
214 218 return dbg.maybeSpace();
215 219 }
216 220
217 221 #include "moc_abstractdomain_p.cpp"
218 222
219 223 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,113 +1,113
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 QAbstractAxis;
40 40
41 41 class QTCOMMERCIALCHART_AUTOTEST_EXPORT AbstractDomain: public QObject
42 42 {
43 43 Q_OBJECT
44 44 public:
45 45 enum DomainType { UndefinedDomain, XYDomain, XLogYDomain, LogXYDomain, LogXLogYDomain };
46 46 public:
47 47 explicit AbstractDomain(QObject *object = 0);
48 48 virtual ~AbstractDomain();
49 49
50 50 void setSize(const QSizeF& size);
51 51 QSizeF size() const;
52 52
53 53 virtual DomainType type() = 0;
54 54
55 55 virtual void setRange(qreal minX, qreal maxX, qreal minY, qreal maxY) = 0;
56 56 void setRangeX(qreal min, qreal max);
57 57 void setRangeY(qreal min, qreal max);
58 58 void setMinX(qreal min);
59 59 void setMaxX(qreal max);
60 60 void setMinY(qreal min);
61 61 void setMaxY(qreal max);
62 62
63 63 qreal minX() const { return m_minX; }
64 64 qreal maxX() const { return m_maxX; }
65 65 qreal minY() const { return m_minY; }
66 66 qreal maxY() const { return m_maxY; }
67 67
68 68 qreal spanX() const;
69 69 qreal spanY() const;
70 70 bool isEmpty() const;
71 71
72 void blockAxisSignals(bool block);
73 bool axisSignalsBlocked() const { return m_axisSignalsBlocked; }
72 void blockRangeSignals(bool block);
73 bool rangeSignalsBlocked() const { return m_signalsBlocked; }
74 74
75 75 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const AbstractDomain &domain1, const AbstractDomain &domain2);
76 76 friend bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const AbstractDomain &domain1, const AbstractDomain &domain2);
77 77 friend QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const AbstractDomain &domain);
78 78
79 79 virtual void zoomIn(const QRectF &rect) = 0;
80 80 virtual void zoomOut(const QRectF &rect) = 0;
81 81 virtual void move(qreal dx, qreal dy) = 0;
82 82
83 83 virtual QPointF calculateGeometryPoint(const QPointF &point) const = 0;
84 84 virtual QPointF calculateDomainPoint(const QPointF &point) const = 0;
85 85 virtual QVector<QPointF> calculateGeometryPoints(const QList<QPointF>& vector) const = 0;
86 86
87 87 virtual bool attachAxis(QAbstractAxis* axis);
88 88 virtual bool detachAxis(QAbstractAxis* axis);
89 89
90 90 static void looseNiceNumbers(qreal &min, qreal &max, int &ticksCount);
91 91 static qreal niceNumber(qreal x, bool ceiling);
92 92
93 93 Q_SIGNALS:
94 94 void updated();
95 95 void rangeHorizontalChanged(qreal min, qreal max);
96 96 void rangeVerticalChanged(qreal min, qreal max);
97 97
98 98 public Q_SLOTS:
99 99 void handleVerticalAxisRangeChanged(qreal min,qreal max);
100 100 void handleHorizontalAxisRangeChanged(qreal min,qreal max);
101 101
102 102 protected:
103 103 qreal m_minX;
104 104 qreal m_maxX;
105 105 qreal m_minY;
106 106 qreal m_maxY;
107 107 QSizeF m_size;
108 bool m_axisSignalsBlocked;
108 bool m_signalsBlocked;
109 109 };
110 110
111 111 QTCOMMERCIALCHART_END_NAMESPACE
112 112
113 113 #endif // ABSTRACTDOMAIN_H
@@ -1,177 +1,179
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 "xydomain_p.h"
22 22 #include "qabstractaxis_p.h"
23 23 #include <qmath.h>
24 24
25 25 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 26
27 27 XYDomain::XYDomain(QObject *parent)
28 28 : AbstractDomain(parent)
29 29 {
30 30 }
31 31
32 32 XYDomain::~XYDomain()
33 33 {
34 34 }
35 35
36 36 void XYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
37 37 {
38 38 bool axisXChanged = false;
39 39 bool axisYChanged = false;
40 40
41 41 if (!qFuzzyCompare(m_minX, minX) || !qFuzzyCompare(m_maxX, maxX)) {
42 42 m_minX = minX;
43 43 m_maxX = maxX;
44 44 axisXChanged = true;
45 emit rangeHorizontalChanged(m_minX, m_maxX);
45 if(!m_signalsBlocked)
46 emit rangeHorizontalChanged(m_minX, m_maxX);
46 47 }
47 48
48 49 if (!qFuzzyCompare(m_minY, minY) || !qFuzzyCompare(m_maxY, maxY)) {
49 50 m_minY = minY;
50 51 m_maxY = maxY;
51 52 axisYChanged = true;
52 emit rangeVerticalChanged(m_minY, m_maxY);
53 if(!m_signalsBlocked)
54 emit rangeVerticalChanged(m_minY, m_maxY);
53 55 }
54 56
55 57 if (axisXChanged || axisYChanged)
56 58 emit updated();
57 59 }
58 60
59 61
60 62 void XYDomain::zoomIn(const QRectF &rect)
61 63 {
62 64 qreal dx = spanX() / m_size.width();
63 65 qreal dy = spanY() / m_size.height();
64 66
65 67 qreal maxX = m_maxX;
66 68 qreal minX = m_minX;
67 69 qreal minY = m_minY;
68 70 qreal maxY = m_maxY;
69 71
70 72 maxX = minX + dx * rect.right();
71 73 minX = minX + dx * rect.left();
72 74 minY = maxY - dy * rect.bottom();
73 75 maxY = maxY - dy * rect.top();
74 76
75 77 setRange(minX, maxX, minY, maxY);
76 78 }
77 79
78 80 void XYDomain::zoomOut(const QRectF &rect)
79 81 {
80 82 qreal dx = spanX() / rect.width();
81 83 qreal dy = spanY() / rect.height();
82 84
83 85 qreal maxX = m_maxX;
84 86 qreal minX = m_minX;
85 87 qreal minY = m_minY;
86 88 qreal maxY = m_maxY;
87 89
88 90 minX = maxX - dx * rect.right();
89 91 maxX = minX + dx * m_size.width();
90 92 maxY = minY + dy * rect.bottom();
91 93 minY = maxY - dy * m_size.height();
92 94
93 95 setRange(minX, maxX, minY, maxY);
94 96 }
95 97
96 98 void XYDomain::move(qreal dx, qreal dy)
97 99 {
98 100 qreal x = spanX() / m_size.width();
99 101 qreal y = spanY() / m_size.height();
100 102
101 103 qreal maxX = m_maxX;
102 104 qreal minX = m_minX;
103 105 qreal minY = m_minY;
104 106 qreal maxY = m_maxY;
105 107
106 108 if (dx != 0) {
107 109 minX = minX + x * dx;
108 110 maxX = maxX + x * dx;
109 111 }
110 112 if (dy != 0) {
111 113 minY = minY + y * dy;
112 114 maxY = maxY + y * dy;
113 115 }
114 116 setRange(minX, maxX, minY, maxY);
115 117 }
116 118
117 119 QPointF XYDomain::calculateGeometryPoint(const QPointF &point) const
118 120 {
119 121 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
120 122 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
121 123 qreal x = (point.x() - m_minX) * deltaX;
122 124 qreal y = (point.y() - m_minY) * -deltaY + m_size.height();
123 125 return QPointF(x, y);
124 126 }
125 127
126 128 QVector<QPointF> XYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
127 129 {
128 130 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
129 131 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
130 132
131 133 QVector<QPointF> result;
132 134 result.resize(vector.count());
133 135
134 136 for (int i = 0; i < vector.count(); ++i) {
135 137 qreal x = (vector[i].x() - m_minX) * deltaX;
136 138 qreal y = (vector[i].y() - m_minY) * -deltaY + m_size.height();
137 139 result[i].setX(x);
138 140 result[i].setY(y);
139 141 }
140 142 return result;
141 143 }
142 144
143 145 QPointF XYDomain::calculateDomainPoint(const QPointF &point) const
144 146 {
145 147 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
146 148 const qreal deltaY = m_size.height() / (m_maxY - m_minY);
147 149 qreal x = point.x() / deltaX + m_minX;
148 150 qreal y = (point.y() - m_size.height()) / (-deltaY) + m_minY;
149 151 return QPointF(x, y);
150 152 }
151 153
152 154 // operators
153 155
154 156 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XYDomain &domain1, const XYDomain &domain2)
155 157 {
156 158 return (qFuzzyCompare(domain1.m_maxX, domain2.m_maxX) &&
157 159 qFuzzyCompare(domain1.m_maxY, domain2.m_maxY) &&
158 160 qFuzzyCompare(domain1.m_minX, domain2.m_minX) &&
159 161 qFuzzyCompare(domain1.m_minY, domain2.m_minY));
160 162 }
161 163
162 164
163 165 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XYDomain &domain1, const XYDomain &domain2)
164 166 {
165 167 return !(domain1 == domain2);
166 168 }
167 169
168 170
169 171 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XYDomain &domain)
170 172 {
171 173 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
172 174 return dbg.maybeSpace();
173 175 }
174 176
175 177 #include "moc_xydomain_p.cpp"
176 178
177 179 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now