##// END OF EJS Templates
Added data from model support to QPieSeries(modify, remove). Data from model example updated
Marek Rosa -
r597:fed5cb29c884
parent child
Show More
@@ -1,121 +1,133
1 1 #include "tablewidget.h"
2 2 #include <QGridLayout>
3 3 #include <QTableView>
4 4 #include <QStyledItemDelegate>
5 5 #include "qlineseries.h"
6 6 #include "qsplineseries.h"
7 7 #include "qscatterseries.h"
8 8 #include "customtablemodel.h"
9 9 #include "qpieseries.h"
10 10 #include <QPushButton>
11 11 #include <QRadioButton>
12 12
13 13 TableWidget::TableWidget(QWidget *parent)
14 14 : QWidget(parent)
15 15 {
16 16 setGeometry(100, 100, 1000, 600);
17 17 // create simple model for storing data
18 18 // user's table data model
19 19 m_model = new CustomTableModel;
20 20 tableView = new QTableView;
21 21 tableView->setModel(m_model);
22 22 tableView->setMinimumSize(340, 480);
23 23 // tableView->setItemDelegate(new QStyledItemDelegate);
24 24 chartView = new QChartView(this);
25 25 chartView->setMinimumSize(640, 480);
26 26
27 27 // create
28 28 // QLineSeries* series = new QLineSeries;
29 29 // QSplineSeries* series = new QSplineSeries;
30 30 // QScatterSeries* series = new QScatterSeries;
31 31 // series->setModel(m_model);
32 32 // series->setModelMapping(0,1, Qt::Vertical);
33 33
34 34 // QPieSeries* pieSeries = new QPieSeries;
35 35 // pieSeries->setModel(model);
36 36 // pieSeries
37 37
38 38 // chartView->addSeries(series);
39 39
40 40 // add, remove data buttons
41 41 QPushButton* addRowAboveButton = new QPushButton("Add row above");
42 42 connect(addRowAboveButton, SIGNAL(clicked()), this, SLOT(addRowAbove()));
43 43
44 44 QPushButton* addRowBelowButton = new QPushButton("Add row below");
45 45 connect(addRowBelowButton, SIGNAL(clicked()), this, SLOT(addRowBelow()));
46 46
47 47 QPushButton* removeRowButton = new QPushButton("Remove row");
48 48 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
49 49
50 50 // buttons layout
51 51 QVBoxLayout* buttonsLayout = new QVBoxLayout;
52 52 buttonsLayout->addWidget(addRowAboveButton);
53 53 buttonsLayout->addWidget(addRowBelowButton);
54 54 buttonsLayout->addWidget(removeRowButton);
55 55 buttonsLayout->addStretch();
56 56
57 57 // chart type radio buttons
58 58 lineRadioButton = new QRadioButton("Line");
59 59 splineRadioButton = new QRadioButton("Spline");
60 60 scatterRadioButton = new QRadioButton("Scatter");
61 pieRadioButton = new QRadioButton("Pie");
61 62
62 63 connect(lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
63 64 connect(splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
64 65 connect(scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
66 connect(pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType()));
65 67 lineRadioButton->setChecked(true);
66 68
67 69 // radio buttons layout
68 70 QHBoxLayout* radioLayout = new QHBoxLayout;
69 71 radioLayout->addWidget(lineRadioButton);
70 72 radioLayout->addWidget(splineRadioButton);
71 73 radioLayout->addWidget(scatterRadioButton);
74 radioLayout->addWidget(pieRadioButton);
72 75
73 76 // create main layout
74 77 QGridLayout* mainLayout = new QGridLayout;
75 78 mainLayout->addLayout(buttonsLayout, 0, 1);
76 79 mainLayout->addLayout(radioLayout, 0, 2);
77 80 mainLayout->addWidget(tableView, 1, 1);
78 81 mainLayout->addWidget(chartView, 1, 2);
79 82 setLayout(mainLayout);
80 83 }
81 84
82 85 void TableWidget::addRowAbove()
83 86 {
84 87 // m_model->insertRow(m_model->rowCount());
85 88 m_model->insertRow(tableView->currentIndex().row());
86 89
87 90 }
88 91
89 92 void TableWidget::addRowBelow()
90 93 {
91 94 // m_model->insertRow(m_model->rowCount());
92 95 m_model->insertRow(tableView->currentIndex().row() + 1);
93 96
94 97 }
95 98
96 99 void TableWidget::removeRow()
97 100 {
98 101 // m_model->removeRow(m_model->rowCount() - 1);
99 102 m_model->removeRow(tableView->currentIndex().row());
100 103 }
101 104
102 105 void TableWidget::updateChartType()
103 106 {
104 107 chartView->removeAllSeries();
105 108
106 109 if (lineRadioButton->isChecked())
107 110 series = new QLineSeries;
108 111 else if (splineRadioButton->isChecked())
109 112 series = new QSplineSeries;
110 else
113 else if (scatterRadioButton->isChecked())
111 114 series = new QScatterSeries;
115 else if (pieRadioButton->isChecked())
116 {
117 QPieSeries* pieSeries = new QPieSeries;
118 pieSeries->setModel(m_model);
119 pieSeries->setModelMapping(0,2, Qt::Vertical);
120 pieSeries->setLabelsVisible(true);
121 chartView->addSeries(pieSeries);
122 return;
123 }
112 124
113 125 series->setModel(m_model);
114 126 series->setModelMapping(0,1, Qt::Vertical);
115 127 chartView->addSeries(series);
116 128 }
117 129
118 130 TableWidget::~TableWidget()
119 131 {
120 132
121 133 }
@@ -1,40 +1,41
1 1 #ifndef TABLEWIDGET_H
2 2 #define TABLEWIDGET_H
3 3
4 4 #include <QtGui/QWidget>
5 5 #include "qchartview.h"
6 6 #include "qxyseries.h"
7 7
8 8 QTCOMMERCIALCHART_USE_NAMESPACE
9 9
10 10 class CustomTableModel;
11 11 class QTableView;
12 12 class QRadioButton;
13 13 //class QSeries;
14 14
15 15 class TableWidget : public QWidget
16 16 {
17 17 Q_OBJECT
18 18
19 19 public:
20 20 TableWidget(QWidget *parent = 0);
21 21 ~TableWidget();
22 22
23 23
24 24 public slots:
25 25 void addRowAbove();
26 26 void addRowBelow();
27 27 void removeRow();
28 28 void updateChartType();
29 29
30 30 private:
31 31 QChartView* chartView;
32 32 QXYSeries* series;
33 33 CustomTableModel* m_model;
34 34 QTableView* tableView;
35 35 QRadioButton* lineRadioButton;
36 36 QRadioButton* splineRadioButton;
37 37 QRadioButton* scatterRadioButton;
38 QRadioButton* pieRadioButton;
38 39 };
39 40
40 41 #endif // TABLEWIDGET_H
@@ -1,536 +1,601
1 1 #include "qpieseries.h"
2 2 #include "qpieslice.h"
3 3 #include <QDebug>
4 4
5 5 QTCOMMERCIALCHART_BEGIN_NAMESPACE
6 6
7 7
8 8 /*!
9 9 \class QPieSeries::ChangeSet
10 10 \brief Defines the changes in the series.
11 11
12 12 Contains the changes that have occurred in the series. Lists of added, changed and removed slices.
13 13
14 14 \sa QPieSeries::changed()
15 15 */
16 16
17 17 /*!
18 18 \internal
19 19 */
20 20 void QPieSeries::ChangeSet::appendAdded(QPieSlice* slice)
21 21 {
22 22 if (!m_added.contains(slice))
23 23 m_added << slice;
24 24 }
25 25
26 26 /*!
27 27 \internal
28 28 */
29 29 void QPieSeries::ChangeSet::appendAdded(QList<QPieSlice*> slices)
30 30 {
31 31 foreach (QPieSlice* s, slices)
32 32 appendAdded(s);
33 33 }
34 34
35 35 /*!
36 36 \internal
37 37 */
38 38 void QPieSeries::ChangeSet::appendChanged(QPieSlice* slice)
39 39 {
40 40 if (!m_changed.contains(slice))
41 41 m_changed << slice;
42 42 }
43 43
44 44 /*!
45 45 \internal
46 46 */
47 47 void QPieSeries::ChangeSet::appendRemoved(QPieSlice* slice)
48 48 {
49 49 if (!m_removed.contains(slice))
50 50 m_removed << slice;
51 51 }
52 52
53 53 /*!
54 54 Returns a list of slices that have been added to the series.
55 55 \sa QPieSeries::changed()
56 56 */
57 57 QList<QPieSlice*> QPieSeries::ChangeSet::added() const
58 58 {
59 59 return m_added;
60 60 }
61 61
62 62 /*!
63 63 Returns a list of slices that have been changed in the series.
64 64 \sa QPieSeries::changed()
65 65 */
66 66 QList<QPieSlice*> QPieSeries::ChangeSet::changed() const
67 67 {
68 68 return m_changed;
69 69 }
70 70
71 71 /*!
72 72 Returns a list of slices that have been removed from the series.
73 73 \sa QPieSeries::changed()
74 74 */
75 75 QList<QPieSlice*> QPieSeries::ChangeSet::removed() const
76 76 {
77 77 return m_removed;
78 78 }
79 79
80 80
81 81 /*!
82 82 Returns true if there are no added/changed or removed slices in the change set.
83 83 */
84 84 bool QPieSeries::ChangeSet::isEmpty() const
85 85 {
86 86 if (m_added.count() || m_changed.count() || m_removed.count())
87 87 return false;
88 88 return true;
89 89 }
90 90
91 91 /*!
92 92 \class QPieSeries
93 93 \brief Pie series API for QtCommercial Charts
94 94
95 95 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
96 96 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
97 97 The actual slice size is determined by that relative value.
98 98
99 99 By default the pie is defined as a full pie but it can be a partial pie.
100 100 This can be done by setting a starting angle and angle span to the series.
101 101 */
102 102
103 103 /*!
104 104 Constructs a series object which is a child of \a parent.
105 105 */
106 106 QPieSeries::QPieSeries(QObject *parent) :
107 107 QSeries(parent),
108 108 m_pieRelativeHorPos(0.5),
109 109 m_pieRelativeVerPos(0.5),
110 110 m_pieRelativeSize(0.7),
111 111 m_pieStartAngle(0),
112 112 m_pieEndAngle(360),
113 113 m_total(0)
114 114 {
115 115
116 116 }
117 117
118 118 /*!
119 119 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
120 120 */
121 121 QPieSeries::~QPieSeries()
122 122 {
123 123
124 124 }
125 125
126 126 /*!
127 127 Returns QChartSeries::SeriesTypePie.
128 128 */
129 129 QSeries::QSeriesType QPieSeries::type() const
130 130 {
131 131 return QSeries::SeriesTypePie;
132 132 }
133 133
134 134 /*!
135 135 Sets an array of \a slices to the series replacing the existing slices.
136 136 Slice ownership is passed to the series.
137 137 */
138 138 void QPieSeries::replace(QList<QPieSlice*> slices)
139 139 {
140 140 clear();
141 141 add(slices);
142 142 }
143 143
144 144 /*!
145 145 Adds an array of \a slices to the series.
146 146 Slice ownership is passed to the series.
147 147 */
148 148 void QPieSeries::add(QList<QPieSlice*> slices)
149 149 {
150 150 foreach (QPieSlice* s, slices) {
151 151 s->setParent(this);
152 152 m_slices << s;
153 153 }
154 154
155 155 updateDerivativeData();
156 156
157 157 foreach (QPieSlice* s, slices) {
158 158 connect(s, SIGNAL(changed()), this, SLOT(sliceChanged()));
159 159 connect(s, SIGNAL(clicked()), this, SLOT(sliceClicked()));
160 160 connect(s, SIGNAL(hoverEnter()), this, SLOT(sliceHoverEnter()));
161 161 connect(s, SIGNAL(hoverLeave()), this, SLOT(sliceHoverLeave()));
162 162 }
163 163
164 164 emit changed();
165 165 }
166 166
167 167 /*!
168 168 Adds a single \a slice to the series.
169 169 Slice ownership is passed to the series.
170 170 */
171 171 void QPieSeries::add(QPieSlice* slice)
172 172 {
173 173 add(QList<QPieSlice*>() << slice);
174 174 }
175 175
176 176 /*!
177 177 Adds a single \a slice to the series and returns a reference to the series.
178 178 Slice ownership is passed to the series.
179 179 */
180 180 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
181 181 {
182 182 add(slice);
183 183 return *this;
184 184 }
185 185
186 186
187 187 /*!
188 188 Adds a single slice to the series with give \a value and \a name.
189 189 Slice ownership is passed to the series.
190 190 */
191 191 QPieSlice* QPieSeries::add(qreal value, QString name)
192 192 {
193 193 QPieSlice* slice = new QPieSlice(value, name);
194 194 add(slice);
195 195 return slice;
196 196 }
197 197
198 198 /*!
199 199 Removes a single \a slice from the series and deletes the slice.
200 200
201 201 Do not reference this pointer after this call.
202 202 */
203 203 void QPieSeries::remove(QPieSlice* slice)
204 204 {
205 205 if (!m_slices.removeOne(slice)) {
206 206 Q_ASSERT(0); // TODO: how should this be reported?
207 207 return;
208 208 }
209 209 emit changed();
210 210
211 211 updateDerivativeData();
212 212
213 213 delete slice;
214 214 slice = NULL;
215 215 }
216 216
217 217 /*!
218 218 Clears all slices from the series.
219 219 */
220 220 void QPieSeries::clear()
221 221 {
222 222 if (m_slices.count() == 0)
223 223 return;
224 224
225 225 foreach (QPieSlice* s, m_slices) {
226 226 m_slices.removeOne(s);
227 227 delete s;
228 228 }
229 229
230 230 emit changed();
231 231
232 232 updateDerivativeData();
233 233 }
234 234
235 235 /*!
236 236 Counts the number of the slices in this series.
237 237 */
238 238 int QPieSeries::count() const
239 239 {
240 240 return m_slices.count();
241 241 }
242 242
243 243 /*!
244 244 Returns a list of slices that belong to this series.
245 245 */
246 246 QList<QPieSlice*> QPieSeries::slices() const
247 247 {
248 248 return m_slices;
249 249 }
250 250
251 251 /*!
252 252 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
253 253
254 254 The factors are relative to the chart rectangle where:
255 255
256 256 \a relativeHorizontalPosition 0.0 means the absolute left.
257 257 \a relativeHorizontalPosition 1.0 means the absolute right.
258 258 \a relativeVerticalPosition 0.0 means the absolute top.
259 259 \a relativeVerticalPosition 1.0 means the absolute bottom.
260 260
261 261 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
262 262
263 263 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
264 264 */
265 265 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
266 266 {
267 267 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
268 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
268 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
269 269 return;
270 270
271 271 if (m_pieRelativeHorPos != relativeHorizontalPosition || m_pieRelativeVerPos != relativeVerticalPosition) {
272 272 m_pieRelativeHorPos = relativeHorizontalPosition;
273 273 m_pieRelativeVerPos = relativeVerticalPosition;
274 274 emit changed();
275 275 }
276 276 }
277 277
278 278 /*!
279 279 Gets the horizontal position of the pie.
280 280
281 281 The returned value is relative to the chart rectangle where:
282 282
283 283 0.0 means the absolute left.
284 284 1.0 means the absolute right.
285 285
286 286 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
287 287
288 288 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
289 289 */
290 290 qreal QPieSeries::pieHorizontalPosition() const
291 291 {
292 292 return m_pieRelativeHorPos;
293 293 }
294 294
295 295 /*!
296 296 Gets the vertical position position of the pie.
297 297
298 298 The returned value is relative to the chart rectangle where:
299 299
300 300 0.0 means the absolute top.
301 301 1.0 means the absolute bottom.
302 302
303 303 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
304 304
305 305 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
306 306 */
307 307 qreal QPieSeries::pieVerticalPosition() const
308 308 {
309 309 return m_pieRelativeVerPos;
310 310 }
311 311
312 312 /*!
313 313 Sets the relative size of the pie.
314 314
315 315 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
316 316
317 317 Default value is 0.7.
318 318
319 319 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
320 320 */
321 321 void QPieSeries::setPieSize(qreal relativeSize)
322 322 {
323 323 if (relativeSize < 0.0 || relativeSize > 1.0)
324 324 return;
325 325
326 326 if (m_pieRelativeSize != relativeSize) {
327 327 m_pieRelativeSize = relativeSize;
328 328 emit changed();
329 329 }
330 330 }
331 331
332 332 /*!
333 333 Gets the relative size of the pie.
334 334
335 335 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
336 336
337 337 Default value is 0.7.
338 338
339 339 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
340 340 */
341 341 qreal QPieSeries::pieSize() const
342 342 {
343 343 return m_pieRelativeSize;
344 344 }
345 345
346 346
347 347 /*!
348 348 Sets the end angle of the pie.
349 349
350 350 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
351 351
352 352 \a angle must be less than pie end angle. Default value is 0.
353 353
354 354 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
355 355 */
356 356 void QPieSeries::setPieStartAngle(qreal angle)
357 357 {
358 358 if (angle >= 0 && angle <= 360 && angle != m_pieStartAngle && angle <= m_pieEndAngle) {
359 359 m_pieStartAngle = angle;
360 360 updateDerivativeData();
361 361 }
362 362 }
363 363
364 364 /*!
365 365 Gets the start angle of the pie.
366 366
367 367 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
368 368
369 369 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
370 370 */
371 371 qreal QPieSeries::pieStartAngle() const
372 372 {
373 373 return m_pieStartAngle;
374 374 }
375 375
376 376 /*!
377 377 Sets the end angle of the pie.
378 378
379 379 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
380 380
381 381 \a angle must be greater than start angle.
382 382
383 383 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
384 384 */
385 385 void QPieSeries::setPieEndAngle(qreal angle)
386 386 {
387 387 if (angle >= 0 && angle <= 360 && angle != m_pieEndAngle && angle >= m_pieStartAngle) {
388 388 m_pieEndAngle = angle;
389 389 updateDerivativeData();
390 390 }
391 391 }
392 392
393 393 /*!
394 394 Returns the end angle of the pie.
395 395
396 396 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
397 397
398 398 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
399 399 */
400 400 qreal QPieSeries::pieEndAngle() const
401 401 {
402 402 return m_pieEndAngle;
403 403 }
404 404
405 405 /*!
406 406 Sets the all the slice labels \a visible or invisible.
407 407
408 408 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
409 409 */
410 410 void QPieSeries::setLabelsVisible(bool visible)
411 411 {
412 412 foreach (QPieSlice* s, m_slices)
413 413 s->setLabelVisible(visible);
414 414 }
415 415
416 416 /*!
417 417 Returns the sum of all slice values in this series.
418 418
419 419 \sa QPieSlice::value(), QPieSlice::setValue()
420 420 */
421 421 qreal QPieSeries::total() const
422 422 {
423 423 return m_total;
424 424 }
425 425
426 426 /*!
427 427 \fn void QPieSeries::changed()
428 428
429 429 This signal emitted when something has changed in the series.
430 430
431 431 \sa QPieSeries::ChangeSet, QPieSlice::changed()
432 432 */
433 433
434 434 /*!
435 435 \fn void QPieSeries::clicked(QPieSlice* slice)
436 436
437 437 This signal is emitted when a \a slice has been clicked.
438 438
439 439 \sa QPieSlice::clicked()
440 440 */
441 441
442 442 /*!
443 443 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
444 444
445 445 This signal is emitted when user has hovered over a \a slice.
446 446
447 447 \sa QPieSlice::hoverEnter()
448 448 */
449 449
450 450 /*!
451 451 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
452 452
453 453 This signal is emitted when user has hovered away from a \a slice.
454 454
455 455 \sa QPieSlice::hoverLeave()
456 456 */
457 457
458 458 void QPieSeries::sliceChanged()
459 459 {
460 460 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
461 461 Q_ASSERT(m_slices.contains(slice));
462 462 updateDerivativeData();
463 463 }
464 464
465 465 void QPieSeries::sliceClicked()
466 466 {
467 467 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
468 468 Q_ASSERT(m_slices.contains(slice));
469 469 emit clicked(slice);
470 470 }
471 471
472 472 void QPieSeries::sliceHoverEnter()
473 473 {
474 474 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
475 475 Q_ASSERT(m_slices.contains(slice));
476 476 emit hoverEnter(slice);
477 477 }
478 478
479 479 void QPieSeries::sliceHoverLeave()
480 480 {
481 481 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
482 482 Q_ASSERT(m_slices.contains(slice));
483 483 emit hoverLeave(slice);
484 484 }
485 485
486 486 void QPieSeries::updateDerivativeData()
487 487 {
488 488 m_total = 0;
489 489
490 490 // nothing to do?
491 491 if (m_slices.count() == 0)
492 492 return;
493 493
494 494 // calculate total
495 495 foreach (QPieSlice* s, m_slices)
496 496 m_total += s->value();
497 497
498 498 // we must have some values
499 499 if (m_total == 0) {
500 500 qDebug() << "QPieSeries::updateDerivativeData() total == 0";
501 501 Q_ASSERT(m_total > 0); // TODO: is this the correct way to handle this?
502 502 }
503 503
504 504 // update slice attributes
505 505 qreal sliceAngle = m_pieStartAngle;
506 506 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
507 507 foreach (QPieSlice* s, m_slices) {
508 508
509 509 bool changed = false;
510 510
511 511 qreal percentage = s->value() / m_total;
512 512 if (s->m_percentage != percentage) {
513 513 s->m_percentage = percentage;
514 514 changed = true;
515 515 }
516 516
517 517 qreal sliceSpan = pieSpan * percentage;
518 518 if (s->m_angleSpan != sliceSpan) {
519 519 s->m_angleSpan = sliceSpan;
520 520 changed = true;
521 521 }
522 522
523 523 if (s->m_startAngle != sliceAngle) {
524 524 s->m_startAngle = sliceAngle;
525 525 changed = true;
526 526 }
527 527 sliceAngle += sliceSpan;
528 528
529 529 if (changed)
530 530 emit s->changed();
531 531 }
532 532 }
533 533
534 bool QPieSeries::setModel(QAbstractItemModel* model)
535 {
536 // disconnect signals from old model
537 if(m_model)
538 {
539 disconnect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0, 0);
540 disconnect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), 0, 0);
541 disconnect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), 0, 0);
542 }
543
544 // set new model if not NULL and connect necessary signals from it
545 if(model)
546 {
547 m_model = model;
548 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
549 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
550 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
551 }
552 }
553
554 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
555 {
556 m_mapValues = modelValuesLine;
557 m_mapLabels = modelLabelsLine;
558 m_mapOrientation = orientation;
559
560 if (m_model == NULL)
561 return;
562
563 if (m_mapOrientation == Qt::Vertical)
564 for (int i = 0; i < m_model->rowCount(); i++)
565 add(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
566 else
567 for (int i = 0; i < m_model->columnCount(); i++)
568 add(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
569
570
571 }
572
573 void QPieSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
574 {
575 if (m_mapOrientation == Qt::Vertical)
576 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
577 if (topLeft.column() == m_mapValues)
578 slices().at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
579 else if (topLeft.column() == m_mapLabels)
580 slices().at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
581 else
582 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
583 if (topLeft.column() == m_mapValues)
584 slices().at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
585 else if (topLeft.column() == m_mapLabels)
586 slices().at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
587 }
588
589 void QPieSeries::modelDataAdded(QModelIndex parent, int start, int end)
590 {
591 //
592 }
593
594 void QPieSeries::modelDataRemoved(QModelIndex parent, int start, int end)
595 {
596 remove(slices().at(start));
597 }
598
534 599 #include "moc_qpieseries.cpp"
535 600
536 601 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,129 +1,143
1 1 #ifndef PIESERIES_H
2 2 #define PIESERIES_H
3 3
4 4 #include "qseries.h"
5 5 #include <QObject>
6 6 #include <QRectF>
7 7 #include <QColor>
8 8 #include <QPen>
9 9 #include <QBrush>
10 10 #include <QSignalMapper>
11 11
12 12 class QGraphicsObject;
13 13 QTCOMMERCIALCHART_BEGIN_NAMESPACE
14 14 class PieChartItem;
15 15 class PieSlice;
16 16 class QPieSlice;
17 17
18 18 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QSeries
19 19 {
20 20 Q_OBJECT
21 21
22 22 public:
23 23
24 24 class ChangeSet
25 25 {
26 26 public:
27 27
28 28 // TODO: these should not really be exposed to the public API
29 29 void appendAdded(QPieSlice* slice);
30 30 void appendAdded(QList<QPieSlice*> slices);
31 31 void appendChanged(QPieSlice* slice);
32 32 void appendRemoved(QPieSlice* slice);
33 33
34 34 QList<QPieSlice*> added() const;
35 35 QList<QPieSlice*> changed() const;
36 36 QList<QPieSlice*> removed() const;
37 37
38 38 bool isEmpty() const;
39 39
40 40 private:
41 41 QList<QPieSlice*> m_added;
42 42 QList<QPieSlice*> m_changed;
43 43 QList<QPieSlice*> m_removed;
44 44 };
45 45
46 46 public:
47 47 QPieSeries(QObject *parent = 0);
48 48 virtual ~QPieSeries();
49 49
50 50 public: // from QChartSeries
51 51 QSeriesType type() const;
52 52
53 53 public:
54 54
55 55 // slice setters
56 56 void add(QPieSlice* slice);
57 57 void add(QList<QPieSlice*> slices);
58 58 void replace(QList<QPieSlice*> slices);
59 59 void remove(QPieSlice* slice);
60 60 void clear();
61 61
62 62 // sluce getters
63 63 QList<QPieSlice*> slices() const;
64 64
65 65 // calculated data
66 66 int count() const;
67 67 qreal total() const;
68 68
69 69 // pie customization
70 70 void setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition);
71 71 qreal pieHorizontalPosition() const;
72 72 qreal pieVerticalPosition() const;
73 73 void setPieSize(qreal relativeSize);
74 74 qreal pieSize() const;
75 75 void setPieStartAngle(qreal startAngle);
76 76 qreal pieStartAngle() const;
77 77 void setPieEndAngle(qreal endAngle);
78 78 qreal pieEndAngle() const;
79 79
80 80 // convenience function
81 81 QPieSeries& operator << (QPieSlice* slice);
82 82 QPieSlice* add(qreal value, QString name);
83 83 void setLabelsVisible(bool visible = true);
84 84
85 // data from model
86 bool setModel(QAbstractItemModel* model);
87 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
88
85 89 // TODO: find slices?
86 90 // QList<QPieSlice*> findByValue(qreal value);
87 91 // ...
88 92
89 93 // TODO: sorting slices?
90 94 // void sort(QPieSeries::SortByValue|label|??)
91 95
92 96 // TODO: general graphics customization
93 97 // setDrawStyle(2d|3d)
94 98 // setDropShadows
95 99
96 100 Q_SIGNALS:
97 101 void clicked(QPieSlice* slice);
98 102 void hoverEnter(QPieSlice* slice);
99 103 void hoverLeave(QPieSlice* slice);
100 104 void changed(); // TODO: hide this in PIMPL
101 105
102 106 private Q_SLOTS: // TODO: should be private and not visible in the interface at all
103 107 void sliceChanged();
104 108 void sliceClicked();
105 109 void sliceHoverEnter();
106 110 void sliceHoverLeave();
107 111
112 // slots for updating pie when data in model changes
113 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
114 void modelDataAdded(QModelIndex parent, int start, int end);
115 void modelDataRemoved(QModelIndex parent, int start, int end);
116
108 117 private:
109 118 void updateDerivativeData();
110 119
111 120 private:
112 121 Q_DISABLE_COPY(QPieSeries)
113 122
114 123 // TODO: use PIML
115 124 friend class PieChartItem;
116 125 friend class PieSlice;
117 126
118 127 QList<QPieSlice*> m_slices;
119 128 qreal m_pieRelativeHorPos;
120 129 qreal m_pieRelativeVerPos;
121 130 qreal m_pieRelativeSize;
122 131 qreal m_pieStartAngle;
123 132 qreal m_pieEndAngle;
124 133 qreal m_total;
134
135 // model map
136 int m_mapValues;
137 int m_mapLabels;
138 Qt::Orientation m_mapOrientation;
125 139 };
126 140
127 141 QTCOMMERCIALCHART_END_NAMESPACE
128 142
129 143 #endif // PIESERIES_H
@@ -1,53 +1,56
1 1 #ifndef QSERIES_H
2 2 #define QSERIES_H
3 3
4 4 #include "qchartglobal.h"
5 5 #include <QObject>
6 6 #include <QAbstractItemModel>
7 7 #include <QPen>
8 8
9 9 QTCOMMERCIALCHART_BEGIN_NAMESPACE
10 10
11 11 class QTCOMMERCIALCHART_EXPORT QSeries : public QObject
12 12 {
13 13 Q_OBJECT
14 14 public:
15 15 enum QSeriesType {
16 16 SeriesTypeLine,
17 17 SeriesTypeArea,
18 18 SeriesTypeBar,
19 19 SeriesTypeStackedBar,
20 20 SeriesTypePercentBar,
21 21 SeriesTypePie,
22 22 SeriesTypeScatter,
23 23 SeriesTypeSpline
24 24 };
25 25
26 26 // Helper class to contain legend and color for it
27 27 // TODO: This is actually quite close to current LegendMarker.. combine them?
28 28 /* class LegendEntry {
29 29 public:
30 30 QString mName;
31 31 /QBrush mBrush;
32 32 };*/
33 33
34 34 protected:
35 QSeries(QObject *parent = 0) : QObject(parent) {}
35 QSeries(QObject *parent = 0) : QObject(parent) {m_model = NULL;}
36 36
37 37 public:
38 38 virtual ~QSeries() {}
39 39 virtual QSeriesType type() const = 0;
40 40 QString name() { return QString("TODO: Name QSeries"); }
41 41 // TODO
42 42 virtual bool setModel(QAbstractItemModel* /*model*/) { return false; }
43 43
44 44 void setTitle(QString title) { m_title = title; }
45 45 QString title() { return m_title; }
46 46
47 protected:
48 QAbstractItemModel* m_model;
49
47 50 private:
48 51 QString m_title;
49 52 };
50 53
51 54 QTCOMMERCIALCHART_END_NAMESPACE
52 55
53 56 #endif
@@ -1,308 +1,310
1 1 #include "qxyseries.h"
2 2
3 3 QTCOMMERCIALCHART_BEGIN_NAMESPACE
4 4
5 5 /*!
6 6 \class QXYSeries
7 7 \brief The QXYSeries class is a base class for line, spline and scatter series.
8 8 */
9 9
10 10 /*!
11 11 \fn QPen QXYSeries::pen() const
12 12 \brief Returns pen used to draw points for series.
13 13 \sa setPen()
14 14 */
15 15
16 16 /*!
17 17 \fn QBrush QXYSeries::brush() const
18 18 \brief Returns brush used to draw points for series.
19 19 \sa setBrush()
20 20 */
21 21
22 22 /*!
23 23 \fn void QXYSeries::clicked(const QPointF& point)
24 24 \brief Signal is emitted when user clicks the \a point on chart.
25 25 */
26 26
27 27 /*!
28 28 \fn void QXYSeries::pointReplaced(int index)
29 29 \brief \internal \a index
30 30 */
31 31
32 32 /*!
33 33 \fn void QXYSeries::pointAdded(int index)
34 34 \brief \internal \a index
35 35 */
36 36
37 37 /*!
38 38 \fn void QXYSeries::pointRemoved(int index)
39 39 \brief \internal \a index
40 40 */
41 41
42 42 /*!
43 43 \fn void QXYSeries::updated()
44 44 \brief \internal
45 45 */
46 46
47 47 /*!
48 48 Constructs empty series object which is a child of \a parent.
49 49 When series object is added to QChartView or QChart instance ownerships is transfered.
50 50 */
51 51 QXYSeries::QXYSeries(QObject* parent):QSeries(parent)
52 52 {
53 m_model = NULL;
54 53 m_mapX = -1;
55 54 m_mapY = -1;
56 55 m_mapOrientation = Qt::Vertical;
57 56 // m_mapYOrientation = Qt::Vertical;
58 57 }
59 58 /*!
60 59 Destroys the object. Series added to QChartView or QChart instances are owned by those,
61 60 and are deleted when mentioned object are destroyed.
62 61 */
63 62 QXYSeries::~QXYSeries()
64 63 {
65 64 }
66 65
67 66 /*!
68 67 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
69 68 */
70 69 void QXYSeries::add(qreal x,qreal y)
71 70 {
72 71 Q_ASSERT(m_x.size() == m_y.size());
73 72 m_x<<x;
74 73 m_y<<y;
75 74 emit pointAdded(m_x.size()-1);
76 75 }
77 76
78 77 /*!
79 78 This is an overloaded function.
80 79 Adds data \a point to the series. Points are connected with lines on the chart.
81 80 */
82 81 void QXYSeries::add(const QPointF& point)
83 82 {
84 83 add(point.x(),point.y());
85 84 }
86 85
87 86 /*!
88 87 This is an overloaded function.
89 88 Adds list of data \a points to the series. Points are connected with lines on the chart.
90 89 */
91 90 void QXYSeries::add(const QList<QPointF> points)
92 91 {
93 92 foreach(const QPointF& point , points) {
94 93 add(point.x(),point.y());
95 94 }
96 95 }
97 96
98 97 /*!
99 98 Modifies \a y value for given \a x a value.
100 99 */
101 100 void QXYSeries::replace(qreal x,qreal y)
102 101 {
103 102 int index = m_x.indexOf(x);
104 103 m_x[index]=x;
105 104 m_y[index]=y;
106 105 emit pointReplaced(index);
107 106 }
108 107
109 108 /*!
110 109 This is an overloaded function.
111 110 Replaces current y value of for given \a point x value with \a point y value.
112 111 */
113 112 void QXYSeries::replace(const QPointF& point)
114 113 {
115 114 replace(point.x(),point.y());
116 115 }
117 116
118 117 /*!
119 118 Removes current \a x and \a y value.
120 119 */
121 120 void QXYSeries::remove(qreal x,qreal y)
122 121 {
123 122 int index =-1;
124 123 do{
125 124 index = m_x.indexOf(x,index+1);
126 125 }while(index !=-1 && m_y.at(index)!=y);
127 126
128 127 if(index==-1) return;
129 128
130 129 m_x.remove(index);
131 130 m_y.remove(index);
132 131 emit pointRemoved(index);
133 132 }
134 133
135 134 /*!
136 135 Removes current \a point x value. Note \a point y value is ignored.
137 136 */
138 137 void QXYSeries::remove(const QPointF& point)
139 138 {
140 139 remove(point.x(),point.y());
141 140 }
142 141
143 142 /*!
144 143 Removes all data points from the series.
145 144 */
146 145 void QXYSeries::removeAll()
147 146 {
148 147 m_x.clear();
149 148 m_y.clear();
150 149 }
151 150
152 151 /*!
153 152 \internal \a pos
154 153 */
155 154 qreal QXYSeries::x(int pos) const
156 155 {
157 156 if (m_model)
158 157 if (m_mapOrientation == Qt::Vertical)
159 158 // consecutive data is read from model's column
160 159 return m_model->data(m_model->index(pos, m_mapX), Qt::DisplayRole).toDouble();
161 160 else
162 161 // consecutive data is read from model's row
163 162 return m_model->data(m_model->index(m_mapX, pos), Qt::DisplayRole).toDouble();
164 163 else
165 164 // model is not specified, return the data from series' internal data store
166 165 return m_x.at(pos);
167 166 }
168 167
169 168 /*!
170 169 \internal \a pos
171 170 */
172 171 qreal QXYSeries::y(int pos) const
173 172 {
174 173 if (m_model)
175 174 if (m_mapOrientation == Qt::Vertical)
176 175 // consecutive data is read from model's column
177 176 return m_model->data(m_model->index(pos, m_mapY), Qt::DisplayRole).toDouble();
178 177 else
179 178 // consecutive data is read from model's row
180 179 return m_model->data(m_model->index(m_mapY, pos), Qt::DisplayRole).toDouble();
181 180 else
182 181 // model is not specified, return the data from series' internal data store
183 182 return m_y.at(pos);
184 183 }
185 184
186 185 /*!
187 186 Returns number of data points within series.
188 187 */
189 188 int QXYSeries::count() const
190 189 {
191 190 Q_ASSERT(m_x.size() == m_y.size());
192 191
193 192 if (m_model)
194 193 if (m_mapOrientation == Qt::Vertical)
195 194 // data is in a column, so return the number of items in single column
196 195 return m_model->rowCount();
197 196 else
198 197 // data is in a row, so return the number of items in single row
199 198 m_model->columnCount();
200 199 else
201 200 // model is not specified, return the number of points in the series internal data store
202 201 return m_x.size();
203 202 }
204 203
205 204 /*!
206 205 Returns the data points of the series.
207 206 */
208 207 QList<QPointF> QXYSeries::data()
209 208 {
210 209 QList<QPointF> data;
211 210 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
212 211 data.append(QPointF(m_x.at(i), m_y.at(i)));
213 212 return data;
214 213 }
215 214
216 215
217 216 /*!
218 217 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
219 218 pen from chart theme is used.
220 219 \sa QChart::setChartTheme()
221 220 */
222 221 void QXYSeries::setPen(const QPen& pen)
223 222 {
224 223 if(pen!=m_pen){
225 224 m_pen=pen;
226 225 emit updated();
227 226 }
228 227 }
229 228
230 229 /*!
231 230 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
232 231 from chart theme setting is used.
233 232 \sa QChart::setChartTheme()
234 233 */
235 234
236 235 void QXYSeries::setBrush(const QBrush& brush)
237 236 {
238 237 if(brush!=m_brush){
239 238 m_brush=brush;
240 239 emit updated();
241 240 }
242 241 }
243 242
244 243
245 244 /*!
246 245 Stream operator for adding a data \a point to the series.
247 246 \sa add()
248 247 */
249 248
250 249 QXYSeries& QXYSeries::operator<< (const QPointF &point)
251 250 {
252 251 add(point);
253 252 return *this;
254 253 }
255 254
256 255
257 256 /*!
258 257 Stream operator for adding a list of \a points to the series.
259 258 \sa add()
260 259 */
261 260
262 261 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
263 262 {
264 263 add(points);
265 264 return *this;
266 265 }
267 266
268 267
269 268 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
270 269 {
271 emit pointReplaced(topLeft.row());
270 if (m_mapOrientation == Qt::Vertical)
271 emit pointReplaced(topLeft.row());
272 else
273 emit pointReplaced(topLeft.column());
272 274 }
273 275
274 276 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
275 277 {
276 278 emit pointAdded(start);
277 279 }
278 280
279 281 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
280 282 {
281 283 emit pointRemoved(start);
282 284 }
283 285
284 286 bool QXYSeries::setModel(QAbstractItemModel* model) {
285 287 m_model = model;
286 288 // for (int i = 0; i < m_model->rowCount(); i++)
287 289 // emit pointAdded(i);
288 290 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
289 291 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
290 292 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
291 293 }
292 294
293 295 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
294 296 {
295 297 m_mapX = modelX;
296 298 m_mapY = modelY;
297 299 m_mapOrientation = orientation;
298 300 }
299 301
300 302 //void QXYSeries::setModelMappingY(int modelLineIndex, Qt::Orientation orientation)
301 303 //{
302 304 // m_mapY = modelLineIndex;
303 305 // m_mapYOrientation = orientation;
304 306 //}
305 307
306 308 #include "moc_qxyseries.cpp"
307 309
308 310 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,76 +1,76
1 1 #ifndef QXYSERIES_H_
2 2 #define QXYSERIES_H_
3 3
4 4 #include "qchartglobal.h"
5 5 #include "qseries.h"
6 6 #include <QDebug>
7 7 #include <QPen>
8 8 #include <QBrush>
9 9
10 10 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 11
12 12 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
13 13 {
14 14 Q_OBJECT
15 15 protected:
16 16 QXYSeries(QObject* parent=0);
17 17 virtual ~QXYSeries();
18 18
19 19 public:
20 20 void add(qreal x, qreal y);
21 21 void add(const QPointF& point);
22 22 void add(const QList<QPointF> points);
23 23 void replace(qreal x,qreal y);
24 24 void replace(const QPointF& point);
25 25 void remove(qreal x, qreal y);
26 26 void remove(const QPointF& point);
27 27 void removeAll();
28 28
29 29 int count() const;
30 30 qreal x(int pos) const;
31 31 qreal y(int pos) const;
32 32 QList<QPointF> data();
33 33
34 34 QXYSeries& operator << (const QPointF &point);
35 35 QXYSeries& operator << (const QList<QPointF> points);
36 36
37 37 void setPen(const QPen& pen);
38 38 QPen pen() const {return m_pen;}
39 39 void setBrush(const QBrush& pen);
40 40 QBrush brush() const {return m_brush;}
41 41
42 42 bool setModel(QAbstractItemModel* model);
43 43 QAbstractItemModel* model() {return m_model;}
44 44
45 45 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
46 46 // void setModelMappingY(int modelLineIndex, Qt::Orientation orientation = Qt::Vertical);
47 47
48 48 private slots:
49 49 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
50 50 void modelDataAdded(QModelIndex parent, int start, int end);
51 51 void modelDataRemoved(QModelIndex parent, int start, int end);
52 52
53 53 signals:
54 54 void clicked(const QPointF& point);
55 55 void updated();
56 56 void pointReplaced(int index);
57 57 void pointRemoved(int index);
58 58 void pointAdded(int index);
59 59
60 60 protected:
61 61 QVector<qreal> m_x;
62 62 QVector<qreal> m_y;
63 63
64 64 QPen m_pen;
65 65 QBrush m_brush;
66 66
67 QAbstractItemModel* m_model;
67 // QAbstractItemModel* m_model;
68 68 int m_mapX;
69 69 Qt::Orientation m_mapOrientation;
70 70 int m_mapY;
71 71 // Qt::Orientation m_mapYOrientation;
72 72 };
73 73
74 74 QTCOMMERCIALCHART_END_NAMESPACE
75 75
76 76 #endif
General Comments 0
You need to be logged in to leave comments. Login now