##// END OF EJS Templates
Removed unnecessary model related function from xyseries and pieseries
Marek Rosa -
r1166:740d4c3988ce
parent child
Show More
@@ -1,798 +1,807
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 "qpieseries.h"
22 22 #include "qpieseries_p.h"
23 23 #include "qpieslice.h"
24 24 #include "pieslicedata_p.h"
25 25 #include "chartdataset_p.h"
26 26 #include "charttheme_p.h"
27 27 #include "chartanimator_p.h"
28 28 #include "legendmarker_p.h"
29 29 #include <QAbstractItemModel>
30 30 #include "qpiemodelmapper.h"
31 31
32 32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33 33
34 34 /*!
35 35 \class QPieSeries
36 36 \brief Pie series API for QtCommercial Charts
37 37
38 38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
39 39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
40 40 The actual slice size is determined by that relative value.
41 41
42 42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
43 43 These relate to the actual chart rectangle.
44 44
45 45 By default the pie is defined as a full pie but it can also be a partial pie.
46 46 This can be done by setting a starting angle and angle span to the series.
47 47 Full pie is 360 degrees where 0 is at 12 a'clock.
48 48
49 49 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
50 50 \image examples_piechart.png
51 51 */
52 52
53 53 /*!
54 54 \property QPieSeries::horizontalPosition
55 55 \brief Defines the horizontal position of the pie.
56 56
57 57 The value is a relative value to the chart rectangle where:
58 58
59 59 \list
60 60 \o 0.0 is the absolute left.
61 61 \o 1.0 is the absolute right.
62 62 \endlist
63 63
64 64 Default value is 0.5 (center).
65 65 */
66 66
67 67 /*!
68 68 \property QPieSeries::verticalPosition
69 69 \brief Defines the vertical position of the pie.
70 70
71 71 The value is a relative value to the chart rectangle where:
72 72
73 73 \list
74 74 \o 0.0 is the absolute top.
75 75 \o 1.0 is the absolute bottom.
76 76 \endlist
77 77
78 78 Default value is 0.5 (center).
79 79 */
80 80
81 81 /*!
82 82 \property QPieSeries::size
83 83 \brief Defines the pie size.
84 84
85 85 The value is a relative value to the chart rectangle where:
86 86
87 87 \list
88 88 \o 0.0 is the minimum size (pie not drawn).
89 89 \o 1.0 is the maximum size that can fit the chart.
90 90 \endlist
91 91
92 92 Default value is 0.7.
93 93 */
94 94
95 95 /*!
96 96 \property QPieSeries::startAngle
97 97 \brief Defines the starting angle of the pie.
98 98
99 99 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
100 100
101 101 Default is value is 0.
102 102 */
103 103
104 104 /*!
105 105 \property QPieSeries::endAngle
106 106 \brief Defines the ending angle of the pie.
107 107
108 108 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
109 109
110 110 Default is value is 360.
111 111 */
112 112
113 113
114 114 /*!
115 115 Constructs a series object which is a child of \a parent.
116 116 */
117 117 QPieSeries::QPieSeries(QObject *parent) :
118 118 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
119 119 {
120 120
121 121 }
122 122
123 123 /*!
124 124 Destroys the series and its slices.
125 125 */
126 126 QPieSeries::~QPieSeries()
127 127 {
128 128 // NOTE: d_prt destroyed by QObject
129 129 }
130 130
131 131 /*!
132 132 Returns QChartSeries::SeriesTypePie.
133 133 */
134 134 QAbstractSeries::SeriesType QPieSeries::type() const
135 135 {
136 136 return QAbstractSeries::SeriesTypePie;
137 137 }
138 138
139 139 /*!
140 140 Appends an array of \a slices to the series.
141 141 Slice ownership is passed to the series.
142 142 */
143 143 bool QPieSeries::append(QList<QPieSlice*> slices)
144 144 {
145 145 Q_D(QPieSeries);
146 146
147 147 if (slices.count() == 0)
148 148 return false;
149 149
150 150 foreach (QPieSlice* s, slices) {
151 151 if (!s || d->m_slices.contains(s))
152 152 return false;
153 153 }
154 154
155 155 foreach (QPieSlice* s, slices) {
156 156 s->setParent(this);
157 157 d->m_slices << s;
158 158 }
159 159
160 160 d->updateDerivativeData();
161 161
162 162 foreach (QPieSlice* s, slices) {
163 163 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
164 164 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
165 165 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
166 166 }
167 167
168 168 emit d->added(slices);
169 169
170 170 return true;
171 171 }
172 172
173 173 /*!
174 174 Appends a single \a slice to the series.
175 175 Slice ownership is passed to the series.
176 176 */
177 177 bool QPieSeries::append(QPieSlice* slice)
178 178 {
179 179 return append(QList<QPieSlice*>() << slice);
180 180 }
181 181
182 182 /*!
183 183 Appends a single \a slice to the series and returns a reference to the series.
184 184 Slice ownership is passed to the series.
185 185 */
186 186 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
187 187 {
188 188 append(slice);
189 189 return *this;
190 190 }
191 191
192 192
193 193 /*!
194 194 Appends a single slice to the series with give \a value and \a name.
195 195 Slice ownership is passed to the series.
196 196 */
197 197 QPieSlice* QPieSeries::append(qreal value, QString name)
198 198 {
199 199 QPieSlice* slice = new QPieSlice(value, name);
200 200 append(slice);
201 201 return slice;
202 202 }
203 203
204 204 /*!
205 205 Inserts a single \a slice to the series before the slice at \a index position.
206 206 Slice ownership is passed to the series.
207 207 */
208 208 bool QPieSeries::insert(int index, QPieSlice* slice)
209 209 {
210 210 Q_D(QPieSeries);
211 211
212 212 if (index < 0 || index > d->m_slices.count())
213 213 return false;
214 214
215 215 if (!slice || d->m_slices.contains(slice))
216 216 return false;
217 217
218 218 slice->setParent(this);
219 219 d->m_slices.insert(index, slice);
220 220
221 221 d->updateDerivativeData();
222 222
223 223 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
224 224 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
225 225 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
226 226
227 227 emit d->added(QList<QPieSlice*>() << slice);
228 228
229 229 return true;
230 230 }
231 231
232 232 /*!
233 233 Removes a single \a slice from the series and deletes the slice.
234 234
235 235 Do not reference the pointer after this call.
236 236 */
237 237 bool QPieSeries::remove(QPieSlice* slice)
238 238 {
239 239 Q_D(QPieSeries);
240 240
241 241 if (!d->m_slices.removeOne(slice))
242 242 return false;
243 243
244 244 d->updateDerivativeData();
245 245
246 246 emit d->removed(QList<QPieSlice*>() << slice);
247 247
248 248 delete slice;
249 249 slice = 0;
250 250
251 251 return true;
252 252 }
253 253
254 254 /*!
255 255 Clears all slices from the series.
256 256 */
257 257 void QPieSeries::clear()
258 258 {
259 259 Q_D(QPieSeries);
260 260 if (d->m_slices.count() == 0)
261 261 return;
262 262
263 263 QList<QPieSlice*> slices = d->m_slices;
264 264 foreach (QPieSlice* s, d->m_slices) {
265 265 d->m_slices.removeOne(s);
266 266 delete s;
267 267 }
268 268
269 269 d->updateDerivativeData();
270 270
271 271 emit d->removed(slices);
272 272 }
273 273
274 274 /*!
275 275 returns the number of the slices in this series.
276 276 */
277 277 int QPieSeries::count() const
278 278 {
279 279 Q_D(const QPieSeries);
280 280 return d->m_slices.count();
281 281 }
282 282
283 283 /*!
284 284 Returns true is the series is empty.
285 285 */
286 286 bool QPieSeries::isEmpty() const
287 287 {
288 288 Q_D(const QPieSeries);
289 289 return d->m_slices.isEmpty();
290 290 }
291 291
292 292 /*!
293 293 Returns a list of slices that belong to this series.
294 294 */
295 295 QList<QPieSlice*> QPieSeries::slices() const
296 296 {
297 297 Q_D(const QPieSeries);
298 298 return d->m_slices;
299 299 }
300 300
301 301 void QPieSeries::setHorizontalPosition(qreal relativePosition)
302 302 {
303 303 Q_D(QPieSeries);
304 304 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
305 305 emit d->piePositionChanged();
306 306 }
307 307
308 308 void QPieSeries::setVerticalPosition(qreal relativePosition)
309 309 {
310 310 Q_D(QPieSeries);
311 311 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
312 312 emit d->piePositionChanged();
313 313 }
314 314
315 315 qreal QPieSeries::horizontalPosition() const
316 316 {
317 317 Q_D(const QPieSeries);
318 318 return d->m_pieRelativeHorPos;
319 319 }
320 320
321 321 qreal QPieSeries::verticalPosition() const
322 322 {
323 323 Q_D(const QPieSeries);
324 324 return d->m_pieRelativeVerPos;
325 325 }
326 326
327 327 void QPieSeries::setPieSize(qreal relativeSize)
328 328 {
329 329 Q_D(QPieSeries);
330 330 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
331 331 emit d->pieSizeChanged();
332 332 }
333 333
334 334 qreal QPieSeries::pieSize() const
335 335 {
336 336 Q_D(const QPieSeries);
337 337 return d->m_pieRelativeSize;
338 338 }
339 339
340 340
341 341 void QPieSeries::setPieStartAngle(qreal angle)
342 342 {
343 343 Q_D(QPieSeries);
344 344 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
345 345 d->updateDerivativeData();
346 346 }
347 347
348 348 qreal QPieSeries::pieStartAngle() const
349 349 {
350 350 Q_D(const QPieSeries);
351 351 return d->m_pieStartAngle;
352 352 }
353 353
354 354 /*!
355 355 Sets the end angle of the pie.
356 356
357 357 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
358 358
359 359 \a angle must be greater than start angle.
360 360
361 361 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
362 362 */
363 363 void QPieSeries::setPieEndAngle(qreal angle)
364 364 {
365 365 Q_D(QPieSeries);
366 366
367 367 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
368 368 d->updateDerivativeData();
369 369 }
370 370
371 371 /*!
372 372 Returns the end angle of the pie.
373 373
374 374 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
375 375
376 376 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
377 377 */
378 378 qreal QPieSeries::pieEndAngle() const
379 379 {
380 380 Q_D(const QPieSeries);
381 381 return d->m_pieEndAngle;
382 382 }
383 383
384 384 /*!
385 385 Sets the all the slice labels \a visible or invisible.
386 386
387 387 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
388 388 */
389 389 void QPieSeries::setLabelsVisible(bool visible)
390 390 {
391 391 Q_D(QPieSeries);
392 392 foreach (QPieSlice* s, d->m_slices)
393 393 s->setLabelVisible(visible);
394 394 }
395 395
396 396 /*!
397 397 Returns the sum of all slice values in this series.
398 398
399 399 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
400 400 */
401 401 qreal QPieSeries::sum() const
402 402 {
403 403 Q_D(const QPieSeries);
404 404 return d->m_sum;
405 405 }
406 406
407 407 /*!
408 408 \fn void QPieSeries::clicked(QPieSlice* slice)
409 409
410 410 This signal is emitted when a \a slice has been clicked.
411 411
412 412 \sa QPieSlice::clicked()
413 413 */
414 414
415 415 /*!
416 416 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
417 417
418 418 This signal is emitted when user has hovered over or away from the \a slice.
419 419
420 420 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
421 421
422 422 \sa QPieSlice::hovered()
423 423 */
424 424
425 425 /*!
426 426 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
427 427 Sets the \a model to be used as a data source
428 428 */
429 429 void QPieSeries::setModel(QAbstractItemModel* model)
430 430 {
431 431 Q_D(QPieSeries);
432 432 // disconnect signals from old model
433 433 if(d->m_model)
434 434 {
435 435 disconnect(d->m_model, 0, this, 0);
436 436 }
437 437
438 438 // set new model
439 439 if(model)
440 440 {
441 441 d->m_model = model;
442 // connect signals from the model
443 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
444 connect(d->m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
445 connect(d->m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
446 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
447 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
448
442 449 if (d->m_mapper)
443 d->setMapping();
450 d->initializePieFromModel();
444 451 }
445 452 else
446 453 {
447 454 d->m_model = 0;
448 455 }
449 456 }
450 457
451 458 void QPieSeries::setModelMapper(QPieModelMapper *mapper)
452 459 {
453 460 Q_D(QPieSeries);
454 461 // disconnect signals from old mapper
455 462 if (d->m_mapper) {
456 463 QObject::disconnect(d->m_mapper, 0, this, 0);
457 464 }
458 465
459 466 if (mapper) {
460 467 d->m_mapper = mapper;
468 // connect the signal from the mapper
469 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(initializePieFromModel()));
470
461 471 if (d->m_model)
462 d->setMapping();
472 d->initializePieFromModel();
463 473 } else {
464 474 d->m_mapper = 0;
465 475 }
466 476 }
467 477
468 478 QPieModelMapper* QPieSeries::modelMapper() const
469 479 {
470 480 Q_D(const QPieSeries);
471 481 return d->m_mapper;
472 482 }
473 483
474 484 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
475 485
476 486
477 487 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
478 488 QAbstractSeriesPrivate(parent),
479 489 m_pieRelativeHorPos(0.5),
480 490 m_pieRelativeVerPos(0.5),
481 491 m_pieRelativeSize(0.7),
482 492 m_pieStartAngle(0),
483 493 m_pieEndAngle(360),
484 494 m_sum(0),
485 495 m_mapper(0)
486 496 {
487 497
488 498 }
489 499
490 500 QPieSeriesPrivate::~QPieSeriesPrivate()
491 501 {
492 502
493 503 }
494 504
495 505 void QPieSeriesPrivate::updateDerivativeData()
496 506 {
497 507 m_sum = 0;
498 508
499 509 // nothing to do?
500 510 if (m_slices.count() == 0)
501 511 return;
502 512
503 513 // calculate sum of all slices
504 514 foreach (QPieSlice* s, m_slices)
505 515 m_sum += s->value();
506 516
507 517 // nothing to show..
508 518 if (qFuzzyIsNull(m_sum))
509 519 return;
510 520
511 521 // update slice attributes
512 522 qreal sliceAngle = m_pieStartAngle;
513 523 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
514 524 QVector<QPieSlice*> changed;
515 525 foreach (QPieSlice* s, m_slices) {
516 526
517 527 PieSliceData data = PieSliceData::data(s);
518 528 data.m_percentage = s->value() / m_sum;
519 529 data.m_angleSpan = pieSpan * data.m_percentage;
520 530 data.m_startAngle = sliceAngle;
521 531 sliceAngle += data.m_angleSpan;
522 532
523 533 if (PieSliceData::data(s) != data) {
524 534 PieSliceData::data(s) = data;
525 535 changed << s;
526 536 }
527 537 }
528 538
529 539 // emit signals
530 540 foreach (QPieSlice* s, changed)
531 541 PieSliceData::data(s).emitChangedSignal(s);
532 542 }
533 543
534 544 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
535 545 {
536 546 return series.d_func();
537 547 }
538 548
539 549 void QPieSeriesPrivate::sliceChanged()
540 550 {
541 551 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
542 552 updateDerivativeData();
543 553 }
544 554
545 555 void QPieSeriesPrivate::sliceClicked()
546 556 {
547 557 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
548 558 Q_ASSERT(m_slices.contains(slice));
549 559 Q_Q(QPieSeries);
550 560 emit q->clicked(slice);
551 561 }
552 562
553 563 void QPieSeriesPrivate::sliceHovered(bool state)
554 564 {
555 565 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
556 566 Q_ASSERT(m_slices.contains(slice));
557 567 Q_Q(QPieSeries);
558 568 emit q->hovered(slice, state);
559 569 }
560 570
561 571 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
562 572 {
563 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
564 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
565 if (m_mapper->orientation() == Qt::Vertical)
566 {
567 if ( topLeft.row() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.row() < m_mapper->first() + m_mapper->count())) {
568 if (topLeft.column() == m_mapper->mapValues())
569 m_slices.at(topLeft.row() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
570 if (topLeft.column() == m_mapper->mapLabels())
571 m_slices.at(topLeft.row() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
573 if (m_mapper) {
574 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
575 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
576 if (m_mapper->orientation() == Qt::Vertical)
577 {
578 if ( topLeft.row() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.row() < m_mapper->first() + m_mapper->count())) {
579 if (topLeft.column() == m_mapper->mapValues())
580 m_slices.at(topLeft.row() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
581 if (topLeft.column() == m_mapper->mapLabels())
582 m_slices.at(topLeft.row() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
583 }
572 584 }
573 }
574 else
575 {
576 if (topLeft.column() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.column() < m_mapper->first() + m_mapper->count())) {
577 if (topLeft.row() == m_mapper->mapValues())
578 m_slices.at(topLeft.column() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
579 if (topLeft.row() == m_mapper->mapLabels())
580 m_slices.at(topLeft.column() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
585 else
586 {
587 if (topLeft.column() >= m_mapper->first() && (m_mapper->count() == - 1 || topLeft.column() < m_mapper->first() + m_mapper->count())) {
588 if (topLeft.row() == m_mapper->mapValues())
589 m_slices.at(topLeft.column() - m_mapper->first())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
590 if (topLeft.row() == m_mapper->mapLabels())
591 m_slices.at(topLeft.column() - m_mapper->first())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
592 }
581 593 }
582 594 }
583 595 }
584 596 }
585 597 }
586 598
587 599
588 600 void QPieSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
589 601 {
590 602 Q_UNUSED(parent);
591 if (m_mapper->orientation() == Qt::Vertical)
592 insertData(start, end);
593 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
594 initializePieFromModel();
603 if (m_mapper) {
604 if (m_mapper->orientation() == Qt::Vertical)
605 insertData(start, end);
606 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
607 initializePieFromModel();
608 }
595 609 }
596 610
597 611 void QPieSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
598 612 {
599 613 Q_UNUSED(parent);
600 if (m_mapper->orientation() == Qt::Vertical)
601 removeData(start, end);
602 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
603 initializePieFromModel();
614 if (m_mapper) {
615 if (m_mapper->orientation() == Qt::Vertical)
616 removeData(start, end);
617 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
618 initializePieFromModel();
619 }
604 620 }
605 621
606 622 void QPieSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
607 623 {
608 624 Q_UNUSED(parent);
609 if (m_mapper->orientation() == Qt::Horizontal)
610 insertData(start, end);
611 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
612 initializePieFromModel();
625 if (m_mapper) {
626 if (m_mapper->orientation() == Qt::Horizontal)
627 insertData(start, end);
628 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
629 initializePieFromModel();
630 }
613 631 }
614 632
615 633 void QPieSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
616 634 {
617 635 Q_UNUSED(parent);
618 if (m_mapper->orientation() == Qt::Horizontal)
619 removeData(start, end);
620 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
621 initializePieFromModel();
636 if (m_mapper) {
637 if (m_mapper->orientation() == Qt::Horizontal)
638 removeData(start, end);
639 else if (start <= m_mapper->mapValues() || start <= m_mapper->mapLabels()) // if the changes affect the map - reinitialize the pie
640 initializePieFromModel();
641 }
622 642 }
623 643
624 644 void QPieSeriesPrivate::insertData(int start, int end)
625 645 {
626 646 Q_Q(QPieSeries);
627 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
628 return;
629 } else {
630 int addedCount = end - start + 1;
631 if (m_mapper->count() != -1 && addedCount > m_mapper->count())
632 addedCount = m_mapper->count();
633 int first = qMax(start, m_mapper->first());
634 int last = qMin(first + addedCount - 1, m_mapper->orientation() == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
635 for (int i = first; i <= last; i++) {
636 QPieSlice *slice = new QPieSlice;
637 if (m_mapper->orientation() == Qt::Vertical) {
638 slice->setValue(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
639 slice->setLabel(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
640 } else {
641 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
642 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
647 if (m_mapper) {
648 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
649 return;
650 } else {
651 int addedCount = end - start + 1;
652 if (m_mapper->count() != -1 && addedCount > m_mapper->count())
653 addedCount = m_mapper->count();
654 int first = qMax(start, m_mapper->first());
655 int last = qMin(first + addedCount - 1, m_mapper->orientation() == Qt::Vertical ? m_model->rowCount() - 1 : m_model->columnCount() - 1);
656 for (int i = first; i <= last; i++) {
657 QPieSlice *slice = new QPieSlice;
658 if (m_mapper->orientation() == Qt::Vertical) {
659 slice->setValue(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble());
660 slice->setLabel(m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
661 } else {
662 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble());
663 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
664 }
665 slice->setLabelVisible();
666 q->insert(i - m_mapper->first(), slice);
643 667 }
644 slice->setLabelVisible();
645 q->insert(i - m_mapper->first(), slice);
668 if (m_mapper->count() != -1 && m_slices.size() > m_mapper->count())
669 for (int i = m_slices.size() - 1; i >= m_mapper->count(); i--)
670 q->remove(q->slices().at(i));
646 671 }
647 if (m_mapper->count() != -1 && m_slices.size() > m_mapper->count())
648 for (int i = m_slices.size() - 1; i >= m_mapper->count(); i--)
649 q->remove(q->slices().at(i));
650 672 }
651 673 }
652 674
653 675 void QPieSeriesPrivate::removeData(int start, int end)
654 676 {
655 677 Q_Q(QPieSeries);
656 int removedCount = end - start + 1;
657 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
658 return;
659 } else {
660 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
661 int first = qMax(start, m_mapper->first()); // get the index of the first item that will be removed.
662 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapper->first() - 1); // get the index of the last item that will be removed.
663 for (int i = last; i >= first; i--)
664 q->remove(q->slices().at(i - m_mapper->first()));
665
666 if (m_mapper->count() != -1) {
667 int itemsAvailable; // check how many are available to be added
668 if (m_mapper->orientation() == Qt::Vertical)
669 itemsAvailable = m_model->rowCount() - m_mapper->first() - m_slices.size();
670 else
671 itemsAvailable = m_model->columnCount() - m_mapper->first() - m_slices.size();
672 int toBeAdded = qMin(itemsAvailable, m_mapper->count() - m_slices.size()); // add not more items than there is space left to be filled.
673 int currentSize = m_slices.size();
674 if (toBeAdded > 0)
675 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
676 QPieSlice *slice = new QPieSlice;
677 if (m_mapper->orientation() == Qt::Vertical) {
678 slice->setValue(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapValues()), Qt::DisplayRole).toDouble());
679 slice->setLabel(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapLabels()), Qt::DisplayRole).toString());
680 } else {
681 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i + m_mapper->first()), Qt::DisplayRole).toDouble());
682 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i + m_mapper->first()), Qt::DisplayRole).toString());
678 if (m_mapper) {
679 int removedCount = end - start + 1;
680 if (m_mapper->count() != -1 && start >= m_mapper->first() + m_mapper->count()) {
681 return;
682 } else {
683 int toRemove = qMin(m_slices.size(), removedCount); // first find how many items can actually be removed
684 int first = qMax(start, m_mapper->first()); // get the index of the first item that will be removed.
685 int last = qMin(first + toRemove - 1, m_slices.size() + m_mapper->first() - 1); // get the index of the last item that will be removed.
686 for (int i = last; i >= first; i--)
687 q->remove(q->slices().at(i - m_mapper->first()));
688
689 if (m_mapper->count() != -1) {
690 int itemsAvailable; // check how many are available to be added
691 if (m_mapper->orientation() == Qt::Vertical)
692 itemsAvailable = m_model->rowCount() - m_mapper->first() - m_slices.size();
693 else
694 itemsAvailable = m_model->columnCount() - m_mapper->first() - m_slices.size();
695 int toBeAdded = qMin(itemsAvailable, m_mapper->count() - m_slices.size()); // add not more items than there is space left to be filled.
696 int currentSize = m_slices.size();
697 if (toBeAdded > 0)
698 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
699 QPieSlice *slice = new QPieSlice;
700 if (m_mapper->orientation() == Qt::Vertical) {
701 slice->setValue(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapValues()), Qt::DisplayRole).toDouble());
702 slice->setLabel(m_model->data(m_model->index(i + m_mapper->first(), m_mapper->mapLabels()), Qt::DisplayRole).toString());
703 } else {
704 slice->setValue(m_model->data(m_model->index(m_mapper->mapValues(), i + m_mapper->first()), Qt::DisplayRole).toDouble());
705 slice->setLabel(m_model->data(m_model->index(m_mapper->mapLabels(), i + m_mapper->first()), Qt::DisplayRole).toString());
706 }
707 slice->setLabelVisible();
708 q->insert(i, slice);
683 709 }
684 slice->setLabelVisible();
685 q->insert(i, slice);
686 }
710 }
687 711 }
688 712 }
689 713 }
690 714
691 void QPieSeriesPrivate::setMapping()
692 {
693 initializePieFromModel();
694
695 // connect signals from the model
696 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
697 connect(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelRowsAdded(QModelIndex,int,int)));
698 connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelRowsRemoved(QModelIndex,int,int)));
699 connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelColumnsAdded(QModelIndex,int,int)));
700 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
701
702 // connect the signal from the mapper
703 connect(m_mapper, SIGNAL(updated()), this, SLOT(initializePieFromModel()));
704 }
705
706 715 void QPieSeriesPrivate::initializePieFromModel()
707 716 {
708 717 Q_Q(QPieSeries);
709 718 // clear current content
710 719 q->clear();
711 720
712 721 // create the initial slices set
713 722 if (m_mapper->orientation() == Qt::Vertical) {
714 723 if (m_mapper->mapValues() >= m_model->columnCount() || m_mapper->mapLabels() >= m_model->columnCount())
715 724 return; // mapped columns are not existing
716 725
717 726 int sliceCount = 0;
718 727 if(m_mapper->count() == -1)
719 728 sliceCount = m_model->rowCount() - m_mapper->first();
720 729 else
721 730 sliceCount = qMin(m_mapper->count(), m_model->rowCount() - m_mapper->first());
722 731 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
723 732 q->append(m_model->data(m_model->index(i, m_mapper->mapValues()), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapper->mapLabels()), Qt::DisplayRole).toString());
724 733 } else {
725 734 if (m_mapper->mapValues() >= m_model->rowCount() || m_mapper->mapLabels() >= m_model->rowCount())
726 735 return; // mapped columns are not existing
727 736
728 737 int sliceCount = 0;
729 738 if(m_mapper->count() == -1)
730 739 sliceCount = m_model->columnCount() - m_mapper->first();
731 740 else
732 741 sliceCount = qMin(m_mapper->count(), m_model->columnCount() - m_mapper->first());
733 742 for (int i = m_mapper->first(); i < m_mapper->first() + sliceCount; i++)
734 743 q->append(m_model->data(m_model->index(m_mapper->mapValues(), i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapper->mapLabels(), i), Qt::DisplayRole).toString());
735 744 }
736 745 q->setLabelsVisible(true);
737 746 }
738 747
739 748 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
740 749 {
741 750 // Remove rounding errors
742 751 qreal roundedValue = newValue;
743 752 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
744 753 roundedValue = 0.0;
745 754 else if (qFuzzyCompare(newValue, max))
746 755 roundedValue = max;
747 756 else if (qFuzzyCompare(newValue, min))
748 757 roundedValue = min;
749 758
750 759 // Check if the position is valid after removing the rounding errors
751 760 if (roundedValue < min || roundedValue > max) {
752 761 qWarning("QPieSeries: Illegal value");
753 762 return false;
754 763 }
755 764
756 765 if (!qFuzzyIsNull(value - roundedValue)) {
757 766 value = roundedValue;
758 767 return true;
759 768 }
760 769
761 770 // The change was so small it is considered a rounding error
762 771 return false;
763 772 }
764 773
765 774 void QPieSeriesPrivate::scaleDomain(Domain& domain)
766 775 {
767 776 Q_UNUSED(domain);
768 777 #ifndef QT_NO_DEBUG
769 778 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
770 779 #endif
771 780 }
772 781
773 782 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
774 783 {
775 784 Q_Q(QPieSeries);
776 785 PieChartItem* pie = new PieChartItem(q,presenter);
777 786 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
778 787 presenter->animator()->addAnimation(pie);
779 788 }
780 789 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
781 790 return pie;
782 791 }
783 792
784 793 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
785 794 {
786 795 Q_Q(QPieSeries);
787 796 QList<LegendMarker*> markers;
788 797 foreach(QPieSlice* slice, q->slices()) {
789 798 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
790 799 markers << marker;
791 800 }
792 801 return markers;
793 802 }
794 803
795 804 #include "moc_qpieseries.cpp"
796 805 #include "moc_qpieseries_p.cpp"
797 806
798 807 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,91 +1,90
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 #ifndef QPIESERIES_P_H
22 22 #define QPIESERIES_P_H
23 23
24 24 #include "qpieseries.h"
25 25 #include "qabstractseries_p.h"
26 26
27 27 class QModelIndex;
28 28
29 29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 30 class QLegendPrivate;
31 31 class QPieModelMapper;
32 32
33 33 class QPieSeriesPrivate : public QAbstractSeriesPrivate
34 34 {
35 35 Q_OBJECT
36 36
37 37 public:
38 38 QPieSeriesPrivate(QPieSeries *parent);
39 39 ~QPieSeriesPrivate();
40 40
41 41 void scaleDomain(Domain& domain);
42 42 Chart* createGraphics(ChartPresenter *presenter);
43 43 QList<LegendMarker*> createLegendMarker(QLegend *legend);
44 44
45 45 void updateDerivativeData();
46 46
47 47 static QPieSeriesPrivate* seriesData(QPieSeries &series);
48 48
49 49 Q_SIGNALS:
50 50 void added(QList<QPieSlice*> slices);
51 51 void removed(QList<QPieSlice*> slices);
52 52 void piePositionChanged();
53 53 void pieSizeChanged();
54 54
55 55 public Q_SLOTS:
56 56 void sliceChanged();
57 57 void sliceClicked();
58 58 void sliceHovered(bool state);
59 59 void initializePieFromModel();
60 60 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
61 61 void modelRowsAdded(QModelIndex parent, int start, int end);
62 62 void modelRowsRemoved(QModelIndex parent, int start, int end);
63 63 void modelColumnsAdded(QModelIndex parent, int start, int end);
64 64 void modelColumnsRemoved(QModelIndex parent, int start, int end);
65 65 bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0);
66 66
67 67 private:
68 void setMapping();
69 68 void insertData(int start, int end);
70 69 void removeData(int start, int end);
71 70
72 71 public:
73 72 QList<QPieSlice*> m_slices;
74 73 qreal m_pieRelativeHorPos;
75 74 qreal m_pieRelativeVerPos;
76 75 qreal m_pieRelativeSize;
77 76 qreal m_pieStartAngle;
78 77 qreal m_pieEndAngle;
79 78 qreal m_sum;
80 79
81 80 // model map
82 81 QPieModelMapper *m_mapper;
83 82
84 83 private:
85 84 friend class QLegendPrivate;
86 85 Q_DECLARE_PUBLIC(QPieSeries)
87 86 };
88 87
89 88 QTCOMMERCIALCHART_END_NAMESPACE
90 89
91 90 #endif // QPIESERIES_P_H
@@ -1,518 +1,524
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 "qxyseries.h"
22 22 #include "qxyseries_p.h"
23 23 #include "domain_p.h"
24 24 #include "legendmarker_p.h"
25 25 #include <QAbstractItemModel>
26 26 #include "qxymodelmapper.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 /*!
31 31 \class QXYSeries
32 32 \brief The QXYSeries class is a base class for line, spline and scatter series.
33 33 */
34 34
35 35 /*!
36 36 \fn QPen QXYSeries::pen() const
37 37 \brief Returns pen used to draw points for series.
38 38 \sa setPen()
39 39 */
40 40
41 41 /*!
42 42 \fn QBrush QXYSeries::brush() const
43 43 \brief Returns brush used to draw points for series.
44 44 \sa setBrush()
45 45 */
46 46
47 47 /*!
48 48 \fn void QXYSeries::clicked(const QPointF& point)
49 49 \brief Signal is emitted when user clicks the \a point on chart.
50 50 */
51 51
52 52
53 53 /*!
54 54 \fn void QXYSeriesPrivate::pointReplaced(int index)
55 55 \brief \internal \a index
56 56 */
57 57
58 58 /*!
59 59 \fn void QXYSeriesPrivate::pointAdded(int index)
60 60 \brief \internal \a index
61 61 */
62 62
63 63 /*!
64 64 \fn void QXYSeriesPrivate::pointRemoved(int index)
65 65 \brief \internal \a index
66 66 */
67 67
68 68 /*!
69 69 \fn void QXYSeriesPrivate::updated()
70 70 \brief \internal
71 71 */
72 72
73 73 /*!
74 74 \internal
75 75
76 76 Constructs empty series object which is a child of \a parent.
77 77 When series object is added to QChartView or QChart instance ownerships is transferred.
78 78 */
79 79 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
80 80 {
81 81
82 82 }
83 83 /*!
84 84 Destroys the object. Series added to QChartView or QChart instances are owned by those,
85 85 and are deleted when mentioned object are destroyed.
86 86 */
87 87 QXYSeries::~QXYSeries()
88 88 {
89 89 }
90 90
91 91 /*!
92 92 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
93 93 */
94 94 void QXYSeries::append(qreal x,qreal y)
95 95 {
96 96 append(QPointF(x,y));
97 97 }
98 98
99 99 /*!
100 100 This is an overloaded function.
101 101 Adds data \a point to the series. Points are connected with lines on the chart.
102 102 */
103 103 void QXYSeries::append(const QPointF &point)
104 104 {
105 105 Q_D(QXYSeries);
106 106 d->m_points<<point;
107 107 emit d->pointAdded(d->m_points.count()-1);
108 108 }
109 109
110 110 /*!
111 111 This is an overloaded function.
112 112 Adds list of data \a points to the series. Points are connected with lines on the chart.
113 113 */
114 114 void QXYSeries::append(const QList<QPointF> &points)
115 115 {
116 116 foreach(const QPointF& point , points) {
117 117 append(point);
118 118 }
119 119 }
120 120
121 121
122 122 void QXYSeries::replace(qreal oldX,qreal oldY,qreal newX,qreal newY)
123 123 {
124 124 replace(QPointF(oldX,oldY),QPointF(newX,newY));
125 125 }
126 126
127 127 void QXYSeries::replace(const QPointF &oldPoint,const QPointF &newPoint)
128 128 {
129 129 Q_D(QXYSeries);
130 130 int index = d->m_points.indexOf(oldPoint);
131 131 if(index==-1) return;
132 132 d->m_points[index] = newPoint;
133 133 emit d->pointReplaced(index);
134 134 }
135 135
136 136 /*!
137 137 Removes current \a x and \a y value.
138 138 */
139 139 void QXYSeries::remove(qreal x,qreal y)
140 140 {
141 141 remove(QPointF(x,y));
142 142 }
143 143
144 144 /*!
145 145 Removes current \a point x value. Note \a point y value is ignored.
146 146 */
147 147 void QXYSeries::remove(const QPointF &point)
148 148 {
149 149 Q_D(QXYSeries);
150 150 int index = d->m_points.indexOf(point);
151 151 if(index==-1) return;
152 152 d->m_points.remove(index);
153 153 emit d->pointRemoved(index);
154 154 }
155 155
156 156 /*!
157 157 Removes all data points from the series.
158 158 */
159 159 void QXYSeries::removeAll()
160 160 {
161 161 Q_D(QXYSeries);
162 162 foreach(const QPointF& point, d->m_points) {
163 163 remove(point);
164 164 }
165 165 }
166 166
167 167 /*!
168 168 \internal \a pos
169 169 */
170 170 QList<QPointF> QXYSeries::points() const
171 171 {
172 172 // Q_ASSERT(false);
173 173 Q_D(const QXYSeries);
174 174 if (d->m_model && d->m_mapper) {
175 175 QList<QPointF> result;
176 176 if (d->m_mapper->orientation() == Qt::Vertical){
177 177 // consecutive data is read from model's column
178 178 if (d->m_mapper->mapX() >= d->m_model->columnCount() || d->m_mapper->mapY() >= d->m_model->columnCount())
179 179 return result; // mapped columns are not existing
180 180
181 181 for(int i = d->m_mapper->first(); i< d->m_mapper->first() + count(); ++i) {
182 182 qreal x = d->m_model->data(d->m_model->index(i, d->m_mapper->mapX()), Qt::DisplayRole).toReal();
183 183 qreal y = d->m_model->data(d->m_model->index(i, d->m_mapper->mapY()), Qt::DisplayRole).toReal();
184 184 result << QPointF(x,y);
185 185 }
186 186 return result;
187 187 }
188 188 else{
189 189 // consecutive data is read from model's row
190 190 if (d->m_mapper->mapX() >= d->m_model->rowCount() || d->m_mapper->mapY() >= d->m_model->rowCount())
191 191 return result; // mapped rows are not existing
192 192
193 193 for(int i = d->m_mapper->first(); i< d->m_mapper->first() + count(); ++i) {
194 194 qreal x = d->m_model->data(d->m_model->index(d->m_mapper->mapX(), i), Qt::DisplayRole).toReal();
195 195 qreal y = d->m_model->data(d->m_model->index(d->m_mapper->mapY(), i), Qt::DisplayRole).toReal();
196 196 result << QPointF(x,y);
197 197 }
198 198 return result;
199 199 }
200 200 } else {
201 201 // model is not specified, return the data from series' internal data store
202 202 return d->m_points.toList();
203 203 }
204 204 }
205 205
206 206 /*!
207 207 Returns number of data points within series.
208 208 */
209 209 int QXYSeries::count() const
210 210 {
211 211 Q_D(const QXYSeries);
212 212
213 213 if (d->m_model && d->m_mapper) {
214 214
215 215 if (d->m_mapper->orientation() == Qt::Vertical) {
216 216 // data is in a column. Return the number of mapped items if the model's column have enough items
217 217 // or the number of items that can be mapped
218 218 if (d->m_mapper->mapX() >= d->m_model->columnCount() || d->m_mapper->mapY() >= d->m_model->columnCount())
219 219 return 0; // mapped columns are not existing
220 220 else if (d->m_mapper->count() != -1)
221 221 return qMin(d->m_mapper->count(), qMax(d->m_model->rowCount() - d->m_mapper->first(), 0));
222 222 else
223 223 return qMax(d->m_model->rowCount() - d->m_mapper->first(), 0);
224 224 } else {
225 225 // data is in a row. Return the number of mapped items if the model's row have enough items
226 226 // or the number of items that can be mapped
227 227 if (d->m_mapper->mapX() >= d->m_model->rowCount() || d->m_mapper->mapY() >= d->m_model->rowCount())
228 228 return 0; // mapped rows are not existing
229 229 else if (d->m_mapper->count() != -1)
230 230 return qMin(d->m_mapper->count(), qMax(d->m_model->columnCount() - d->m_mapper->first(), 0));
231 231 else
232 232 return qMax(d->m_model->columnCount() - d->m_mapper->first(), 0);
233 233 }
234 234 }
235 235
236 236 // model is not specified, return the number of points in the series internal data store
237 237 return d->m_points.count();
238 238 }
239 239
240 240
241 241 /*!
242 242 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
243 243 pen from chart theme is used.
244 244 \sa QChart::setTheme()
245 245 */
246 246 void QXYSeries::setPen(const QPen &pen)
247 247 {
248 248 Q_D(QXYSeries);
249 249 if (d->m_pen!=pen) {
250 250 d->m_pen = pen;
251 251 emit d->updated();
252 252 }
253 253 }
254 254
255 255 QPen QXYSeries::pen() const
256 256 {
257 257 Q_D(const QXYSeries);
258 258 return d->m_pen;
259 259 }
260 260
261 261 /*!
262 262 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
263 263 from chart theme setting is used.
264 264 \sa QChart::setTheme()
265 265 */
266 266 void QXYSeries::setBrush(const QBrush &brush)
267 267 {
268 268 Q_D(QXYSeries);
269 269 if (d->m_brush!=brush) {
270 270 d->m_brush = brush;
271 271 emit d->updated();
272 272 }
273 273 }
274 274
275 275 QBrush QXYSeries::brush() const
276 276 {
277 277 Q_D(const QXYSeries);
278 278 return d->m_brush;
279 279 }
280 280
281 281
282 282 /*!
283 283 Sets if data points are \a visible and should be drawn on line.
284 284 */
285 285 void QXYSeries::setPointsVisible(bool visible)
286 286 {
287 287 Q_D(QXYSeries);
288 288 if (d->m_pointsVisible != visible){
289 289 d->m_pointsVisible = visible;
290 290 emit d->updated();
291 291 }
292 292 }
293 293
294 294 /*!
295 295 Returns true if drawing the data points of the series is enabled.
296 296 */
297 297 bool QXYSeries::pointsVisible() const
298 298 {
299 299 Q_D(const QXYSeries);
300 300 return d->m_pointsVisible;
301 301 }
302 302
303 303
304 304 /*!
305 305 Stream operator for adding a data \a point to the series.
306 306 \sa append()
307 307 */
308 308 QXYSeries& QXYSeries::operator<< (const QPointF &point)
309 309 {
310 310 append(point);
311 311 return *this;
312 312 }
313 313
314 314
315 315 /*!
316 316 Stream operator for adding a list of \a points to the series.
317 317 \sa append()
318 318 */
319 319
320 320 QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points)
321 321 {
322 322 append(points);
323 323 return *this;
324 324 }
325 325
326 326 /*!
327 327 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
328 328 Sets the \a model to be used as a data source
329 329 \sa setModelMapping()
330 330 */
331 331 void QXYSeries::setModel(QAbstractItemModel *model)
332 332 {
333 333 Q_D(QXYSeries);
334 334 // disconnect signals from old model
335 335 if (d->m_model) {
336 336 QObject::disconnect(d->m_model, 0, this, 0);
337 337 }
338 338
339 339 // set new model
340 340 if (model) {
341 341 d->m_model = model;
342 if (d->m_mapper)
343 d->setMapping();
342 emit d->reinitialized();
343
344 // connect signals from the model
345 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
346 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
347 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
348 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
349 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
344 350 } else {
345 351 d->m_model = 0;
346 352 }
347 353 }
348 354
349 355 void QXYSeries::setModelMapper(QXYModelMapper *mapper)
350 356 {
351 357 Q_D(QXYSeries);
352 358 // disconnect signals from old mapper
353 359 if (d->m_mapper) {
354 360 QObject::disconnect(d->m_mapper, 0, this, 0);
355 361 }
356 362
357 363 if (mapper) {
358 364 d->m_mapper = mapper;
359 if (d->m_model)
360 d->setMapping();
365 emit d->reinitialized();
366
367 // connect the signal from the mapper
368 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(mappingUpdated()));
361 369 } else {
362 370 d->m_mapper = 0;
363 371 }
364 372 }
365 373
366 374 QXYModelMapper* QXYSeries::modelMapper() const
367 375 {
368 376 Q_D(const QXYSeries);
369 377 return d->m_mapper;
370 378 }
371 379
372 380 /*!
373 381 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
374 382 as a data source for y coordinate. The \a orientation parameter specifies whether the data
375 383 is in columns or in rows.
376 384 \sa setModel()
377 385 */
378 386
379 387
380 388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
381 389
382 390
383 391 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
384 392 m_mapper(0),
385 393 m_pointsVisible(false)
386 394 {
387 395 }
388 396
389 397 void QXYSeriesPrivate::scaleDomain(Domain& domain)
390 398 {
391 399 qreal minX(domain.minX());
392 400 qreal minY(domain.minY());
393 401 qreal maxX(domain.maxX());
394 402 qreal maxY(domain.maxY());
395 403 int tickXCount(domain.tickXCount());
396 404 int tickYCount(domain.tickYCount());
397 405
398 406 Q_Q(QXYSeries);
399 407
400 408 const QList<QPointF>& points = q->points();
401 409
402 410 // if(points.isEmpty()){
403 411 // minX=0.0;
404 412 // minY=0.0;
405 413 // maxX=1.0;
406 414 // maxY=1.0;
407 415 // }
408 416
409 417 // for (int i = 0; i < points.count(); i++)
410 418 // {
411 419 // qreal x = points[i].x();
412 420 // qreal y = points[i].y();
413 421 // minX = qMin(minX, x);
414 422 // minY = qMin(minY, y);
415 423 // maxX = qMax(maxX, x);
416 424 // maxY = qMax(maxY, y);
417 425 // }
418 426
419 427 // domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
420 428
421 429 if (!points.isEmpty()) {
422 430 for (int i = 0; i < points.count(); i++) {
423 431 qreal x = points[i].x();
424 432 qreal y = points[i].y();
425 433 minX = qMin(minX, x);
426 434 minY = qMin(minY, y);
427 435 maxX = qMax(maxX, x);
428 436 maxY = qMax(maxY, y);
429 437 }
430 438 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
431 439 }
432 440 }
433 441
434 442 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
435 443 {
436 444 Q_Q(QXYSeries);
437 445 QList<LegendMarker*> list;
438 446 return list << new XYLegendMarker(q,legend);
439 447 }
440 448
441 void QXYSeriesPrivate::setMapping()
442 {
443 // connect signals from the model
444 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
445 connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelRowsAdded(QModelIndex,int,int)));
446 connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelRowsRemoved(QModelIndex,int,int)));
447 connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelColumnsAdded(QModelIndex,int,int)));
448 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
449
450 // connect the signal from the mapper
451 connect(m_mapper, SIGNAL(updated()), this, SLOT(mappingUpdated()));
452 }
453
454 449 void QXYSeriesPrivate::mappingUpdated()
455 450 {
456 emit reinitialized();
451 if (m_model)
452 emit reinitialized();
457 453 }
458 454
459 455 void QXYSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
460 456 {
461 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
462 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
463 if (m_mapper->orientation() == Qt::Vertical) {
464 if ((column == m_mapper->mapX() || column == m_mapper->mapY()) // modified item is in a mapped column
465 && row >= m_mapper->first() // modfied item in not before first item
466 && (m_mapper->count() == -1 || row < m_mapper->first() + m_mapper->count())) // map is not limited or item lays before the end of map
467 emit pointReplaced(row - m_mapper->first());
468 } else {
469 if ((row == m_mapper->mapX() || row == m_mapper->mapY()) // modified item is in a mapped row
470 && column >= m_mapper->first() // modfied item in not before first item
471 && (m_mapper->count() == -1 || column < m_mapper->first() + m_mapper->count())) // map is not limited or item lays before the end of map
472 emit pointReplaced(column - m_mapper->first());
457 if (m_mapper) {
458 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
459 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
460 if (m_mapper->orientation() == Qt::Vertical) {
461 if ((column == m_mapper->mapX() || column == m_mapper->mapY()) // modified item is in a mapped column
462 && row >= m_mapper->first() // modfied item in not before first item
463 && (m_mapper->count() == -1 || row < m_mapper->first() + m_mapper->count())) // map is not limited or item lays before the end of map
464 emit pointReplaced(row - m_mapper->first());
465 } else {
466 if ((row == m_mapper->mapX() || row == m_mapper->mapY()) // modified item is in a mapped row
467 && column >= m_mapper->first() // modfied item in not before first item
468 && (m_mapper->count() == -1 || column < m_mapper->first() + m_mapper->count())) // map is not limited or item lays before the end of map
469 emit pointReplaced(column - m_mapper->first());
470 }
473 471 }
474 472 }
475 473 }
476 474 }
477 475
478 476
479 477 void QXYSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
480 478 {
481 479 Q_UNUSED(parent);
482 if (m_mapper->orientation() == Qt::Vertical)
483 emit pointsAdded(start, end);
484 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
485 emit reinitialized();
480 if (m_mapper) {
481 if (m_mapper->orientation() == Qt::Vertical)
482 emit pointsAdded(start, end);
483 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
484 emit reinitialized();
485 }
486 486 }
487 487
488 488 void QXYSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
489 489 {
490 490 Q_UNUSED(parent);
491 if (m_mapper->orientation() == Qt::Vertical)
492 emit pointsRemoved(start, end);
493 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
494 emit reinitialized();
491 if (m_mapper) {
492 if (m_mapper->orientation() == Qt::Vertical)
493 emit pointsRemoved(start, end);
494 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
495 emit reinitialized();
496 }
495 497 }
496 498
497 499 void QXYSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
498 500 {
499 501 Q_UNUSED(parent);
500 if (m_mapper->orientation() == Qt::Horizontal)
501 emit pointsAdded(start, end);
502 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
503 emit reinitialized();
502 if (m_mapper) {
503 if (m_mapper->orientation() == Qt::Horizontal)
504 emit pointsAdded(start, end);
505 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
506 emit reinitialized();
507 }
504 508 }
505 509
506 510 void QXYSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
507 511 {
508 512 Q_UNUSED(parent);
509 if (m_mapper->orientation() == Qt::Horizontal)
510 emit pointsRemoved(start, end);
511 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
512 emit reinitialized();
513 if (m_mapper) {
514 if (m_mapper->orientation() == Qt::Horizontal)
515 emit pointsRemoved(start, end);
516 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
517 emit reinitialized();
518 }
513 519 }
514 520
515 521 #include "moc_qxyseries.cpp"
516 522 #include "moc_qxyseries_p.cpp"
517 523
518 524 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,88 +1,87
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 QXYSERIES_P_H
31 31 #define QXYSERIES_P_H
32 32
33 33 #include "qabstractseries_p.h"
34 34
35 35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 36
37 37 class QXYSeries;
38 38 class QXYModelMapper;
39 39
40 40 class QXYSeriesPrivate: public QAbstractSeriesPrivate
41 41 {
42 42 Q_OBJECT
43 43
44 44 public:
45 45 QXYSeriesPrivate(QXYSeries* q);
46 46
47 47 void scaleDomain(Domain& domain);
48 48 QList<LegendMarker*> createLegendMarker(QLegend* legend);
49 49
50 50 protected Q_SLOTS:
51 51 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
52 52 virtual void modelRowsAdded(QModelIndex parent, int start, int end);
53 53 virtual void modelRowsRemoved(QModelIndex parent, int start, int end);
54 54 virtual void modelColumnsAdded(QModelIndex parent, int start, int end);
55 55 virtual void modelColumnsRemoved(QModelIndex parent, int start, int end);
56 56 virtual void mappingUpdated();
57 57
58 58 private:
59 void setMapping();
60 59 void insertData(int start, int end);
61 60 void removeData(int start, int end);
62 61
63 62 Q_SIGNALS:
64 63 void updated();
65 64 void pointReplaced(int index);
66 65 void pointRemoved(int index);
67 66 void pointsRemoved(int start, int end);
68 67 void pointAdded(int index);
69 68 void pointsAdded(int start, int end);
70 69 void reinitialized();
71 70
72 71 protected:
73 72 QVector<QPointF> m_points;
74 73
75 74 QPen m_pen;
76 75 QBrush m_brush;
77 76 QXYModelMapper* m_mapper;
78 77 bool m_pointsVisible;
79 78
80 79 private:
81 80 Q_DECLARE_PUBLIC(QXYSeries);
82 81 friend class QScatterSeries;
83 82
84 83 };
85 84
86 85 QTCOMMERCIALCHART_END_NAMESPACE
87 86
88 87 #endif
General Comments 0
You need to be logged in to leave comments. Login now