##// END OF EJS Templates
Preset range on LogAxis fix
Marek Rosa -
r2373:8d156e433738
parent child
Show More
@@ -1,511 +1,513
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 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
117 117
118 118 foreach(QAbstractAxis* axis, axes) {
119 119 detachAxis(series,axis);
120 120 }
121 121
122 122 emit seriesRemoved(series);
123 123 m_seriesList.removeAll(series);
124 124
125 125 series->setParent(0);
126 126 series->d_ptr->m_chart = 0;
127 127 }
128 128
129 129 /*
130 130 * This method removes axis form chartdataset, series ownership is passed back to caller.
131 131 */
132 132 void ChartDataSet::removeAxis(QAbstractAxis *axis)
133 133 {
134 134 if (! m_axisList.contains(axis)) {
135 135 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
136 136 return;
137 137 }
138 138
139 139 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
140 140
141 141 foreach(QAbstractSeries* s, series) {
142 142 detachAxis(s,axis);
143 143 }
144 144
145 145 emit axisRemoved(axis);
146 146 m_axisList.removeAll(axis);
147 147
148 148 axis->setParent(0);
149 149 axis->d_ptr->m_chart = 0;
150 150 }
151 151
152 152 /*
153 153 * This method attaches axis to series, return true if success.
154 154 */
155 155 bool ChartDataSet::attachAxis(QAbstractSeries* series,QAbstractAxis *axis)
156 156 {
157 157 Q_ASSERT(series);
158 158 Q_ASSERT(axis);
159 159
160 160 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
161 161 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
162 162
163 163 if (!m_seriesList.contains(series)) {
164 164 qWarning() << QObject::tr("Can not find series on the chart.");
165 165 return false;
166 166 }
167 167
168 168 if (axis && !m_axisList.contains(axis)) {
169 169 qWarning() << QObject::tr("Can not find axis on the chart.");
170 170 return false;
171 171 }
172 172
173 173 if (attachedAxisList.contains(axis)) {
174 174 qWarning() << QObject::tr("Axis already attached to series.");
175 175 return false;
176 176 }
177 177
178 178 if (attachedSeriesList.contains(series)) {
179 179 qWarning() << QObject::tr("Axis already attached to series.");
180 180 return false;
181 181 }
182 182
183 183 AbstractDomain* domain = series->d_ptr->domain();
184 184 AbstractDomain::DomainType type = selectDomain(attachedAxisList<<axis);
185 185
186 186 if(type == AbstractDomain::UndefinedDomain) return false;
187 187
188 188 if(domain->type()!=type){
189 AbstractDomain *old = domain;
189 190 domain = createDomain(type);
191 domain->setRange(old->minX(), old->maxX(), old->minY(), old->maxY());
190 192 }
191 193
192 194 if(!domain) return false;
193 195
194 196 if(!domain->attachAxis(axis)) return false;
195 197
196 198 if(domain!=series->d_ptr->domain()){
197 199 foreach(QAbstractAxis* axis,series->d_ptr->m_axes){
198 200 series->d_ptr->domain()->detachAxis(axis);
199 201 domain->attachAxis(axis);
200 202 }
201 203 series->d_ptr->setDomain(domain);
202 204 series->d_ptr->initializeDomain();
203 205 }
204 206
205 207 series->d_ptr->m_axes<<axis;
206 208 axis->d_ptr->m_series<<series;
207 209
208 210 series->d_ptr->initializeAxes();
209 211 axis->d_ptr->initializeDomain(domain);
210 212
211 213 return true;
212 214 }
213 215
214 216 /*
215 217 * This method detaches axis to series, return true if success.
216 218 */
217 219 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
218 220 {
219 221 Q_ASSERT(series);
220 222 Q_ASSERT(axis);
221 223
222 224 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
223 225 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
224 226 AbstractDomain* domain = series->d_ptr->domain();
225 227
226 228 if (!m_seriesList.contains(series)) {
227 229 qWarning() << QObject::tr("Can not find series on the chart.");
228 230 return false;
229 231 }
230 232
231 233 if (axis && !m_axisList.contains(axis)) {
232 234 qWarning() << QObject::tr("Can not find axis on the chart.");
233 235 return false;
234 236 }
235 237
236 238 if (!attachedAxisList.contains(axis)) {
237 239 qWarning() << QObject::tr("Axis not attached to series.");
238 240 return false;
239 241 }
240 242
241 243 Q_ASSERT(axis->d_ptr->m_series.contains(series));
242 244
243 245 domain->detachAxis(axis);
244 246 series->d_ptr->m_axes.removeAll(axis);
245 247 axis->d_ptr->m_series.removeAll(series);
246 248
247 249 return true;
248 250 }
249 251
250 252 void ChartDataSet::createDefaultAxes()
251 253 {
252 254 if (m_seriesList.isEmpty())
253 255 return;
254 256
255 257 QAbstractAxis::AxisTypes typeX(0);
256 258 QAbstractAxis::AxisTypes typeY(0);
257 259
258 260 // Remove possibly existing axes
259 261 deleteAllAxes();
260 262
261 263 Q_ASSERT(m_axisList.isEmpty());
262 264
263 265 // Select the required axis x and axis y types based on the types of the current series
264 266 foreach(QAbstractSeries* s, m_seriesList) {
265 267 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
266 268 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
267 269 }
268 270
269 271 // Create the axes of the types selected
270 272 createAxes(typeX, Qt::Horizontal);
271 273 createAxes(typeY, Qt::Vertical);
272 274
273 275 }
274 276
275 277 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
276 278 {
277 279 QAbstractAxis *axis = 0;
278 280 //decide what axis should be created
279 281
280 282 switch (type) {
281 283 case QAbstractAxis::AxisTypeValue:
282 284 axis = new QValueAxis(this);
283 285 break;
284 286 case QAbstractAxis::AxisTypeBarCategory:
285 287 axis = new QBarCategoryAxis(this);
286 288 break;
287 289 case QAbstractAxis::AxisTypeCategory:
288 290 axis = new QCategoryAxis(this);
289 291 break;
290 292 #ifndef Q_WS_QWS
291 293 case QAbstractAxis::AxisTypeDateTime:
292 294 axis = new QDateTimeAxis(this);
293 295 break;
294 296 #endif
295 297 default:
296 298 axis = 0;
297 299 break;
298 300 }
299 301
300 302 if (axis) {
301 303 //create one axis for all
302 304
303 305 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
304 306
305 307 foreach(QAbstractSeries *s, m_seriesList) {
306 308 attachAxis(s,axis);
307 309 }
308 310
309 311 }
310 312 else if (!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
311 313 //create separate axis
312 314 foreach(QAbstractSeries *s, m_seriesList) {
313 315 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
314 316 if(axis) {
315 317 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
316 318 attachAxis(s,axis);
317 319 }
318 320 }
319 321 }
320 322 }
321 323
322 324 void ChartDataSet::deleteAllSeries()
323 325 {
324 326 foreach (QAbstractSeries *s , m_seriesList){
325 327 removeSeries(s);
326 328 s->deleteLater();
327 329 }
328 330 Q_ASSERT(m_seriesList.count() == 0);
329 331 }
330 332
331 333 void ChartDataSet::deleteAllAxes()
332 334 {
333 335 foreach (QAbstractAxis *a , m_axisList){
334 336 removeAxis(a);
335 337 a->deleteLater();
336 338 }
337 339 Q_ASSERT(m_axisList.count() == 0);
338 340 }
339 341
340 342 void ChartDataSet::zoomInDomain(const QRectF &rect)
341 343 {
342 344 QList<AbstractDomain*> domains;
343 345 foreach(QAbstractSeries *s, m_seriesList) {
344 346 AbstractDomain* domain = s->d_ptr->domain();
345 347 s->d_ptr->m_domain->blockRangeSignals(true);
346 348 domains<<domain;
347 349 }
348 350
349 351 foreach(AbstractDomain *domain, domains)
350 352 domain->zoomIn(rect);
351 353
352 354 foreach(AbstractDomain *domain, domains)
353 355 domain->blockRangeSignals(false);
354 356 }
355 357
356 358 void ChartDataSet::zoomOutDomain(const QRectF &rect)
357 359 {
358 360 QList<AbstractDomain*> domains;
359 361 foreach(QAbstractSeries *s, m_seriesList) {
360 362 AbstractDomain* domain = s->d_ptr->domain();
361 363 s->d_ptr->m_domain->blockRangeSignals(true);
362 364 domains<<domain;
363 365 }
364 366
365 367 foreach(AbstractDomain *domain, domains)
366 368 domain->zoomOut(rect);
367 369
368 370 foreach(AbstractDomain *domain, domains)
369 371 domain->blockRangeSignals(false);
370 372 }
371 373
372 374 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
373 375 {
374 376 QList<AbstractDomain*> domains;
375 377 foreach(QAbstractSeries *s, m_seriesList) {
376 378 AbstractDomain* domain = s->d_ptr->domain();
377 379 s->d_ptr->m_domain->blockRangeSignals(true);
378 380 domains<<domain;
379 381 }
380 382
381 383 foreach(AbstractDomain *domain, domains)
382 384 domain->move(dx, dy);
383 385
384 386 foreach(AbstractDomain *domain, domains)
385 387 domain->blockRangeSignals(false);
386 388 }
387 389
388 390 QPointF ChartDataSet::mapToValue(const QPointF &position, QAbstractSeries *series)
389 391 {
390 392 QPointF point;
391 393 if (series == 0 && !m_seriesList.isEmpty())
392 394 series = m_seriesList.first();
393 395
394 396 if (series && series->type() == QAbstractSeries::SeriesTypePie)
395 397 return point;
396 398
397 399 if (series && m_seriesList.contains(series))
398 400 point = series->d_ptr->m_domain->calculateDomainPoint(position - m_chart->plotArea().topLeft());
399 401 return point;
400 402 }
401 403
402 404 QPointF ChartDataSet::mapToPosition(const QPointF &value, QAbstractSeries *series)
403 405 {
404 406 QPointF point = m_chart->plotArea().topLeft();
405 407 if (series == 0 && !m_seriesList.isEmpty())
406 408 series = m_seriesList.first();
407 409
408 410 if (series && series->type() == QAbstractSeries::SeriesTypePie)
409 411 return QPoint(0, 0);
410 412
411 413 bool ok;
412 414 if (series && m_seriesList.contains(series))
413 415 point += series->d_ptr->m_domain->calculateGeometryPoint(value, ok);
414 416 return point;
415 417 }
416 418
417 419 QList<QAbstractAxis*> ChartDataSet::axes() const
418 420 {
419 421 return m_axisList;
420 422 }
421 423
422 424 QList<QAbstractSeries *> ChartDataSet::series() const
423 425 {
424 426 return m_seriesList;
425 427 }
426 428
427 429 AbstractDomain::DomainType ChartDataSet::selectDomain(QList<QAbstractAxis*> axes)
428 430 {
429 431 enum Type {
430 432 Undefined = 0,
431 433 LogType = 0x1,
432 434 ValueType = 0x2
433 435 };
434 436
435 437 int horizontal(Undefined);
436 438 int vertical(Undefined);
437 439
438 440 foreach(QAbstractAxis* axis, axes)
439 441 {
440 442 switch(axis->type()) {
441 443 case QAbstractAxis::AxisTypeLogValue:
442 444
443 445 if(axis->orientation()==Qt::Horizontal) {
444 446 horizontal|=LogType;
445 447 }
446 448 if(axis->orientation()==Qt::Vertical) {
447 449 vertical|=LogType;
448 450 }
449 451
450 452 break;
451 453 case QAbstractAxis::AxisTypeValue:
452 454 case QAbstractAxis::AxisTypeBarCategory:
453 455 case QAbstractAxis::AxisTypeCategory:
454 456 case QAbstractAxis::AxisTypeDateTime:
455 457 if(axis->orientation()==Qt::Horizontal) {
456 458 horizontal|=ValueType;
457 459 }
458 460 if(axis->orientation()==Qt::Vertical) {
459 461 vertical|=ValueType;
460 462 }
461 463 break;
462 464 default:
463 465 qWarning()<<"Undefined type";
464 466 break;
465 467 }
466 468 }
467 469
468 470 if(vertical==Undefined) vertical=ValueType;
469 471 if(horizontal==Undefined) horizontal=ValueType;
470 472
471 473 if(vertical==ValueType && horizontal== ValueType) {
472 474 return AbstractDomain::XYDomain;
473 475 }
474 476
475 477 if(vertical==LogType && horizontal== ValueType) {
476 478 return AbstractDomain::XLogYDomain;
477 479 }
478 480
479 481 if(vertical==ValueType && horizontal== LogType) {
480 482 return AbstractDomain::LogXYDomain;
481 483 }
482 484
483 485 if(vertical==LogType && horizontal== LogType) {
484 486 return AbstractDomain::LogXLogYDomain;
485 487 }
486 488
487 489 return AbstractDomain::UndefinedDomain;
488 490 }
489 491
490 492
491 493 //refactor create factory
492 494 AbstractDomain* ChartDataSet::createDomain(AbstractDomain::DomainType type)
493 495 {
494 496 switch(type)
495 497 {
496 498 case AbstractDomain::LogXLogYDomain:
497 499 return new LogXLogYDomain();
498 500 case AbstractDomain::XYDomain:
499 501 return new XYDomain();
500 502 case AbstractDomain::XLogYDomain:
501 503 return new XLogYDomain();
502 504 case AbstractDomain::LogXYDomain:
503 505 return new LogXYDomain();
504 506 default:
505 507 return 0;
506 508 }
507 509 }
508 510
509 511 #include "moc_chartdataset_p.cpp"
510 512
511 513 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now