##// END OF EJS Templates
PieSeries: model now supports custom mapping.
Marek Rosa -
r1056:65526593187b
parent child
Show More
1 NO CONTENT: modified file
NO CONTENT: modified file
@@ -1,486 +1,666
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qbarseries.h"
21 #include "qbarseries.h"
22 #include "qbarseries_p.h"
22 #include "qbarseries_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "domain_p.h"
25 #include "domain_p.h"
26 #include "legendmarker_p.h"
26 #include "legendmarker_p.h"
27 #include "chartdataset_p.h"
27 #include "chartdataset_p.h"
28 #include "charttheme_p.h"
28 #include "charttheme_p.h"
29 #include "chartanimator_p.h"
29 #include "chartanimator_p.h"
30
30
31 #include <QAbstractItemModel>
31 #include <QAbstractItemModel>
32 #include <QModelIndex>
32 #include <QModelIndex>
33
33
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
34 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35
35
36 /*!
36 /*!
37 \class QBarSeries
37 \class QBarSeries
38 \brief part of QtCommercial chart API.
38 \brief part of QtCommercial chart API.
39 \mainclass
39 \mainclass
40
40
41 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple
41 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multiple
42 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
42 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
43 by QStringList.
43 by QStringList.
44
44
45 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
45 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
46 \image examples_barchart.png
46 \image examples_barchart.png
47
47
48 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
48 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
49 */
49 */
50
50
51 /*!
51 /*!
52 \fn void QBarSeries::clicked(QBarSet *barset, QString category)
52 \fn void QBarSeries::clicked(QBarSet *barset, QString category)
53
53
54 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category
54 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset of category \a category
55 contained by the series.
55 contained by the series.
56 */
56 */
57
57
58 /*!
58 /*!
59 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
59 \fn void QBarSeries::hovered(QBarSet* barset, bool status)
60
60
61 The signal is emitted if mouse is hovered on top of series.
61 The signal is emitted if mouse is hovered on top of series.
62 Parameter \a barset is the pointer of barset, where hover happened.
62 Parameter \a barset is the pointer of barset, where hover happened.
63 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
63 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
64 */
64 */
65
65
66 /*!
66 /*!
67 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
67 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
68 QBarSeries is QObject which is a child of a \a parent.
68 QBarSeries is QObject which is a child of a \a parent.
69 */
69 */
70 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) :
70 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) :
71 QAbstractSeries(*new QBarSeriesPrivate(categories, this),parent)
71 QAbstractSeries(*new QBarSeriesPrivate(categories, this),parent)
72 {
72 {
73 }
73 }
74
74
75 /*!
75 /*!
76 Destructs barseries and owned barsets.
76 Destructs barseries and owned barsets.
77 */
77 */
78 QBarSeries::~QBarSeries()
78 QBarSeries::~QBarSeries()
79 {
79 {
80 // NOTE: d_ptr destroyed by QObject
80 // NOTE: d_ptr destroyed by QObject
81 }
81 }
82
82
83 /*!
83 /*!
84 \internal
84 \internal
85 */
85 */
86 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
86 QBarSeries::QBarSeries(QBarSeriesPrivate &d, QObject *parent) :
87 QAbstractSeries(d,parent)
87 QAbstractSeries(d,parent)
88 {
88 {
89 }
89 }
90
90
91 /*!
91 /*!
92 Returns the type of series. Derived classes override this.
92 Returns the type of series. Derived classes override this.
93 */
93 */
94 QAbstractSeries::QSeriesType QBarSeries::type() const
94 QAbstractSeries::QSeriesType QBarSeries::type() const
95 {
95 {
96 return QAbstractSeries::SeriesTypeBar;
96 return QAbstractSeries::SeriesTypeBar;
97 }
97 }
98
98
99 /*!
99 /*!
100 Adds a set of bars to series. Takes ownership of \a set.
100 Adds a set of bars to series. Takes ownership of \a set.
101 */
101 */
102 void QBarSeries::appendBarSet(QBarSet *set)
102 void QBarSeries::appendBarSet(QBarSet *set)
103 {
103 {
104 Q_D(QBarSeries);
104 Q_D(QBarSeries);
105 d->m_barSets.append(set);
105 d->m_barSets.append(set);
106 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
106 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), d, SLOT(barsetChanged()));
107 emit d->restructuredBars();
107 emit d->restructuredBars();
108 }
108 }
109
109
110 /*!
110 /*!
111 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
111 Removes a set of bars from series. Releases ownership of \a set. Doesn't delete \a set.
112 */
112 */
113 void QBarSeries::removeBarSet(QBarSet *set)
113 void QBarSeries::removeBarSet(QBarSet *set)
114 {
114 {
115 Q_D(QBarSeries);
115 Q_D(QBarSeries);
116 if (d->m_barSets.contains(set)) {
116 if (d->m_barSets.contains(set)) {
117 d->m_barSets.removeOne(set);
117 d->m_barSets.removeOne(set);
118 QObject::disconnect(set, SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
118 QObject::disconnect(set, SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
119 emit d->restructuredBars();
119 emit d->restructuredBars();
120 }
120 }
121 }
121 }
122
122
123 /*!
123 /*!
124 Adds a list of barsets to series. Takes ownership of \a sets.
124 Adds a list of barsets to series. Takes ownership of \a sets.
125 */
125 */
126 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
126 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
127 {
127 {
128 Q_D(QBarSeries);
128 Q_D(QBarSeries);
129 foreach (QBarSet* set, sets) {
129 foreach (QBarSet* set, sets) {
130 d->m_barSets.append(set);
130 d->m_barSets.append(set);
131 QObject::connect(set, SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
131 QObject::connect(set, SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
132 }
132 }
133 emit d->restructuredBars();
133 emit d->restructuredBars();
134 }
134 }
135
135
136 /*!
136 /*!
137 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
137 Removes a list of barsets from series. Releases ownership of \a sets. Doesn't delete \a sets.
138 */
138 */
139 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
139 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
140 {
140 {
141 Q_D(QBarSeries);
141 Q_D(QBarSeries);
142
142
143 foreach (QBarSet* set, sets) {
143 foreach (QBarSet* set, sets) {
144 if (d->m_barSets.contains(set)) {
144 if (d->m_barSets.contains(set)) {
145 d->m_barSets.removeOne(set);
145 d->m_barSets.removeOne(set);
146 QObject::disconnect(set, SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
146 QObject::disconnect(set, SIGNAL(updatedBars()), this, SLOT(barsetChanged()));
147 }
147 }
148 }
148 }
149 emit d->restructuredBars();
149 emit d->restructuredBars();
150 }
150 }
151
151
152 /*!
152 /*!
153 Returns number of sets in series.
153 Returns number of sets in series.
154 */
154 */
155 int QBarSeries::barsetCount() const
155 int QBarSeries::barsetCount() const
156 {
156 {
157 Q_D(const QBarSeries);
157 Q_D(const QBarSeries);
158 return d->m_barSets.count();
158 return d->m_barSets.count();
159 }
159 }
160
160
161 /*!
161 /*!
162 Returns number of categories in series
162 Returns number of categories in series
163 */
163 */
164 int QBarSeries::categoryCount() const
164 int QBarSeries::categoryCount() const
165 {
165 {
166 Q_D(const QBarSeries);
166 Q_D(const QBarSeries);
167 return d->m_categories.count();
167 return d->m_categories.count();
168 }
168 }
169
169
170 /*!
170 /*!
171 Returns a list of sets in series. Keeps ownership of sets.
171 Returns a list of sets in series. Keeps ownership of sets.
172 */
172 */
173 QList<QBarSet*> QBarSeries::barSets() const
173 QList<QBarSet*> QBarSeries::barSets() const
174 {
174 {
175 Q_D(const QBarSeries);
175 Q_D(const QBarSeries);
176 return d->m_barSets;
176 return d->m_barSets;
177 }
177 }
178
178
179 /*!
179 /*!
180 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
180 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
181 Sets the \a model to be used as a data source
181 Sets the \a model to be used as a data source
182 */
182 */
183 bool QBarSeries::setModel(QAbstractItemModel *model)
183 bool QBarSeries::setModel(QAbstractItemModel *model)
184 {
184 {
185 Q_D(QBarSeries);
185 Q_D(QBarSeries);
186 return d->setModel(model);
186 return d->setModel(model);
187 }
187 }
188
188
189 /*!
189 /*!
190 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
190 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
191 Sets column/row specified by \a categories to be used as a list of bar series categories.
191 Sets column/row specified by \a categories to be used as a list of bar series categories.
192 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
192 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
193 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
193 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
194 All the columns/rows inbetween those two values are also used as data for bar sets.
194 All the columns/rows inbetween those two values are also used as data for bar sets.
195 The \a orientation parameter specifies whether the data is in columns or in rows.
195 The \a orientation parameter specifies whether the data is in columns or in rows.
196 */
196 */
197 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation)
197 void QBarSeries::setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation)
198 {
198 {
199 Q_D(QBarSeries);
199 Q_D(QBarSeries);
200 d->setModelMapping(categories,bottomBoundary,topBoundary,orientation);
200 d->setModelMapping(categories,bottomBoundary,topBoundary,orientation);
201 }
201 }
202
202
203 void QBarSeries::setModelMappingRange(int first, int count)
204 {
205 Q_D(QBarSeries);
206 d->setModelMappingRange(first, count);
207 }
208
203 /*!
209 /*!
204 Returns the bar categories of the series.
210 Returns the bar categories of the series.
205 */
211 */
206 QBarCategories QBarSeries::categories() const
212 QBarCategories QBarSeries::categories() const
207 {
213 {
208 Q_D(const QBarSeries);
214 Q_D(const QBarSeries);
209 return d->m_categories;
215 return d->m_categories;
210 }
216 }
211
217
212 /*!
218 /*!
213 Sets the visibility of labels in series to \a visible
219 Sets the visibility of labels in series to \a visible
214 */
220 */
215 void QBarSeries::setLabelsVisible(bool visible)
221 void QBarSeries::setLabelsVisible(bool visible)
216 {
222 {
217 foreach (QBarSet* s, barSets()) {
223 foreach (QBarSet* s, barSets()) {
218 s->setLabelsVisible(visible);
224 s->setLabelsVisible(visible);
219 }
225 }
220 }
226 }
221
227
222 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
228 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
223
229
224 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) :
230 QBarSeriesPrivate::QBarSeriesPrivate(QBarCategories categories, QBarSeries *q) :
225 QAbstractSeriesPrivate(q),
231 QAbstractSeriesPrivate(q),
226 m_categories(categories),
232 m_categories(categories),
227 m_mapCategories(-1),
233 m_mapCategories(-1),
228 m_mapBarBottom(-1),
234 m_mapBarBottom(-1),
229 m_mapBarTop(-1)
235 m_mapBarTop(-1)
230 {
236 {
231 }
237 }
232
238
233 QBarSet* QBarSeriesPrivate::barsetAt(int index)
239 QBarSet* QBarSeriesPrivate::barsetAt(int index)
234 {
240 {
235 return m_barSets.at(index);
241 return m_barSets.at(index);
236 }
242 }
237
243
238 QString QBarSeriesPrivate::categoryName(int category)
244 QString QBarSeriesPrivate::categoryName(int category)
239 {
245 {
240 return m_categories.at(category);
246 return m_categories.at(category);
241 }
247 }
242
248
243 qreal QBarSeriesPrivate::min()
249 qreal QBarSeriesPrivate::min()
244 {
250 {
245 if (m_barSets.count() <= 0) {
251 if (m_barSets.count() <= 0) {
246 return 0;
252 return 0;
247 }
253 }
248 qreal min = INT_MAX;
254 qreal min = INT_MAX;
249
255
250 for (int i = 0; i < m_barSets.count(); i++) {
256 for (int i = 0; i < m_barSets.count(); i++) {
251 int categoryCount = m_barSets.at(i)->count();
257 int categoryCount = m_barSets.at(i)->count();
252 for (int j = 0; j < categoryCount; j++) {
258 for (int j = 0; j < categoryCount; j++) {
253 qreal temp = m_barSets.at(i)->at(j);
259 qreal temp = m_barSets.at(i)->at(j);
254 if (temp < min)
260 if (temp < min)
255 min = temp;
261 min = temp;
256 }
262 }
257 }
263 }
258 return min;
264 return min;
259 }
265 }
260
266
261 qreal QBarSeriesPrivate::max()
267 qreal QBarSeriesPrivate::max()
262 {
268 {
263 if (m_barSets.count() <= 0) {
269 if (m_barSets.count() <= 0) {
264 return 0;
270 return 0;
265 }
271 }
266 qreal max = INT_MIN;
272 qreal max = INT_MIN;
267
273
268 for (int i = 0; i < m_barSets.count(); i++) {
274 for (int i = 0; i < m_barSets.count(); i++) {
269 int categoryCount = m_barSets.at(i)->count();
275 int categoryCount = m_barSets.at(i)->count();
270 for (int j = 0; j < categoryCount; j++) {
276 for (int j = 0; j < categoryCount; j++) {
271 qreal temp = m_barSets.at(i)->at(j);
277 qreal temp = m_barSets.at(i)->at(j);
272 if (temp > max)
278 if (temp > max)
273 max = temp;
279 max = temp;
274 }
280 }
275 }
281 }
276
282
277 return max;
283 return max;
278 }
284 }
279
285
280 qreal QBarSeriesPrivate::valueAt(int set, int category)
286 qreal QBarSeriesPrivate::valueAt(int set, int category)
281 {
287 {
282 if ((set < 0) || (set >= m_barSets.count())) {
288 if ((set < 0) || (set >= m_barSets.count())) {
283 // No set, no value.
289 // No set, no value.
284 return 0;
290 return 0;
285 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
291 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
286 // No category, no value.
292 // No category, no value.
287 return 0;
293 return 0;
288 }
294 }
289
295
290 return m_barSets.at(set)->at(category);
296 return m_barSets.at(set)->at(category);
291 }
297 }
292
298
293 qreal QBarSeriesPrivate::percentageAt(int set, int category)
299 qreal QBarSeriesPrivate::percentageAt(int set, int category)
294 {
300 {
295 if ((set < 0) || (set >= m_barSets.count())) {
301 if ((set < 0) || (set >= m_barSets.count())) {
296 // No set, no value.
302 // No set, no value.
297 return 0;
303 return 0;
298 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
304 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
299 // No category, no value.
305 // No category, no value.
300 return 0;
306 return 0;
301 }
307 }
302
308
303 qreal value = m_barSets.at(set)->at(category);
309 qreal value = m_barSets.at(set)->at(category);
304 qreal sum = categorySum(category);
310 qreal sum = categorySum(category);
305 if ( qFuzzyIsNull(sum) ) {
311 if ( qFuzzyIsNull(sum) ) {
306 return 0;
312 return 0;
307 }
313 }
308
314
309 return value / sum;
315 return value / sum;
310 }
316 }
311
317
312 qreal QBarSeriesPrivate::categorySum(int category)
318 qreal QBarSeriesPrivate::categorySum(int category)
313 {
319 {
314 qreal sum(0);
320 qreal sum(0);
315 int count = m_barSets.count(); // Count sets
321 int count = m_barSets.count(); // Count sets
316 for (int set = 0; set < count; set++) {
322 for (int set = 0; set < count; set++) {
317 if (category < m_barSets.at(set)->count())
323 if (category < m_barSets.at(set)->count())
318 sum += m_barSets.at(set)->at(category);
324 sum += m_barSets.at(set)->at(category);
319 }
325 }
320 return sum;
326 return sum;
321 }
327 }
322
328
323 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
329 qreal QBarSeriesPrivate::absoluteCategorySum(int category)
324 {
330 {
325 qreal sum(0);
331 qreal sum(0);
326 int count = m_barSets.count(); // Count sets
332 int count = m_barSets.count(); // Count sets
327 for (int set = 0; set < count; set++) {
333 for (int set = 0; set < count; set++) {
328 if (category < m_barSets.at(set)->count())
334 if (category < m_barSets.at(set)->count())
329 sum += qAbs(m_barSets.at(set)->at(category));
335 sum += qAbs(m_barSets.at(set)->at(category));
330 }
336 }
331 return sum;
337 return sum;
332 }
338 }
333
339
334 qreal QBarSeriesPrivate::maxCategorySum()
340 qreal QBarSeriesPrivate::maxCategorySum()
335 {
341 {
336 qreal max = INT_MIN;
342 qreal max = INT_MIN;
337 int count = m_categories.count();
343 int count = m_categories.count();
338 for (int i = 0; i < count; i++) {
344 for (int i = 0; i < count; i++) {
339 qreal sum = categorySum(i);
345 qreal sum = categorySum(i);
340 if (sum > max)
346 if (sum > max)
341 max = sum;
347 max = sum;
342 }
348 }
343 return max;
349 return max;
344 }
350 }
345
351
346 bool QBarSeriesPrivate::setModel(QAbstractItemModel *model)
352 bool QBarSeriesPrivate::setModel(QAbstractItemModel *model)
347 {
353 {
348 // disconnect signals from old model
354 // disconnect signals from old model
349 if(m_model)
355 if(m_model)
350 {
356 {
351 disconnect(m_model, 0, this, 0);
357 disconnect(m_model, 0, this, 0);
352 m_mapCategories = -1;
358 m_mapCategories = -1;
353 m_mapBarBottom = -1;
359 m_mapBarBottom = -1;
354 m_mapBarTop = -1;
360 m_mapBarTop = -1;
355 m_mapOrientation = Qt::Vertical;
361 m_mapOrientation = Qt::Vertical;
356 }
362 }
357
363
358 // set new model
364 // set new model
359 if(model)
365 if(model)
360 {
366 {
361 m_model = model;
367 m_model = model;
362 return true;
368 return true;
363 }
369 }
364 else
370 else
365 {
371 {
366 m_model = 0;
372 m_model = 0;
367 return false;
373 return false;
368 }
374 }
369 }
375 }
370
376
371 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
377 void QBarSeriesPrivate::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
372 {
378 {
373 Q_Q(QBarSeries);
379 Q_Q(QBarSeries);
374
380
375 if (m_model == 0)
381 if (m_model == 0)
376 return;
382 return;
377
383
378 m_mapCategories = categories;
384 m_mapCategories = categories;
379 m_mapBarBottom = bottomBoundry;
385 m_mapBarBottom = bottomBoundry;
380 m_mapBarTop = topBoundry;
386 m_mapBarTop = topBoundry;
381 m_mapOrientation = orientation;
387 m_mapOrientation = orientation;
382
388
383 // connect the signals
389 // connect the signals
384 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
390 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
385 this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
391 if (m_mapOrientation == Qt::Vertical) {
392 connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
393 connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
394 } else {
395 connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
396 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
397 }
386
398
387 // create the initial bars
399 // create the initial bars
388 m_categories.clear();
400 m_categories.clear();
389 if (m_mapOrientation == Qt::Vertical) {
401 if (m_mapOrientation == Qt::Vertical) {
390 for (int k = 0; k < m_model->rowCount(); k++) {
402 int rowCount = 0;
403 if(m_mapCount == -1)
404 rowCount = m_model->rowCount() - m_mapFirst;
405 else
406 rowCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst);
407 for (int k = m_mapFirst; k < m_mapFirst + rowCount; k++) {
391 m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
408 m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
392 }
409 }
393
410
394 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
411 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
395 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
412 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
396 for(int m = 0; m < m_model->rowCount(); m++)
413 for(int m = m_mapFirst; m < m_mapFirst + rowCount; m++)
397 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
414 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
398 q->appendBarSet(barSet);
415 q->appendBarSet(barSet);
399 }
416 }
400 } else {
417 } else {
401 for (int k = 0; k < m_model->columnCount(); k++) {
418 int columnCount = 0;
419 if(m_mapCount == -1)
420 columnCount = m_model->columnCount() - m_mapFirst;
421 else
422 columnCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst);
423 for (int k = m_mapFirst; k < m_mapFirst + columnCount; k++) {
402 m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
424 m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
403 }
425 }
404
426
405 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
427 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
406 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString());
428 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString());
407 for(int m = 0; m < m_model->columnCount(); m++)
429 for(int m = m_mapFirst; m < m_mapFirst + columnCount; m++)
408 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
430 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
409 q->appendBarSet(barSet);
431 q->appendBarSet(barSet);
410 }
432 }
411 }
433 }
412 }
434 }
413
435
414 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
436 void QBarSeriesPrivate::setModelMappingRange(int first, int count)
415 {
437 {
416 Q_UNUSED(bottomRight)
438 m_mapFirst = first;
439 m_mapCount = count;
440 }
417
441
442 void QBarSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
443 {
444 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
445 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
418 if (m_mapOrientation == Qt::Vertical)
446 if (m_mapOrientation == Qt::Vertical)
419 {
447 {
420 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
448 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
421 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop)
449 if ( row >= m_mapFirst && (m_mapCount == - 1 || row < m_mapFirst + m_mapCount)) {
422 barsetAt(topLeft.column() - m_mapBarBottom)->replace(topLeft.row(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
450 if (column >= m_mapBarBottom && column <= m_mapBarTop)
451 barsetAt(column - m_mapBarBottom)->replace(row - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
452 // if (column == m_mapCategories);// TODO:
453 }
423 }
454 }
424 else
455 else
425 {
456 {
426 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
457 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
427 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop)
458 if (column >= m_mapFirst && (m_mapCount == - 1 || column < m_mapFirst + m_mapCount)) {
428 barsetAt(topLeft.row() - m_mapBarBottom)->replace(topLeft.column(), m_model->data(topLeft, Qt::DisplayRole).toDouble());
459 if (row >= m_mapBarBottom && row <= m_mapBarTop)
460 barsetAt(row - m_mapBarBottom)->replace(column - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
461 // if (row == m_mapCategories);// TODO:
462 }
463 }
464 }
465 }
466 }
467
468 void QBarSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
469 {
470 Q_UNUSED(parent);
471 Q_UNUSED(start);
472 Q_UNUSED(end);
473 initializeDataFromModel();
474 // // series uses model as a data sourceupda
475 // int addedCount = end - start + 1;
476 // if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
477 // return;
478 // } else {
479
480 // for (int bar = m_mapBarBottom; bar <= m_mapBarTop; bar++) {
481 // QBarSet *barSet = barsetAt(bar - m_mapBarBottom);
482 // // adding items to unlimited map
483 // if (m_mapCount == -1 && start >= m_mapFirst) {
484 // for (int i = start; i <= end; i++) {
485 // if (bar == m_mapBarBottom)
486 // insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString());
487 // barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble());
488 // }
489 // } else if (m_mapCount == - 1 && start < m_mapFirst) {
490 // // not all newly added items
491 // for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) {
492 // if (bar == m_mapBarBottom)
493 // insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString());
494 // barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble());
495 // }
496 // }
497
498 // // adding items to limited map
499 // else if (start >= m_mapFirst) {
500 // // remove the items that will no longer fit into the map
501 // // int toRemove = addedCount - (count - points().size());
502 // for (int i = start; i <= end; i++) {
503 // if (bar == m_mapBarBottom)
504 // insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString());
505 // barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble());
506 // }
507 // if (m_barSets.size() > m_mapCount)
508 // for (int i = m_barSets.size() - 1; i >= m_mapCount; i--) {
509 // if (bar == m_mapBarBottom)
510 // removeCategory(i);
511 // barSet->remove(i);
512 // }
513 // } else {
514 // //
515 // for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) {
516 // if (bar == m_mapBarBottom)
517 // insertCategory(i - m_mapFirst, m_model->data(m_model->index(i, m_mapCategories), Qt::DisplayRole).toString());
518 // barSet->insert(i - m_mapFirst, m_model->data(m_model->index(i, bar), Qt::DisplayRole).toDouble());
519 // }
520 // if (m_barSets.size() > m_mapCount)
521 // for (int i = m_barSets.size() - 1; i >= m_mapCount; i--) {
522 // if (bar == m_mapBarBottom)
523 // removeCategory(i);
524 // barSet->remove(i);
525 // }
526 // }
527 // }
528 // emit restructuredBars();
529 // emit barsetChanged();
530 // emit categoriesUpdated();
531 // }
532 }
533
534 void QBarSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
535 {
536 Q_UNUSED(parent);
537 Q_UNUSED(start);
538 Q_UNUSED(end);
539 initializeDataFromModel();
540 }
541
542 void QBarSeriesPrivate::initializeDataFromModel()
543 {
544 Q_Q(QBarSeries);
545
546 if (m_model == 0)
547 return;
548
549 // connect the signals
550 // connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
551 // if (m_mapOrientation == Qt::Vertical) {
552 // connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
553 // connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
554 // } else {
555 // connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
556 // connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
557 // }
558
559 // create the initial bars
560 m_categories.clear();
561 m_barSets.clear();
562 emit restructuredBars();
563 if (m_mapOrientation == Qt::Vertical) {
564 int rowCount = 0;
565 if(m_mapCount == -1)
566 rowCount = m_model->rowCount() - m_mapFirst;
567 else
568 rowCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst);
569 for (int k = m_mapFirst; k < m_mapFirst + rowCount; k++) {
570 m_categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
571 }
572
573 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
574 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString());
575 for(int m = m_mapFirst; m < m_mapFirst + rowCount; m++)
576 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
577 q->appendBarSet(barSet);
429 }
578 }
579 } else {
580 int columnCount = 0;
581 if(m_mapCount == -1)
582 columnCount = m_model->columnCount() - m_mapFirst;
583 else
584 columnCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst);
585 for (int k = m_mapFirst; k < m_mapFirst + columnCount; k++) {
586 m_categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
587 }
588
589 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
590 QBarSet* barSet = new QBarSet(m_model->headerData(i, Qt::Vertical, Qt::DisplayRole).toString());
591 for(int m = m_mapFirst; m < m_mapFirst + columnCount; m++)
592 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
593 q->appendBarSet(barSet);
594 }
595 }
596 emit restructuredBars();
597 emit updatedBars();
598 }
599
600 void QBarSeriesPrivate::insertCategory(int index, const QString category)
601 {
602 m_categories.insert(index, category);
603 emit categoriesUpdated();
604 }
605
606 void QBarSeriesPrivate::removeCategory(int index)
607 {
608 m_categories.removeAt(index);
609 emit categoriesUpdated();
430 }
610 }
431
611
432 void QBarSeriesPrivate::barsetChanged()
612 void QBarSeriesPrivate::barsetChanged()
433 {
613 {
434 emit updatedBars();
614 emit updatedBars();
435 }
615 }
436
616
437 void QBarSeriesPrivate::scaleDomain(Domain& domain)
617 void QBarSeriesPrivate::scaleDomain(Domain& domain)
438 {
618 {
439 qreal minX(domain.minX());
619 qreal minX(domain.minX());
440 qreal minY(domain.minY());
620 qreal minY(domain.minY());
441 qreal maxX(domain.maxX());
621 qreal maxX(domain.maxX());
442 qreal maxY(domain.maxY());
622 qreal maxY(domain.maxY());
443 int tickXCount(domain.tickXCount());
623 int tickXCount(domain.tickXCount());
444 int tickYCount(domain.tickYCount());
624 int tickYCount(domain.tickYCount());
445
625
446 qreal x = m_categories.count();
626 qreal x = m_categories.count();
447 qreal y = max();
627 qreal y = max();
448 minX = qMin(minX, x);
628 minX = qMin(minX, x);
449 minY = qMin(minY, y);
629 minY = qMin(minY, y);
450 maxX = qMax(maxX, x);
630 maxX = qMax(maxX, x);
451 maxY = qMax(maxY, y);
631 maxY = qMax(maxY, y);
452 tickXCount = x+1;
632 tickXCount = x+1;
453
633
454 domain.setRangeX(minX,maxX,tickXCount);
634 domain.setRangeX(minX,maxX,tickXCount);
455 domain.setRangeY(minY,maxY,tickYCount);
635 domain.setRangeY(minY,maxY,tickYCount);
456 }
636 }
457
637
458 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
638 Chart* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
459 {
639 {
460 Q_Q(QBarSeries);
640 Q_Q(QBarSeries);
461
641
462 BarChartItem* bar = new BarChartItem(q,presenter);
642 BarChartItem* bar = new BarChartItem(q,presenter);
463 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
643 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
464 presenter->animator()->addAnimation(bar);
644 presenter->animator()->addAnimation(bar);
465 }
645 }
466 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
646 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
467 return bar;
647 return bar;
468
648
469 }
649 }
470
650
471 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
651 QList<LegendMarker*> QBarSeriesPrivate::createLegendMarker(QLegend* legend)
472 {
652 {
473 Q_Q(QBarSeries);
653 Q_Q(QBarSeries);
474 QList<LegendMarker*> markers;
654 QList<LegendMarker*> markers;
475 foreach(QBarSet* set, q->barSets()) {
655 foreach(QBarSet* set, q->barSets()) {
476 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
656 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
477 markers << marker;
657 markers << marker;
478 }
658 }
479
659
480 return markers;
660 return markers;
481 }
661 }
482
662
483 #include "moc_qbarseries.cpp"
663 #include "moc_qbarseries.cpp"
484 #include "moc_qbarseries_p.cpp"
664 #include "moc_qbarseries_p.cpp"
485
665
486 QTCOMMERCIALCHART_END_NAMESPACE
666 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,77 +1,78
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef BARSERIES_H
21 #ifndef BARSERIES_H
22 #define BARSERIES_H
22 #define BARSERIES_H
23
23
24 #include <qabstractseries.h>
24 #include <qabstractseries.h>
25 #include <QStringList>
25 #include <QStringList>
26
26
27 class QModelIndex;
27 class QModelIndex;
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 typedef QStringList QBarCategories;
31 typedef QStringList QBarCategories;
32
32
33 class QBarSet;
33 class QBarSet;
34 class BarCategory;
34 class BarCategory;
35 class QBarSeriesPrivate;
35 class QBarSeriesPrivate;
36
36
37 // Container for series
37 // Container for series
38 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QAbstractSeries
38 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QAbstractSeries
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 explicit QBarSeries(QBarCategories categories, QObject *parent = 0);
42 explicit QBarSeries(QBarCategories categories, QObject *parent = 0);
43 virtual ~QBarSeries();
43 virtual ~QBarSeries();
44
44
45 QAbstractSeries::QSeriesType type() const;
45 QAbstractSeries::QSeriesType type() const;
46
46
47 void appendBarSet(QBarSet *set); // Takes ownership of set
47 void appendBarSet(QBarSet *set); // Takes ownership of set
48 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
48 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
49 void appendBarSets(QList<QBarSet* > sets);
49 void appendBarSets(QList<QBarSet* > sets);
50 void removeBarSets(QList<QBarSet* > sets);
50 void removeBarSets(QList<QBarSet* > sets);
51 int barsetCount() const;
51 int barsetCount() const;
52 int categoryCount() const;
52 int categoryCount() const;
53 QList<QBarSet*> barSets() const;
53 QList<QBarSet*> barSets() const;
54 QBarCategories categories() const;
54 QBarCategories categories() const;
55
55
56 void setLabelsVisible(bool visible = true);
56 void setLabelsVisible(bool visible = true);
57
57
58 bool setModel(QAbstractItemModel *model);
58 bool setModel(QAbstractItemModel *model);
59 void setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical);
59 void setModelMapping(int categories, int bottomBoundary, int topBoundary, Qt::Orientation orientation = Qt::Vertical);
60 void setModelMappingRange(int first, int count = -1);
60
61
61 protected:
62 protected:
62 explicit QBarSeries(QBarSeriesPrivate &d,QObject *parent = 0);
63 explicit QBarSeries(QBarSeriesPrivate &d,QObject *parent = 0);
63
64
64 Q_SIGNALS:
65 Q_SIGNALS:
65 void clicked(QBarSet *barset, QString category);
66 void clicked(QBarSet *barset, QString category);
66 void hovered(QBarSet* barset, bool status);
67 void hovered(QBarSet* barset, bool status);
67
68
68 protected:
69 protected:
69 Q_DECLARE_PRIVATE(QBarSeries)
70 Q_DECLARE_PRIVATE(QBarSeries)
70 friend class BarChartItem;
71 friend class BarChartItem;
71 friend class PercentBarChartItem;
72 friend class PercentBarChartItem;
72 friend class StackedBarChartItem;
73 friend class StackedBarChartItem;
73 };
74 };
74
75
75 QTCOMMERCIALCHART_END_NAMESPACE
76 QTCOMMERCIALCHART_END_NAMESPACE
76
77
77 #endif // BARSERIES_H
78 #endif // BARSERIES_H
@@ -1,60 +1,68
1 #ifndef QBARSERIES_P_H
1 #ifndef QBARSERIES_P_H
2 #define QBARSERIES_P_H
2 #define QBARSERIES_P_H
3
3
4 #include "qbarseries.h"
4 #include "qbarseries.h"
5 #include "qabstractseries_p.h"
5 #include "qabstractseries_p.h"
6 #include <QStringList>
6 #include <QStringList>
7 #include <QAbstractSeries>
7 #include <QAbstractSeries>
8
8
9 class QModelIndex;
9 class QModelIndex;
10
10
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
11 QTCOMMERCIALCHART_BEGIN_NAMESPACE
12
12
13 // Container for series
13 // Container for series
14 class QBarSeriesPrivate : public QAbstractSeriesPrivate
14 class QBarSeriesPrivate : public QAbstractSeriesPrivate
15 {
15 {
16 Q_OBJECT
16 Q_OBJECT
17 public:
17 public:
18 QBarSeriesPrivate(QBarCategories categories, QBarSeries *parent);
18 QBarSeriesPrivate(QBarCategories categories, QBarSeries *parent);
19
19
20 void scaleDomain(Domain& domain);
20 void scaleDomain(Domain& domain);
21 Chart* createGraphics(ChartPresenter* presenter);
21 Chart* createGraphics(ChartPresenter* presenter);
22 QList<LegendMarker*> createLegendMarker(QLegend* legend);
22 QList<LegendMarker*> createLegendMarker(QLegend* legend);
23
23
24 bool setModel(QAbstractItemModel *model);
24 bool setModel(QAbstractItemModel *model);
25 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
25 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
26 void setModelMappingRange(int first, int count = -1);
27
28 void insertCategory(int index, const QString category);
29 void removeCategory(int index);
26
30
27 QBarSet* barsetAt(int index);
31 QBarSet* barsetAt(int index);
28 QString categoryName(int category);
32 QString categoryName(int category);
29 qreal min();
33 qreal min();
30 qreal max();
34 qreal max();
31 qreal valueAt(int set, int category);
35 qreal valueAt(int set, int category);
32 qreal percentageAt(int set, int category);
36 qreal percentageAt(int set, int category);
33 qreal categorySum(int category);
37 qreal categorySum(int category);
34 qreal absoluteCategorySum(int category);
38 qreal absoluteCategorySum(int category);
35 qreal maxCategorySum();
39 qreal maxCategorySum();
36
40
37 Q_SIGNALS:
41 Q_SIGNALS:
38 void clicked(QBarSet *barset, QString category);
42 void clicked(QBarSet *barset, QString category);
39 void updatedBars();
43 void updatedBars();
40 void restructuredBars();
44 void restructuredBars();
45 void categoriesUpdated();
41
46
42 private Q_SLOTS:
47 private Q_SLOTS:
43 // slots for updating bars when data in model changes
48 // slots for updating bars when data in model changes
44 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
49 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
50 void modelDataAdded(QModelIndex parent, int start, int end);
51 void modelDataRemoved(QModelIndex parent, int start, int end);
52 void initializeDataFromModel();
45 void barsetChanged();
53 void barsetChanged();
46
54
47 protected:
55 protected:
48 QList<QBarSet *> m_barSets;
56 QList<QBarSet *> m_barSets;
49 QBarCategories m_categories;
57 QBarCategories m_categories;
50
58
51 int m_mapCategories;
59 int m_mapCategories;
52 int m_mapBarBottom;
60 int m_mapBarBottom;
53 int m_mapBarTop;
61 int m_mapBarTop;
54 private:
62 private:
55 Q_DECLARE_PUBLIC(QBarSeries)
63 Q_DECLARE_PUBLIC(QBarSeries)
56 };
64 };
57
65
58 QTCOMMERCIALCHART_END_NAMESPACE
66 QTCOMMERCIALCHART_END_NAMESPACE
59
67
60 #endif // QBARSERIESPRIVATE_P_H
68 #endif // QBARSERIESPRIVATE_P_H
@@ -1,303 +1,303
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qbarset.h"
21 #include "qbarset.h"
22 #include "qbarset_p.h"
22 #include "qbarset_p.h"
23
23
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25
25
26 /*!
26 /*!
27 \class QBarSet
27 \class QBarSet
28 \brief part of QtCommercial chart API.
28 \brief part of QtCommercial chart API.
29
29
30 QBarSet represents one set of bars. Set of bars contains one data value for each category.
30 QBarSet represents one set of bars. Set of bars contains one data value for each category.
31 First value of set is assumed to belong to first category, second to second category and so on.
31 First value of set is assumed to belong to first category, second to second category and so on.
32 If set has fewer values than there are categories, then the missing values are assumed to be
32 If set has fewer values than there are categories, then the missing values are assumed to be
33 at the end of set. For missing values in middle of a set, numerical value of zero is used.
33 at the end of set. For missing values in middle of a set, numerical value of zero is used.
34
34
35 \mainclass
35 \mainclass
36
36
37 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
37 \sa QBarSeries, QStackedBarSeries, QPercentBarSeries
38 */
38 */
39
39
40 /*!
40 /*!
41 \fn void QBarSet::clicked(QString category)
41 \fn void QBarSet::clicked(QString category)
42 \brief signals that set has been clicked
42 \brief signals that set has been clicked
43 Parameter \a category describes on which category was clicked
43 Parameter \a category describes on which category was clicked
44 */
44 */
45
45
46 /*!
46 /*!
47 \fn void QBarSet::hovered(bool status)
47 \fn void QBarSet::hovered(bool status)
48 \brief signals that mouse has hovered over the set. If \a status is true, then mouse was entered. If \a status is false, then mouse was left.
48 \brief signals that mouse has hovered over the set. If \a status is true, then mouse was entered. If \a status is false, then mouse was left.
49
49
50 The signal is emitted if mouse is hovered on top of set
50 The signal is emitted if mouse is hovered on top of set
51 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
51 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
52 */
52 */
53
53
54 /*!
54 /*!
55 Constructs QBarSet with a name of \a name and with parent of \a parent
55 Constructs QBarSet with a name of \a name and with parent of \a parent
56 */
56 */
57 QBarSet::QBarSet(const QString name, QObject *parent)
57 QBarSet::QBarSet(const QString name, QObject *parent)
58 : QObject(parent)
58 : QObject(parent)
59 ,d_ptr(new QBarSetPrivate(name,this))
59 ,d_ptr(new QBarSetPrivate(name,this))
60 {
60 {
61 }
61 }
62
62
63 /*!
63 /*!
64 Destroys the barset
64 Destroys the barset
65 */
65 */
66 QBarSet::~QBarSet()
66 QBarSet::~QBarSet()
67 {
67 {
68 // NOTE: d_ptr destroyed by QObject
68 // NOTE: d_ptr destroyed by QObject
69 }
69 }
70
70
71 /*!
71 /*!
72 Sets new \a name for set.
72 Sets new \a name for set.
73 */
73 */
74 void QBarSet::setName(const QString name)
74 void QBarSet::setName(const QString name)
75 {
75 {
76 d_ptr->m_name = name;
76 d_ptr->m_name = name;
77 }
77 }
78
78
79 /*!
79 /*!
80 Returns name of the set.
80 Returns name of the set.
81 */
81 */
82 QString QBarSet::name() const
82 QString QBarSet::name() const
83 {
83 {
84 return d_ptr->m_name;
84 return d_ptr->m_name;
85 }
85 }
86
86
87 /*!
87 /*!
88 Appends new value \a value to the end of set.
88 Appends new value \a value to the end of set.
89 */
89 */
90 void QBarSet::append(const qreal value)
90 void QBarSet::append(const qreal value)
91 {
91 {
92 d_ptr->m_values.append(value);
92 d_ptr->m_values.append(value);
93 emit d_ptr->restructuredBars();
93 emit d_ptr->restructuredBars();
94 }
94 }
95
95
96 /*!
96 /*!
97 Appends new value \a value to the end of set.
97 Appends new value \a value to the end of set.
98 */
98 */
99 QBarSet& QBarSet::operator << (const qreal &value)
99 QBarSet& QBarSet::operator << (const qreal &value)
100 {
100 {
101 append(value);
101 append(value);
102 return *this;
102 return *this;
103 }
103 }
104
104
105 /*!
105 /*!
106 Inserts new \a value on the \a index position.
106 Inserts new \a value on the \a index position.
107 The value that is currently at this postion is moved to postion index + 1
107 The value that is currently at this postion is moved to postion index + 1
108 \sa remove()
108 \sa remove()
109 */
109 */
110 void QBarSet::insert(const int index, const qreal value)
110 void QBarSet::insert(const int index, const qreal value)
111 {
111 {
112 d_ptr->m_values.insert(index, value);
112 d_ptr->m_values.insert(index, value);
113 emit d_ptr->updatedBars();
113 // emit d_ptr->updatedBars();
114 }
114 }
115
115
116 /*!
116 /*!
117 Removes the value specified by \a index
117 Removes the value specified by \a index
118 \sa insert()
118 \sa insert()
119 */
119 */
120 void QBarSet::remove(const int index)
120 void QBarSet::remove(const int index)
121 {
121 {
122 d_ptr->m_values.removeAt(index);
122 d_ptr->m_values.removeAt(index);
123 emit d_ptr->updatedBars();
123 // emit d_ptr->updatedBars();
124 }
124 }
125
125
126 /*!
126 /*!
127 Sets a new value \a value to set, indexed by \a index
127 Sets a new value \a value to set, indexed by \a index
128 */
128 */
129 void QBarSet::replace(const int index, const qreal value)
129 void QBarSet::replace(const int index, const qreal value)
130 {
130 {
131 d_ptr->m_values.replace(index,value);
131 d_ptr->m_values.replace(index,value);
132 emit d_ptr->updatedBars();
132 emit d_ptr->updatedBars();
133 }
133 }
134
134
135 /*!
135 /*!
136 Returns value of set indexed by \a index
136 Returns value of set indexed by \a index
137 */
137 */
138 qreal QBarSet::at(const int index) const
138 qreal QBarSet::at(const int index) const
139 {
139 {
140 return d_ptr->m_values.at(index);
140 return d_ptr->m_values.at(index);
141 }
141 }
142
142
143 /*!
143 /*!
144 Returns value of set indexed by \a index
144 Returns value of set indexed by \a index
145 */
145 */
146 qreal QBarSet::operator [] (int index) const
146 qreal QBarSet::operator [] (int index) const
147 {
147 {
148 return d_ptr->m_values.at(index);
148 return d_ptr->m_values.at(index);
149 }
149 }
150
150
151 /*!
151 /*!
152 Returns count of values in set.
152 Returns count of values in set.
153 */
153 */
154 int QBarSet::count() const
154 int QBarSet::count() const
155 {
155 {
156 return d_ptr->m_values.count();
156 return d_ptr->m_values.count();
157 }
157 }
158
158
159 /*!
159 /*!
160 Returns sum of all values in barset.
160 Returns sum of all values in barset.
161 */
161 */
162 qreal QBarSet::sum() const
162 qreal QBarSet::sum() const
163 {
163 {
164 qreal total(0);
164 qreal total(0);
165 for (int i=0; i < d_ptr->m_values.count(); i++) {
165 for (int i=0; i < d_ptr->m_values.count(); i++) {
166 total += d_ptr->m_values.at(i);
166 total += d_ptr->m_values.at(i);
167 }
167 }
168 return total;
168 return total;
169 }
169 }
170
170
171 /*!
171 /*!
172 Sets pen for set. Bars of this set are drawn using \a pen
172 Sets pen for set. Bars of this set are drawn using \a pen
173 */
173 */
174 void QBarSet::setPen(const QPen &pen)
174 void QBarSet::setPen(const QPen &pen)
175 {
175 {
176 if(d_ptr->m_pen!=pen){
176 if(d_ptr->m_pen!=pen){
177 d_ptr->m_pen = pen;
177 d_ptr->m_pen = pen;
178 emit d_ptr->updatedBars();
178 emit d_ptr->updatedBars();
179 }
179 }
180 }
180 }
181
181
182 /*!
182 /*!
183 Returns pen of the set.
183 Returns pen of the set.
184 */
184 */
185 QPen QBarSet::pen() const
185 QPen QBarSet::pen() const
186 {
186 {
187 return d_ptr->m_pen;
187 return d_ptr->m_pen;
188 }
188 }
189
189
190 /*!
190 /*!
191 Sets brush for the set. Bars of this set are drawn using \a brush
191 Sets brush for the set. Bars of this set are drawn using \a brush
192 */
192 */
193 void QBarSet::setBrush(const QBrush &brush)
193 void QBarSet::setBrush(const QBrush &brush)
194 {
194 {
195 if(d_ptr->m_brush!=brush){
195 if(d_ptr->m_brush!=brush){
196 d_ptr->m_brush = brush;
196 d_ptr->m_brush = brush;
197 emit d_ptr->updatedBars();
197 emit d_ptr->updatedBars();
198 }
198 }
199 }
199 }
200
200
201 /*!
201 /*!
202 Returns brush of the set.
202 Returns brush of the set.
203 */
203 */
204 QBrush QBarSet::brush() const
204 QBrush QBarSet::brush() const
205 {
205 {
206 return d_ptr->m_brush;
206 return d_ptr->m_brush;
207 }
207 }
208
208
209 /*!
209 /*!
210 Sets \a pen of the values that are drawn on top of this barset
210 Sets \a pen of the values that are drawn on top of this barset
211 */
211 */
212 void QBarSet::setLabelPen(const QPen &pen)
212 void QBarSet::setLabelPen(const QPen &pen)
213 {
213 {
214 if(d_ptr->m_labelPen!=pen){
214 if(d_ptr->m_labelPen!=pen){
215 d_ptr->m_labelPen = pen;
215 d_ptr->m_labelPen = pen;
216 emit d_ptr->updatedBars();
216 emit d_ptr->updatedBars();
217 }
217 }
218 }
218 }
219
219
220 /*!
220 /*!
221 Returns pen of the values that are drawn on top of this barset
221 Returns pen of the values that are drawn on top of this barset
222 */
222 */
223 QPen QBarSet::labelPen() const
223 QPen QBarSet::labelPen() const
224 {
224 {
225 return d_ptr->m_labelPen;
225 return d_ptr->m_labelPen;
226 }
226 }
227
227
228 /*!
228 /*!
229 Sets \a brush of the values that are drawn on top of this barset
229 Sets \a brush of the values that are drawn on top of this barset
230 */
230 */
231 void QBarSet::setLabelBrush(const QBrush &brush)
231 void QBarSet::setLabelBrush(const QBrush &brush)
232 {
232 {
233 if(d_ptr->m_labelBrush!=brush){
233 if(d_ptr->m_labelBrush!=brush){
234 d_ptr->m_labelBrush = brush;
234 d_ptr->m_labelBrush = brush;
235 emit d_ptr->updatedBars();
235 emit d_ptr->updatedBars();
236 }
236 }
237 }
237 }
238
238
239 /*!
239 /*!
240 Returns brush of the values that are drawn on top of this barset
240 Returns brush of the values that are drawn on top of this barset
241 */
241 */
242 QBrush QBarSet::labelBrush() const
242 QBrush QBarSet::labelBrush() const
243 {
243 {
244 return d_ptr->m_labelBrush;
244 return d_ptr->m_labelBrush;
245 }
245 }
246
246
247 /*!
247 /*!
248 Sets the \a font for values that are drawn on top of this barset
248 Sets the \a font for values that are drawn on top of this barset
249 */
249 */
250 void QBarSet::setLabelFont(const QFont &font)
250 void QBarSet::setLabelFont(const QFont &font)
251 {
251 {
252 if(d_ptr->m_labelFont!=font) {
252 if(d_ptr->m_labelFont!=font) {
253 d_ptr->m_labelFont = font;
253 d_ptr->m_labelFont = font;
254 emit d_ptr->updatedBars();
254 emit d_ptr->updatedBars();
255 }
255 }
256
256
257 }
257 }
258
258
259 /*!
259 /*!
260 Returns the pen for values that are drawn on top of this set
260 Returns the pen for values that are drawn on top of this set
261 */
261 */
262 QFont QBarSet::labelFont() const
262 QFont QBarSet::labelFont() const
263 {
263 {
264 return d_ptr->m_labelFont;
264 return d_ptr->m_labelFont;
265 }
265 }
266
266
267 /*!
267 /*!
268 Sets visibility of bar labels. If \a visible is true, labels are drawn on top of barsets.
268 Sets visibility of bar labels. If \a visible is true, labels are drawn on top of barsets.
269 */
269 */
270
270
271 void QBarSet::setLabelsVisible(bool visible)
271 void QBarSet::setLabelsVisible(bool visible)
272 {
272 {
273 if(d_ptr->m_labelsVisible!=visible) {
273 if(d_ptr->m_labelsVisible!=visible) {
274 d_ptr->m_labelsVisible = visible;
274 d_ptr->m_labelsVisible = visible;
275 emit d_ptr->labelsVisibleChanged(visible);
275 emit d_ptr->labelsVisibleChanged(visible);
276 }
276 }
277 }
277 }
278
278
279 /*!
279 /*!
280 Returns the visibility of values
280 Returns the visibility of values
281 */
281 */
282 bool QBarSet::labelsVisible() const
282 bool QBarSet::labelsVisible() const
283 {
283 {
284 return d_ptr->m_labelsVisible;
284 return d_ptr->m_labelsVisible;
285 }
285 }
286
286
287 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
287 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
288
288
289 QBarSetPrivate::QBarSetPrivate(const QString name, QBarSet *parent) : QObject(parent),
289 QBarSetPrivate::QBarSetPrivate(const QString name, QBarSet *parent) : QObject(parent),
290 q_ptr(parent),
290 q_ptr(parent),
291 m_name(name),
291 m_name(name),
292 m_labelsVisible(false)
292 m_labelsVisible(false)
293 {
293 {
294 }
294 }
295
295
296 QBarSetPrivate::~QBarSetPrivate()
296 QBarSetPrivate::~QBarSetPrivate()
297 {
297 {
298 }
298 }
299
299
300 #include "moc_qbarset.cpp"
300 #include "moc_qbarset.cpp"
301 #include "moc_qbarset_p.cpp"
301 #include "moc_qbarset_p.cpp"
302
302
303 QTCOMMERCIALCHART_END_NAMESPACE
303 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,649 +1,863
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qpieseries.h"
21 #include "qpieseries.h"
22 #include "qpieseries_p.h"
22 #include "qpieseries_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "pieslicedata_p.h"
24 #include "pieslicedata_p.h"
25 #include "chartdataset_p.h"
25 #include "chartdataset_p.h"
26 #include "charttheme_p.h"
26 #include "charttheme_p.h"
27 #include "chartanimator_p.h"
27 #include "chartanimator_p.h"
28 #include "legendmarker_p.h"
28 #include "legendmarker_p.h"
29 #include <QAbstractItemModel>
29 #include <QAbstractItemModel>
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 /*!
33 /*!
34 \class QPieSeries
34 \class QPieSeries
35 \brief Pie series API for QtCommercial Charts
35 \brief Pie series API for QtCommercial Charts
36
36
37 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
37 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
38 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 The actual slice size is determined by that relative value.
39 The actual slice size is determined by that relative value.
40
40
41 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
41 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 These relate to the actual chart rectangle.
42 These relate to the actual chart rectangle.
43
43
44 By default the pie is defined as a full pie but it can also be a partial pie.
44 By default the pie is defined as a full pie but it can also be a partial pie.
45 This can be done by setting a starting angle and angle span to the series.
45 This can be done by setting a starting angle and angle span to the series.
46 Full pie is 360 degrees where 0 is at 12 a'clock.
46 Full pie is 360 degrees where 0 is at 12 a'clock.
47
47
48 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
48 See the \l {PieChart Example} {pie chart example} to learn how to create a simple pie chart.
49 \image examples_piechart.png
49 \image examples_piechart.png
50 */
50 */
51
51
52 /*!
52 /*!
53 \property QPieSeries::horizontalPosition
53 \property QPieSeries::horizontalPosition
54 \brief Defines the horizontal position of the pie.
54 \brief Defines the horizontal position of the pie.
55
55
56 The value is a relative value to the chart rectangle where:
56 The value is a relative value to the chart rectangle where:
57
57
58 \list
58 \list
59 \o 0.0 is the absolute left.
59 \o 0.0 is the absolute left.
60 \o 1.0 is the absolute right.
60 \o 1.0 is the absolute right.
61 \endlist
61 \endlist
62
62
63 Default value is 0.5 (center).
63 Default value is 0.5 (center).
64 */
64 */
65
65
66 /*!
66 /*!
67 \property QPieSeries::verticalPosition
67 \property QPieSeries::verticalPosition
68 \brief Defines the vertical position of the pie.
68 \brief Defines the vertical position of the pie.
69
69
70 The value is a relative value to the chart rectangle where:
70 The value is a relative value to the chart rectangle where:
71
71
72 \list
72 \list
73 \o 0.0 is the absolute top.
73 \o 0.0 is the absolute top.
74 \o 1.0 is the absolute bottom.
74 \o 1.0 is the absolute bottom.
75 \endlist
75 \endlist
76
76
77 Default value is 0.5 (center).
77 Default value is 0.5 (center).
78 */
78 */
79
79
80 /*!
80 /*!
81 \property QPieSeries::size
81 \property QPieSeries::size
82 \brief Defines the pie size.
82 \brief Defines the pie size.
83
83
84 The value is a relative value to the chart rectangle where:
84 The value is a relative value to the chart rectangle where:
85
85
86 \list
86 \list
87 \o 0.0 is the minimum size (pie not drawn).
87 \o 0.0 is the minimum size (pie not drawn).
88 \o 1.0 is the maximum size that can fit the chart.
88 \o 1.0 is the maximum size that can fit the chart.
89 \endlist
89 \endlist
90
90
91 Default value is 0.7.
91 Default value is 0.7.
92 */
92 */
93
93
94 /*!
94 /*!
95 \property QPieSeries::startAngle
95 \property QPieSeries::startAngle
96 \brief Defines the starting angle of the pie.
96 \brief Defines the starting angle of the pie.
97
97
98 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
98 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
99
99
100 Default is value is 0.
100 Default is value is 0.
101 */
101 */
102
102
103 /*!
103 /*!
104 \property QPieSeries::endAngle
104 \property QPieSeries::endAngle
105 \brief Defines the ending angle of the pie.
105 \brief Defines the ending angle of the pie.
106
106
107 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
107 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
108
108
109 Default is value is 360.
109 Default is value is 360.
110 */
110 */
111
111
112
112
113 /*!
113 /*!
114 Constructs a series object which is a child of \a parent.
114 Constructs a series object which is a child of \a parent.
115 */
115 */
116 QPieSeries::QPieSeries(QObject *parent) :
116 QPieSeries::QPieSeries(QObject *parent) :
117 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
117 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
118 {
118 {
119
119
120 }
120 }
121
121
122 /*!
122 /*!
123 Destroys the series and its slices.
123 Destroys the series and its slices.
124 */
124 */
125 QPieSeries::~QPieSeries()
125 QPieSeries::~QPieSeries()
126 {
126 {
127 // NOTE: d_prt destroyed by QObject
127 // NOTE: d_prt destroyed by QObject
128 }
128 }
129
129
130 /*!
130 /*!
131 Returns QChartSeries::SeriesTypePie.
131 Returns QChartSeries::SeriesTypePie.
132 */
132 */
133 QAbstractSeries::QSeriesType QPieSeries::type() const
133 QAbstractSeries::QSeriesType QPieSeries::type() const
134 {
134 {
135 return QAbstractSeries::SeriesTypePie;
135 return QAbstractSeries::SeriesTypePie;
136 }
136 }
137
137
138 /*!
138 /*!
139 Appends an array of \a slices to the series.
139 Appends an array of \a slices to the series.
140 Slice ownership is passed to the series.
140 Slice ownership is passed to the series.
141 */
141 */
142 void QPieSeries::append(QList<QPieSlice*> slices)
142 void QPieSeries::append(QList<QPieSlice*> slices)
143 {
143 {
144 Q_D(QPieSeries);
144 Q_D(QPieSeries);
145
145
146 foreach (QPieSlice* s, slices) {
146 foreach (QPieSlice* s, slices) {
147 s->setParent(this);
147 s->setParent(this);
148 d->m_slices << s;
148 d->m_slices << s;
149 }
149 }
150
150
151 d->updateDerivativeData();
151 d->updateDerivativeData();
152
152
153 foreach (QPieSlice* s, slices) {
153 foreach (QPieSlice* s, slices) {
154 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
154 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
155 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
155 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
156 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
156 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
157 }
157 }
158
158
159 emit d->added(slices);
159 emit d->added(slices);
160 }
160 }
161
161
162 /*!
162 /*!
163 Appends a single \a slice to the series.
163 Appends a single \a slice to the series.
164 Slice ownership is passed to the series.
164 Slice ownership is passed to the series.
165 */
165 */
166 void QPieSeries::append(QPieSlice* slice)
166 void QPieSeries::append(QPieSlice* slice)
167 {
167 {
168 append(QList<QPieSlice*>() << slice);
168 append(QList<QPieSlice*>() << slice);
169 }
169 }
170
170
171 /*!
171 /*!
172 Appends a single \a slice to the series and returns a reference to the series.
172 Appends a single \a slice to the series and returns a reference to the series.
173 Slice ownership is passed to the series.
173 Slice ownership is passed to the series.
174 */
174 */
175 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
175 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
176 {
176 {
177 append(slice);
177 append(slice);
178 return *this;
178 return *this;
179 }
179 }
180
180
181
181
182 /*!
182 /*!
183 Appends a single slice to the series with give \a value and \a name.
183 Appends a single slice to the series with give \a value and \a name.
184 Slice ownership is passed to the series.
184 Slice ownership is passed to the series.
185 */
185 */
186 QPieSlice* QPieSeries::append(qreal value, QString name)
186 QPieSlice* QPieSeries::append(qreal value, QString name)
187 {
187 {
188 QPieSlice* slice = new QPieSlice(value, name);
188 QPieSlice* slice = new QPieSlice(value, name);
189 append(slice);
189 append(slice);
190 return slice;
190 return slice;
191 }
191 }
192
192
193 /*!
193 /*!
194 Inserts a single \a slice to the series before the slice at \a index position.
194 Inserts a single \a slice to the series before the slice at \a index position.
195 Slice ownership is passed to the series.
195 Slice ownership is passed to the series.
196 */
196 */
197 void QPieSeries::insert(int index, QPieSlice* slice)
197 void QPieSeries::insert(int index, QPieSlice* slice)
198 {
198 {
199 Q_D(QPieSeries);
199 Q_D(QPieSeries);
200 Q_ASSERT(index <= d->m_slices.count());
200 Q_ASSERT(index <= d->m_slices.count());
201 slice->setParent(this);
201 slice->setParent(this);
202 d->m_slices.insert(index, slice);
202 d->m_slices.insert(index, slice);
203
203
204 d->updateDerivativeData();
204 d->updateDerivativeData();
205
205
206 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
206 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
207 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
207 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
208 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
208 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
209
209
210 emit d->added(QList<QPieSlice*>() << slice);
210 emit d->added(QList<QPieSlice*>() << slice);
211 }
211 }
212
212
213 /*!
213 /*!
214 Removes a single \a slice from the series and deletes the slice.
214 Removes a single \a slice from the series and deletes the slice.
215
215
216 Do not reference the pointer after this call.
216 Do not reference the pointer after this call.
217 */
217 */
218 void QPieSeries::remove(QPieSlice* slice)
218 void QPieSeries::remove(QPieSlice* slice)
219 {
219 {
220 Q_D(QPieSeries);
220 Q_D(QPieSeries);
221 if (!d->m_slices.removeOne(slice)) {
221 if (!d->m_slices.removeOne(slice)) {
222 Q_ASSERT(0); // TODO: how should this be reported?
222 Q_ASSERT(0); // TODO: how should this be reported?
223 return;
223 return;
224 }
224 }
225
225
226 d->updateDerivativeData();
226 d->updateDerivativeData();
227
227
228 emit d->removed(QList<QPieSlice*>() << slice);
228 emit d->removed(QList<QPieSlice*>() << slice);
229
229
230 delete slice;
230 delete slice;
231 slice = 0;
231 slice = 0;
232 }
232 }
233
233
234 /*!
234 /*!
235 Clears all slices from the series.
235 Clears all slices from the series.
236 */
236 */
237 void QPieSeries::clear()
237 void QPieSeries::clear()
238 {
238 {
239 Q_D(QPieSeries);
239 Q_D(QPieSeries);
240 if (d->m_slices.count() == 0)
240 if (d->m_slices.count() == 0)
241 return;
241 return;
242
242
243 QList<QPieSlice*> slices = d->m_slices;
243 QList<QPieSlice*> slices = d->m_slices;
244 foreach (QPieSlice* s, d->m_slices) {
244 foreach (QPieSlice* s, d->m_slices) {
245 d->m_slices.removeOne(s);
245 d->m_slices.removeOne(s);
246 delete s;
246 delete s;
247 }
247 }
248
248
249 d->updateDerivativeData();
249 d->updateDerivativeData();
250
250
251 emit d->removed(slices);
251 emit d->removed(slices);
252 }
252 }
253
253
254 /*!
254 /*!
255 returns the number of the slices in this series.
255 returns the number of the slices in this series.
256 */
256 */
257 int QPieSeries::count() const
257 int QPieSeries::count() const
258 {
258 {
259 Q_D(const QPieSeries);
259 Q_D(const QPieSeries);
260 return d->m_slices.count();
260 return d->m_slices.count();
261 }
261 }
262
262
263 /*!
263 /*!
264 Returns true is the series is empty.
264 Returns true is the series is empty.
265 */
265 */
266 bool QPieSeries::isEmpty() const
266 bool QPieSeries::isEmpty() const
267 {
267 {
268 Q_D(const QPieSeries);
268 Q_D(const QPieSeries);
269 return d->m_slices.isEmpty();
269 return d->m_slices.isEmpty();
270 }
270 }
271
271
272 /*!
272 /*!
273 Returns a list of slices that belong to this series.
273 Returns a list of slices that belong to this series.
274 */
274 */
275 QList<QPieSlice*> QPieSeries::slices() const
275 QList<QPieSlice*> QPieSeries::slices() const
276 {
276 {
277 Q_D(const QPieSeries);
277 Q_D(const QPieSeries);
278 return d->m_slices;
278 return d->m_slices;
279 }
279 }
280
280
281 void QPieSeries::setHorizontalPosition(qreal relativePosition)
281 void QPieSeries::setHorizontalPosition(qreal relativePosition)
282 {
282 {
283 Q_D(QPieSeries);
283 Q_D(QPieSeries);
284 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
284 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
285 emit d->piePositionChanged();
285 emit d->piePositionChanged();
286 }
286 }
287
287
288 void QPieSeries::setVerticalPosition(qreal relativePosition)
288 void QPieSeries::setVerticalPosition(qreal relativePosition)
289 {
289 {
290 Q_D(QPieSeries);
290 Q_D(QPieSeries);
291 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
291 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
292 emit d->piePositionChanged();
292 emit d->piePositionChanged();
293 }
293 }
294
294
295 qreal QPieSeries::horizontalPosition() const
295 qreal QPieSeries::horizontalPosition() const
296 {
296 {
297 Q_D(const QPieSeries);
297 Q_D(const QPieSeries);
298 return d->m_pieRelativeHorPos;
298 return d->m_pieRelativeHorPos;
299 }
299 }
300
300
301 qreal QPieSeries::verticalPosition() const
301 qreal QPieSeries::verticalPosition() const
302 {
302 {
303 Q_D(const QPieSeries);
303 Q_D(const QPieSeries);
304 return d->m_pieRelativeVerPos;
304 return d->m_pieRelativeVerPos;
305 }
305 }
306
306
307 void QPieSeries::setPieSize(qreal relativeSize)
307 void QPieSeries::setPieSize(qreal relativeSize)
308 {
308 {
309 Q_D(QPieSeries);
309 Q_D(QPieSeries);
310 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
310 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
311 emit d->pieSizeChanged();
311 emit d->pieSizeChanged();
312 }
312 }
313
313
314 qreal QPieSeries::pieSize() const
314 qreal QPieSeries::pieSize() const
315 {
315 {
316 Q_D(const QPieSeries);
316 Q_D(const QPieSeries);
317 return d->m_pieRelativeSize;
317 return d->m_pieRelativeSize;
318 }
318 }
319
319
320
320
321 void QPieSeries::setPieStartAngle(qreal angle)
321 void QPieSeries::setPieStartAngle(qreal angle)
322 {
322 {
323 Q_D(QPieSeries);
323 Q_D(QPieSeries);
324 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
324 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
325 d->updateDerivativeData();
325 d->updateDerivativeData();
326 }
326 }
327
327
328 qreal QPieSeries::pieStartAngle() const
328 qreal QPieSeries::pieStartAngle() const
329 {
329 {
330 Q_D(const QPieSeries);
330 Q_D(const QPieSeries);
331 return d->m_pieStartAngle;
331 return d->m_pieStartAngle;
332 }
332 }
333
333
334 /*!
334 /*!
335 Sets the end angle of the pie.
335 Sets the end angle of the pie.
336
336
337 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
337 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
338
338
339 \a angle must be greater than start angle.
339 \a angle must be greater than start angle.
340
340
341 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
341 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
342 */
342 */
343 void QPieSeries::setPieEndAngle(qreal angle)
343 void QPieSeries::setPieEndAngle(qreal angle)
344 {
344 {
345 Q_D(QPieSeries);
345 Q_D(QPieSeries);
346
346
347 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
347 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
348 d->updateDerivativeData();
348 d->updateDerivativeData();
349 }
349 }
350
350
351 /*!
351 /*!
352 Returns the end angle of the pie.
352 Returns the end angle of the pie.
353
353
354 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
354 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
355
355
356 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
356 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
357 */
357 */
358 qreal QPieSeries::pieEndAngle() const
358 qreal QPieSeries::pieEndAngle() const
359 {
359 {
360 Q_D(const QPieSeries);
360 Q_D(const QPieSeries);
361 return d->m_pieEndAngle;
361 return d->m_pieEndAngle;
362 }
362 }
363
363
364 /*!
364 /*!
365 Sets the all the slice labels \a visible or invisible.
365 Sets the all the slice labels \a visible or invisible.
366
366
367 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
367 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
368 */
368 */
369 void QPieSeries::setLabelsVisible(bool visible)
369 void QPieSeries::setLabelsVisible(bool visible)
370 {
370 {
371 Q_D(QPieSeries);
371 Q_D(QPieSeries);
372 foreach (QPieSlice* s, d->m_slices)
372 foreach (QPieSlice* s, d->m_slices)
373 s->setLabelVisible(visible);
373 s->setLabelVisible(visible);
374 }
374 }
375
375
376 /*!
376 /*!
377 Returns the sum of all slice values in this series.
377 Returns the sum of all slice values in this series.
378
378
379 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
379 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
380 */
380 */
381 qreal QPieSeries::sum() const
381 qreal QPieSeries::sum() const
382 {
382 {
383 Q_D(const QPieSeries);
383 Q_D(const QPieSeries);
384 return d->m_sum;
384 return d->m_sum;
385 }
385 }
386
386
387 /*!
387 /*!
388 \fn void QPieSeries::clicked(QPieSlice* slice)
388 \fn void QPieSeries::clicked(QPieSlice* slice)
389
389
390 This signal is emitted when a \a slice has been clicked.
390 This signal is emitted when a \a slice has been clicked.
391
391
392 \sa QPieSlice::clicked()
392 \sa QPieSlice::clicked()
393 */
393 */
394
394
395 /*!
395 /*!
396 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
396 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
397
397
398 This signal is emitted when user has hovered over or away from the \a slice.
398 This signal is emitted when user has hovered over or away from the \a slice.
399
399
400 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
400 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
401
401
402 \sa QPieSlice::hovered()
402 \sa QPieSlice::hovered()
403 */
403 */
404
404
405 /*!
405 /*!
406 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
406 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
407 Sets the \a model to be used as a data source
407 Sets the \a model to be used as a data source
408 */
408 */
409 bool QPieSeries::setModel(QAbstractItemModel* model)
409 bool QPieSeries::setModel(QAbstractItemModel* model)
410 {
410 {
411 Q_D(QPieSeries);
411 Q_D(QPieSeries);
412 // disconnect signals from old model
412 // disconnect signals from old model
413 if(d->m_model)
413 if(d->m_model)
414 {
414 {
415 disconnect(d->m_model, 0, this, 0);
415 disconnect(d->m_model, 0, this, 0);
416 d->m_mapValues = -1;
416 d->m_mapValues = -1;
417 d->m_mapLabels = -1;
417 d->m_mapLabels = -1;
418 d->m_mapOrientation = Qt::Vertical;
418 d->m_mapOrientation = Qt::Vertical;
419 }
419 }
420
420
421 // set new model
421 // set new model
422 if(model)
422 if(model)
423 {
423 {
424 d->m_model = model;
424 d->m_model = model;
425 return true;
425 return true;
426 }
426 }
427 else
427 else
428 {
428 {
429 d->m_model = 0;
429 d->m_model = 0;
430 return false;
430 return false;
431 }
431 }
432 }
432 }
433
433
434 /*!
434 /*!
435 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
435 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
436 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
436 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
437 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
437 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
438 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
438 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
439 The \a orientation parameter specifies whether the data is in columns or in rows.
439 The \a orientation parameter specifies whether the data is in columns or in rows.
440 */
440 */
441 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
441 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
442 {
442 {
443 Q_D(QPieSeries);
443 Q_D(QPieSeries);
444
444
445 if (d->m_model == 0)
445 if (d->m_model == 0)
446 return;
446 return;
447
447
448 d->m_mapValues = modelValuesLine;
448 d->m_mapValues = modelValuesLine;
449 d->m_mapLabels = modelLabelsLine;
449 d->m_mapLabels = modelLabelsLine;
450 d->m_mapOrientation = orientation;
450 d->m_mapOrientation = orientation;
451
451
452 // connect the signals
452 d->initializePieFromModel();
453 connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
453 // // connect the signals
454 // connect(d->m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
454
455
455
456
456 // create the initial slices set
457 // // create the initial slices set
457 if (d->m_mapOrientation == Qt::Vertical) {
458 // if (d->m_mapOrientation == Qt::Vertical) {
458 for (int i = 0; i < d->m_model->rowCount(); i++)
459 // for (int i = 0; i < d->m_model->rowCount(); i++)
459 append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
460 // append(d->m_model->data(d->m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
460 } else {
461 // } else {
461 for (int i = 0; i < d->m_model->columnCount(); i++)
462 // for (int i = 0; i < d->m_model->columnCount(); i++)
462 append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
463 // append(d->m_model->data(d->m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), d->m_model->data(d->m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
464 // }
463 }
465 }
466
467 void QPieSeries::setModelMappingRange(int first, int count)
468 {
469 Q_D(QPieSeries);
470 d->m_mapFirst = first;
471 d->m_mapCount = count;
464 }
472 }
465
473
466 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
474 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
467
475
468
476
469 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
477 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
470 QAbstractSeriesPrivate(parent),
478 QAbstractSeriesPrivate(parent),
471 m_pieRelativeHorPos(0.5),
479 m_pieRelativeHorPos(0.5),
472 m_pieRelativeVerPos(0.5),
480 m_pieRelativeVerPos(0.5),
473 m_pieRelativeSize(0.7),
481 m_pieRelativeSize(0.7),
474 m_pieStartAngle(0),
482 m_pieStartAngle(0),
475 m_pieEndAngle(360),
483 m_pieEndAngle(360),
476 m_sum(0),
484 m_sum(0),
477 m_mapValues(0),
485 m_mapValues(0),
478 m_mapLabels(0)
486 m_mapLabels(0)
479 {
487 {
480
488
481 }
489 }
482
490
483 QPieSeriesPrivate::~QPieSeriesPrivate()
491 QPieSeriesPrivate::~QPieSeriesPrivate()
484 {
492 {
485
493
486 }
494 }
487
495
488 void QPieSeriesPrivate::updateDerivativeData()
496 void QPieSeriesPrivate::updateDerivativeData()
489 {
497 {
490 m_sum = 0;
498 m_sum = 0;
491
499
492 // nothing to do?
500 // nothing to do?
493 if (m_slices.count() == 0)
501 if (m_slices.count() == 0)
494 return;
502 return;
495
503
496 // calculate sum of all slices
504 // calculate sum of all slices
497 foreach (QPieSlice* s, m_slices)
505 foreach (QPieSlice* s, m_slices)
498 m_sum += s->value();
506 m_sum += s->value();
499
507
500 // nothing to show..
508 // nothing to show..
501 if (qFuzzyIsNull(m_sum))
509 if (qFuzzyIsNull(m_sum))
502 return;
510 return;
503
511
504 // update slice attributes
512 // update slice attributes
505 qreal sliceAngle = m_pieStartAngle;
513 qreal sliceAngle = m_pieStartAngle;
506 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
514 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
507 QVector<QPieSlice*> changed;
515 QVector<QPieSlice*> changed;
508 foreach (QPieSlice* s, m_slices) {
516 foreach (QPieSlice* s, m_slices) {
509
517
510 PieSliceData data = PieSliceData::data(s);
518 PieSliceData data = PieSliceData::data(s);
511 data.m_percentage = s->value() / m_sum;
519 data.m_percentage = s->value() / m_sum;
512 data.m_angleSpan = pieSpan * data.m_percentage;
520 data.m_angleSpan = pieSpan * data.m_percentage;
513 data.m_startAngle = sliceAngle;
521 data.m_startAngle = sliceAngle;
514 sliceAngle += data.m_angleSpan;
522 sliceAngle += data.m_angleSpan;
515
523
516 if (PieSliceData::data(s) != data) {
524 if (PieSliceData::data(s) != data) {
517 PieSliceData::data(s) = data;
525 PieSliceData::data(s) = data;
518 changed << s;
526 changed << s;
519 }
527 }
520 }
528 }
521
529
522 // emit signals
530 // emit signals
523 foreach (QPieSlice* s, changed)
531 foreach (QPieSlice* s, changed)
524 PieSliceData::data(s).emitChangedSignal(s);
532 PieSliceData::data(s).emitChangedSignal(s);
525 }
533 }
526
534
527 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
535 QPieSeriesPrivate* QPieSeriesPrivate::seriesData(QPieSeries &series)
528 {
536 {
529 return series.d_func();
537 return series.d_func();
530 }
538 }
531
539
532 void QPieSeriesPrivate::sliceChanged()
540 void QPieSeriesPrivate::sliceChanged()
533 {
541 {
534 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
542 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
535 updateDerivativeData();
543 updateDerivativeData();
536 }
544 }
537
545
538 void QPieSeriesPrivate::sliceClicked()
546 void QPieSeriesPrivate::sliceClicked()
539 {
547 {
540 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
548 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
541 Q_ASSERT(m_slices.contains(slice));
549 Q_ASSERT(m_slices.contains(slice));
542 Q_Q(QPieSeries);
550 Q_Q(QPieSeries);
543 emit q->clicked(slice);
551 emit q->clicked(slice);
544 }
552 }
545
553
546 void QPieSeriesPrivate::sliceHovered(bool state)
554 void QPieSeriesPrivate::sliceHovered(bool state)
547 {
555 {
548 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
556 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
549 Q_ASSERT(m_slices.contains(slice));
557 Q_ASSERT(m_slices.contains(slice));
550 Q_Q(QPieSeries);
558 Q_Q(QPieSeries);
551 emit q->hovered(slice, state);
559 emit q->hovered(slice, state);
552 }
560 }
553
561
554 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
562 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
555 {
563 {
556 Q_UNUSED(bottomRight)
564 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
557
565 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
558 if (m_mapOrientation == Qt::Vertical)
566 if (m_mapOrientation == Qt::Vertical)
559 {
567 {
568 if ( topLeft.row() >= m_mapFirst && (m_mapCount == - 1 || topLeft.row() < m_mapFirst + m_mapCount)) {
560 if (topLeft.column() == m_mapValues)
569 if (topLeft.column() == m_mapValues)
561 if (m_mapValues == m_mapLabels)
570 m_slices.at(topLeft.row() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
562 {
571 if (topLeft.column() == m_mapLabels)
563 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
572 m_slices.at(topLeft.row() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
564 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
565 }
566 else
567 {
568 m_slices.at(topLeft.row())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
569 }
573 }
570 else if (topLeft.column() == m_mapLabels)
571 m_slices.at(topLeft.row())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
572 }
574 }
573 else
575 else
574 {
576 {
577 if (topLeft.column() >= m_mapFirst && (m_mapCount == - 1 || topLeft.column() < m_mapFirst + m_mapCount)) {
575 if (topLeft.row() == m_mapValues)
578 if (topLeft.row() == m_mapValues)
576 if (m_mapValues == m_mapLabels)
579 m_slices.at(topLeft.column() - m_mapFirst)->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
580 if (topLeft.row() == m_mapLabels)
581 m_slices.at(topLeft.column() - m_mapFirst)->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
582 }
583 }
584 }
585 }
586 }
587
588
589 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
577 {
590 {
578 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
591 Q_UNUSED(parent);
579 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
592 Q_Q(QPieSeries);
593 // series uses model as a data sourceupda
594 int addedCount = end - start + 1;
595 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
596 return;
597 } else {
598 int first = qMax(start, m_mapFirst);
599 int last = qMin(first + addedCount - 1, end);
600 for (int i = first; i <= last; i++) {
601 QPieSlice *slice = new QPieSlice;
602 if (m_mapOrientation == Qt::Vertical) {
603 slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
604 slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
605 } else {
606 slice->setValue(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble());
607 slice->setLabel(m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
608 }
609 slice->setLabelVisible();
610 q->insert(i - m_mapFirst, slice);
611 }
612 if (m_mapCount != -1 && m_slices.size() > m_mapCount)
613 for (int i = m_slices.size() - 1; i >= m_mapCount; i--)
614 q->remove(q->slices().at(i));
615 }
616
617 // // adding items to unlimited map
618 // else if (m_mapCount == -1 && start >= m_mapFirst) {
619 // for (int i = start; i <= end; i++) {
620 // QPieSlice *slice = new QPieSlice;
621 // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
622 // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
623 // slice->setLabelVisible(true);
624 // q->insert(i - m_mapFirst, slice);
625 // // handlePointAdded(i - first);
626 // }
627 // } else if (m_mapCount == - 1 && start < m_mapFirst) {
628 // // not all newly added items
629 // for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) {
630 // QPieSlice *slice = new QPieSlice;
631 // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
632 // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
633 // slice->setLabelVisible(true);
634 // q->insert(i - m_mapFirst, slice);
635 // // handlePointAdded(i - first);
636 // }
637 // }
638
639 // // adding items to limited map
640 // else if (start >= m_mapFirst) {
641 // // remove the items that will no longer fit into the map
642 // // int toRemove = addedCount - (count - points().size());
643 // for (int i = start; i <= end; i++) {
644 // QPieSlice *slice = new QPieSlice;
645 // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
646 // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
647 // slice->setLabelVisible(true);
648 // q->insert(i - m_mapFirst, slice);
649 // }
650 // if (m_slices.size() > m_mapCount)
651 // for (int i = m_slices.size() - 1; i >= m_mapCount; i--)
652 // q->remove(q->slices().at(i));
653 // // handlePointRemoved(i);
654 // // update();
655 // } else {
656 // //
657 // for (int i = m_mapFirst; i < m_mapFirst + addedCount; i++) {
658 // QPieSlice *slice = new QPieSlice;
659 // slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
660 // slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
661 // slice->setLabelVisible(true);
662 // q->insert(i - m_mapFirst, slice);
663 // // handlePointAdded(i - first);
664 // }
665 // if (m_slices.size() > m_mapCount)
666 // for (int i = m_slices.size() - 1; i >= m_mapCount; i--)
667 // q->remove(q->slices().at(i));
668 // // handlePointRemoved(i);
669 // }
670 }
671
672 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
673 {
674 Q_UNUSED(parent);
675 Q_Q(QPieSeries);
676 int removedCount = end - start + 1;
677 if (m_mapCount != -1 && start >= m_mapFirst + m_mapCount) {
678 return;
580 }
679 }
680
681 // else if (m_mapCount == -1) {
682 // int first = qMax(start, m_mapFirst);
683 // int last = qMax(end, m_mapFirst + removedCount - 1);
684 // for (int i = last; i >= first; i--)
685 // q->remove(q->slices().at(i - m_mapFirst));
686 // }
687 // else {
688 // int toRemove = qMin(m_slices.size() - 1, removedCount);
689 // int first = qMax(start, m_mapFirst);
690 // int last = qMax(end, m_mapFirst + toRemove - 1);
691
692 // }
693
694 // removing items from unlimited map
695 else if (m_mapCount == -1 && start >= m_mapFirst) {
696 for (int i = end; i >= start; i--)
697 q->remove(q->slices().at(i - m_mapFirst));
698 // handlePointRemoved(i - m_mapFirst);
699 } else if (m_mapCount == - 1 && start < m_mapFirst) {
700 // not all removed items
701 for (int i = m_mapFirst + removedCount - 1; i >= m_mapFirst; i--)
702 q->remove(q->slices().at(i - m_mapFirst));
703 // handlePointRemoved(i - m_mapFirst);
704 }
705
706 // removing items from limited map
707 else if (start >= m_mapFirst) {
708 //
709 // int sizeAfter = m_slices.size();
710 int lastExisting = qMin(m_mapFirst + m_slices.size() - 1, end);
711 for (int i = lastExisting; i >= start; i--) {
712 q->remove(q->slices().at(i - m_mapFirst));
713 // sizeAfter--;
714 // handlePointRemoved(i - m_mapFirst);
715 }
716
717 // the map is limited, so after removing the items some new items may have fall within the mapped area
718 int itemsAvailable;
719 if (m_mapOrientation == Qt::Vertical)
720 itemsAvailable = m_model->rowCount() - m_mapFirst - m_slices.size();
581 else
721 else
722 itemsAvailable = m_model->columnCount() - m_mapFirst - m_slices.size();
723 int toBeAdded = qMin(itemsAvailable, m_mapCount - m_slices.size());
724 int currentSize = m_slices.size();
725 if (itemsAvailable > 0)
726 for (int i = m_slices.size() + m_mapFirst; i < currentSize + toBeAdded + m_mapFirst; i++) {
727 // handlePointAdded(i);
728 QPieSlice *slice = new QPieSlice;
729 slice->setValue(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble());
730 slice->setLabel(m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
731 slice->setLabelVisible(true);
732 q->insert(i - m_mapFirst, slice);
733 }
734
735 // for (int i = lastExisting; i >= start; i--) {
736 // q->remove(q->slices().at(i - m_mapFirst));
737 //// sizeAfter--;
738 //// handlePointRemoved(i - m_mapFirst);
739 // }
740 } else {
741 // first remove item lays before the mapped area
742 int toRemove = qMin(m_slices.size(), removedCount);
743 for (int i = m_mapFirst; i < m_mapFirst + toRemove; i++)
744 q->remove(q->slices().at(0));
745 // handlePointRemoved(0);
746
747 // the map is limited, so after removing the items some new items may have fall into the map
748 int itemsAvailable;
749 if (m_mapOrientation == Qt::Vertical)
750 itemsAvailable = m_model->rowCount() - m_mapFirst - m_slices.size();
751 else
752 itemsAvailable = m_model->columnCount() - m_mapFirst - m_slices.size();
753 int toBeAdded = qMin(itemsAvailable, m_mapCount - m_slices.size());
754 int currentSize = m_slices.size();
755 if (itemsAvailable > 0)
756 for (int i = m_slices.size(); i < currentSize + toBeAdded; i++) {
757 QPieSlice *slice = new QPieSlice;
758 slice->setValue(m_model->data(m_model->index(i + m_mapFirst, m_mapValues), Qt::DisplayRole).toDouble());
759 slice->setLabel(m_model->data(m_model->index(i + m_mapFirst, m_mapLabels), Qt::DisplayRole).toString());
760 slice->setLabelVisible(true);
761 q->insert(i, slice);
762 // handlePointAdded(i);
763 }
764 }
765
766 }
767
768 void QPieSeriesPrivate::initializePieFromModel()
582 {
769 {
583 m_slices.at(topLeft.column())->setValue(m_model->data(topLeft, Qt::DisplayRole).toDouble());
770 Q_Q(QPieSeries);
771 // clear current content
772 q->clear();
773
774 // connect the signals
775 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex,QModelIndex)));
776 if (m_mapOrientation == Qt::Vertical) {
777 connect(m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
778 connect(m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
779 } else {
780 connect(m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
781 connect(m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
584 }
782 }
585 else if (topLeft.row() == m_mapLabels)
783
586 m_slices.at(topLeft.column())->setLabel(m_model->data(topLeft, Qt::DisplayRole).toString());
784 // create the initial slices set
785 if (m_mapOrientation == Qt::Vertical) {
786 int sliceCount = 0;
787 if(m_mapCount == -1)
788 sliceCount = m_model->rowCount() - m_mapFirst;
789 else
790 sliceCount = qMin(m_mapCount, m_model->rowCount() - m_mapFirst);
791 for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++)
792 q->append(m_model->data(m_model->index(i, m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, m_mapLabels), Qt::DisplayRole).toString());
793 } else {
794 int sliceCount = 0;
795 if(m_mapCount == -1)
796 sliceCount = m_model->columnCount() - m_mapFirst;
797 else
798 sliceCount = qMin(m_mapCount, m_model->columnCount() - m_mapFirst);
799 for (int i = m_mapFirst; i < m_mapFirst + sliceCount; i++)
800 q->append(m_model->data(m_model->index(m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(m_mapLabels, i), Qt::DisplayRole).toString());
587 }
801 }
588 }
802 }
589
803
590 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
804 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
591 {
805 {
592 // Remove rounding errors
806 // Remove rounding errors
593 qreal roundedValue = newValue;
807 qreal roundedValue = newValue;
594 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
808 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
595 roundedValue = 0.0;
809 roundedValue = 0.0;
596 else if (qFuzzyCompare(newValue, max))
810 else if (qFuzzyCompare(newValue, max))
597 roundedValue = max;
811 roundedValue = max;
598 else if (qFuzzyCompare(newValue, min))
812 else if (qFuzzyCompare(newValue, min))
599 roundedValue = min;
813 roundedValue = min;
600
814
601 // Check if the position is valid after removing the rounding errors
815 // Check if the position is valid after removing the rounding errors
602 if (roundedValue < min || roundedValue > max) {
816 if (roundedValue < min || roundedValue > max) {
603 qWarning("QPieSeries: Illegal value");
817 qWarning("QPieSeries: Illegal value");
604 return false;
818 return false;
605 }
819 }
606
820
607 if (!qFuzzyIsNull(value - roundedValue)) {
821 if (!qFuzzyIsNull(value - roundedValue)) {
608 value = roundedValue;
822 value = roundedValue;
609 return true;
823 return true;
610 }
824 }
611
825
612 // The change was so small it is considered a rounding error
826 // The change was so small it is considered a rounding error
613 return false;
827 return false;
614 }
828 }
615
829
616 void QPieSeriesPrivate::scaleDomain(Domain& domain)
830 void QPieSeriesPrivate::scaleDomain(Domain& domain)
617 {
831 {
618 Q_UNUSED(domain);
832 Q_UNUSED(domain);
619 #ifndef QT_NO_DEBUG
833 #ifndef QT_NO_DEBUG
620 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
834 qWarning() << __FILE__<<__FUNCTION__<<"not implemented";
621 #endif
835 #endif
622 }
836 }
623
837
624 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
838 Chart* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
625 {
839 {
626 Q_Q(QPieSeries);
840 Q_Q(QPieSeries);
627 PieChartItem* pie = new PieChartItem(q,presenter);
841 PieChartItem* pie = new PieChartItem(q,presenter);
628 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
842 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
629 presenter->animator()->addAnimation(pie);
843 presenter->animator()->addAnimation(pie);
630 }
844 }
631 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
845 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
632 return pie;
846 return pie;
633 }
847 }
634
848
635 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
849 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
636 {
850 {
637 Q_Q(QPieSeries);
851 Q_Q(QPieSeries);
638 QList<LegendMarker*> markers;
852 QList<LegendMarker*> markers;
639 foreach(QPieSlice* slice, q->slices()) {
853 foreach(QPieSlice* slice, q->slices()) {
640 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
854 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
641 markers << marker;
855 markers << marker;
642 }
856 }
643 return markers;
857 return markers;
644 }
858 }
645
859
646 #include "moc_qpieseries.cpp"
860 #include "moc_qpieseries.cpp"
647 #include "moc_qpieseries_p.cpp"
861 #include "moc_qpieseries_p.cpp"
648
862
649 QTCOMMERCIALCHART_END_NAMESPACE
863 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,88 +1,89
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef PIESERIES_H
21 #ifndef PIESERIES_H
22 #define PIESERIES_H
22 #define PIESERIES_H
23
23
24 #include <qabstractseries.h>
24 #include <qabstractseries.h>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 class QPieSeriesPrivate;
27 class QPieSeriesPrivate;
28 class QPieSlice;
28 class QPieSlice;
29
29
30 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
30 class QTCOMMERCIALCHART_EXPORT QPieSeries : public QAbstractSeries
31 {
31 {
32 Q_OBJECT
32 Q_OBJECT
33 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
33 Q_PROPERTY(qreal horizontalPosition READ horizontalPosition WRITE setHorizontalPosition)
34 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
34 Q_PROPERTY(qreal verticalPosition READ verticalPosition WRITE setVerticalPosition)
35 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
35 Q_PROPERTY(qreal size READ pieSize WRITE setPieSize)
36 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
36 Q_PROPERTY(qreal startAngle READ pieStartAngle WRITE setPieStartAngle)
37 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
37 Q_PROPERTY(qreal endAngle READ pieEndAngle WRITE setPieEndAngle)
38
38
39 public:
39 public:
40 explicit QPieSeries(QObject *parent = 0);
40 explicit QPieSeries(QObject *parent = 0);
41 virtual ~QPieSeries();
41 virtual ~QPieSeries();
42
42
43 QSeriesType type() const;
43 QSeriesType type() const;
44
44
45 void append(QPieSlice* slice);
45 void append(QPieSlice* slice);
46 void append(QList<QPieSlice*> slices);
46 void append(QList<QPieSlice*> slices);
47 QPieSeries& operator << (QPieSlice* slice);
47 QPieSeries& operator << (QPieSlice* slice);
48 QPieSlice* append(qreal value, QString name);
48 QPieSlice* append(qreal value, QString name);
49 void insert(int index, QPieSlice* slice);
49 void insert(int index, QPieSlice* slice);
50 void remove(QPieSlice* slice);
50 void remove(QPieSlice* slice);
51 void clear();
51 void clear();
52
52
53 QList<QPieSlice*> slices() const;
53 QList<QPieSlice*> slices() const;
54 int count() const;
54 int count() const;
55 bool isEmpty() const;
55 bool isEmpty() const;
56
56
57 qreal sum() const;
57 qreal sum() const;
58
58
59 void setHorizontalPosition(qreal relativePosition);
59 void setHorizontalPosition(qreal relativePosition);
60 qreal horizontalPosition() const;
60 qreal horizontalPosition() const;
61 void setVerticalPosition(qreal relativePosition);
61 void setVerticalPosition(qreal relativePosition);
62 qreal verticalPosition() const;
62 qreal verticalPosition() const;
63
63
64 void setPieSize(qreal relativeSize);
64 void setPieSize(qreal relativeSize);
65 qreal pieSize() const;
65 qreal pieSize() const;
66
66
67 void setPieStartAngle(qreal startAngle);
67 void setPieStartAngle(qreal startAngle);
68 qreal pieStartAngle() const;
68 qreal pieStartAngle() const;
69 void setPieEndAngle(qreal endAngle);
69 void setPieEndAngle(qreal endAngle);
70 qreal pieEndAngle() const;
70 qreal pieEndAngle() const;
71
71
72 void setLabelsVisible(bool visible = true);
72 void setLabelsVisible(bool visible = true);
73
73
74 bool setModel(QAbstractItemModel* model);
74 bool setModel(QAbstractItemModel* model);
75 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
75 void setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation = Qt::Vertical);
76 void setModelMappingRange(int first, int count = -1);
76
77
77 Q_SIGNALS:
78 Q_SIGNALS:
78 void clicked(QPieSlice* slice);
79 void clicked(QPieSlice* slice);
79 void hovered(QPieSlice* slice, bool state);
80 void hovered(QPieSlice* slice, bool state);
80
81
81 private:
82 private:
82 Q_DECLARE_PRIVATE(QPieSeries)
83 Q_DECLARE_PRIVATE(QPieSeries)
83 Q_DISABLE_COPY(QPieSeries)
84 Q_DISABLE_COPY(QPieSeries)
84 };
85 };
85
86
86 QTCOMMERCIALCHART_END_NAMESPACE
87 QTCOMMERCIALCHART_END_NAMESPACE
87
88
88 #endif // PIESERIES_H
89 #endif // PIESERIES_H
@@ -1,81 +1,85
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef QPIESERIES_P_H
21 #ifndef QPIESERIES_P_H
22 #define QPIESERIES_P_H
22 #define QPIESERIES_P_H
23
23
24 #include "qpieseries.h"
24 #include "qpieseries.h"
25 #include "qabstractseries_p.h"
25 #include "qabstractseries_p.h"
26
26
27 class QModelIndex;
27 class QModelIndex;
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 class QLegendPrivate;
30 class QLegendPrivate;
31
31
32 class QPieSeriesPrivate : public QAbstractSeriesPrivate
32 class QPieSeriesPrivate : public QAbstractSeriesPrivate
33 {
33 {
34 Q_OBJECT
34 Q_OBJECT
35
35
36 public:
36 public:
37 QPieSeriesPrivate(QPieSeries *parent);
37 QPieSeriesPrivate(QPieSeries *parent);
38 ~QPieSeriesPrivate();
38 ~QPieSeriesPrivate();
39
39
40 void scaleDomain(Domain& domain);
40 void scaleDomain(Domain& domain);
41 Chart* createGraphics(ChartPresenter *presenter);
41 Chart* createGraphics(ChartPresenter *presenter);
42 QList<LegendMarker*> createLegendMarker(QLegend *legend);
42 QList<LegendMarker*> createLegendMarker(QLegend *legend);
43
43
44 void updateDerivativeData();
44 void updateDerivativeData();
45
45
46 static QPieSeriesPrivate* seriesData(QPieSeries &series);
46 static QPieSeriesPrivate* seriesData(QPieSeries &series);
47
47
48 Q_SIGNALS:
48 Q_SIGNALS:
49 void added(QList<QPieSlice*> slices);
49 void added(QList<QPieSlice*> slices);
50 void removed(QList<QPieSlice*> slices);
50 void removed(QList<QPieSlice*> slices);
51 void piePositionChanged();
51 void piePositionChanged();
52 void pieSizeChanged();
52 void pieSizeChanged();
53
53
54 public Q_SLOTS:
54 public Q_SLOTS:
55 void sliceChanged();
55 void sliceChanged();
56 void sliceClicked();
56 void sliceClicked();
57 void sliceHovered(bool state);
57 void sliceHovered(bool state);
58 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
58 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
59 void modelDataAdded(QModelIndex parent, int start, int end);
60 void modelDataRemoved(QModelIndex parent, int start, int end);
61 void initializePieFromModel();
59 bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0);
62 bool setRealValue(qreal &value, qreal newValue, qreal max, qreal min = 0.0);
60
63
61 public:
64 public:
62 QList<QPieSlice*> m_slices;
65 QList<QPieSlice*> m_slices;
63 qreal m_pieRelativeHorPos;
66 qreal m_pieRelativeHorPos;
64 qreal m_pieRelativeVerPos;
67 qreal m_pieRelativeVerPos;
65 qreal m_pieRelativeSize;
68 qreal m_pieRelativeSize;
66 qreal m_pieStartAngle;
69 qreal m_pieStartAngle;
67 qreal m_pieEndAngle;
70 qreal m_pieEndAngle;
68 qreal m_sum;
71 qreal m_sum;
69
72
70 // model map
73 // model map
71 int m_mapValues;
74 int m_mapValues;
72 int m_mapLabels;
75 int m_mapLabels;
76 bool m_modelReady;
73
77
74 private:
78 private:
75 friend class QLegendPrivate;
79 friend class QLegendPrivate;
76 Q_DECLARE_PUBLIC(QPieSeries)
80 Q_DECLARE_PUBLIC(QPieSeries)
77 };
81 };
78
82
79 QTCOMMERCIALCHART_END_NAMESPACE
83 QTCOMMERCIALCHART_END_NAMESPACE
80
84
81 #endif // QPIESERIES_P_H
85 #endif // QPIESERIES_P_H
@@ -1,306 +1,306
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "xychartitem_p.h"
21 #include "xychartitem_p.h"
22 #include "qxyseries.h"
22 #include "qxyseries.h"
23 #include "qxyseries_p.h"
23 #include "qxyseries_p.h"
24 #include "chartpresenter_p.h"
24 #include "chartpresenter_p.h"
25 #include "chartanimator_p.h"
25 #include "chartanimator_p.h"
26 #include <QPainter>
26 #include <QPainter>
27 #include <QGraphicsSceneMouseEvent>
27 #include <QGraphicsSceneMouseEvent>
28 #include <QAbstractItemModel>
28 #include <QAbstractItemModel>
29
29
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 //TODO: optimize : remove points which are not visible
33 //TODO: optimize : remove points which are not visible
34
34
35 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
35 XYChartItem::XYChartItem(QXYSeries *series, ChartPresenter *presenter):ChartItem(presenter),
36 m_minX(0),
36 m_minX(0),
37 m_maxX(0),
37 m_maxX(0),
38 m_minY(0),
38 m_minY(0),
39 m_maxY(0),
39 m_maxY(0),
40 m_series(series)
40 m_series(series)
41 {
41 {
42 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
42 connect(series->d_func(),SIGNAL(pointReplaced(int)),this,SLOT(handlePointReplaced(int)));
43 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
43 connect(series->d_func(),SIGNAL(pointAdded(int)),this,SLOT(handlePointAdded(int)));
44 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
44 connect(series->d_func(),SIGNAL(pointsAdded(int, int)),this,SLOT(handlePointsAdded(int, int)));
45 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
45 connect(series->d_func(),SIGNAL(pointRemoved(int)),this,SLOT(handlePointRemoved(int)));
46 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
46 connect(series->d_func(),SIGNAL(pointsRemoved(int, int)),this,SLOT(handlePointsRemoved(int, int)));
47 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
47 connect(this,SIGNAL(clicked(QPointF)),series,SIGNAL(clicked(QPointF)));
48 }
48 }
49
49
50 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
50 QPointF XYChartItem::calculateGeometryPoint(const QPointF &point) const
51 {
51 {
52 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
52 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
53 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
53 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
54 qreal x = (point.x() - m_minX)* deltaX;
54 qreal x = (point.x() - m_minX)* deltaX;
55 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
55 qreal y = (point.y() - m_minY)*-deltaY + m_size.height();
56 return QPointF(x,y);
56 return QPointF(x,y);
57 }
57 }
58
58
59
59
60 QPointF XYChartItem::calculateGeometryPoint(int index) const
60 QPointF XYChartItem::calculateGeometryPoint(int index) const
61 {
61 {
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
62 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
63 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
64 qreal x = (m_series->x(index) - m_minX)* deltaX;
64 qreal x = (m_series->x(index) - m_minX)* deltaX;
65 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
65 qreal y = (m_series->y(index) - m_minY)*-deltaY + m_size.height();
66 return QPointF(x,y);
66 return QPointF(x,y);
67 }
67 }
68
68
69 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
69 QVector<QPointF> XYChartItem::calculateGeometryPoints() const
70 {
70 {
71 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
71 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
72 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
72 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
73
73
74 QVector<QPointF> points;
74 QVector<QPointF> points;
75 points.reserve(m_series->count());
75 points.reserve(m_series->count());
76 for (int i = 0; i < m_series->count(); ++i) {
76 for (int i = 0; i < m_series->count(); ++i) {
77 qreal x = (m_series->x(i) - m_minX)* deltaX;
77 qreal x = (m_series->x(i) - m_minX)* deltaX;
78 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
78 qreal y = (m_series->y(i) - m_minY)*-deltaY + m_size.height();
79 points << QPointF(x,y);
79 points << QPointF(x,y);
80 }
80 }
81 return points;
81 return points;
82 }
82 }
83
83
84 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
84 QPointF XYChartItem::calculateDomainPoint(const QPointF &point) const
85 {
85 {
86 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
86 const qreal deltaX = m_size.width()/(m_maxX-m_minX);
87 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
87 const qreal deltaY = m_size.height()/(m_maxY-m_minY);
88 qreal x = point.x()/deltaX +m_minX;
88 qreal x = point.x()/deltaX +m_minX;
89 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
89 qreal y = (point.y()-m_size.height())/(-deltaY)+ m_minY;
90 return QPointF(x,y);
90 return QPointF(x,y);
91 }
91 }
92
92
93 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
93 void XYChartItem::updateLayout(QVector<QPointF> &oldPoints, QVector<QPointF> &newPoints,int index)
94 {
94 {
95 if (animator()) {
95 if (animator()) {
96 animator()->updateLayout(this,oldPoints,newPoints,index);
96 animator()->updateLayout(this,oldPoints,newPoints,index);
97 } else {
97 } else {
98 setLayout(newPoints);
98 setLayout(newPoints);
99 }
99 }
100 }
100 }
101
101
102 void XYChartItem::setLayout(QVector<QPointF> &points)
102 void XYChartItem::setLayout(QVector<QPointF> &points)
103 {
103 {
104 m_points = points;
104 m_points = points;
105 update();
105 update();
106 }
106 }
107
107
108 //handlers
108 //handlers
109
109
110 void XYChartItem::handlePointAdded(int index)
110 void XYChartItem::handlePointAdded(int index)
111 {
111 {
112 if (m_series->model() == 0) {
112 if (m_series->model() == 0) {
113 Q_ASSERT(index<m_series->count());
113 Q_ASSERT(index<m_series->count());
114 Q_ASSERT(index>=0);
114 Q_ASSERT(index>=0);
115 }
115 }
116 QVector<QPointF> points = m_points;
116 QVector<QPointF> points = m_points;
117 QPointF point;
117 QPointF point;
118 point = calculateGeometryPoint(index);
118 point = calculateGeometryPoint(index);
119 points.insert(index, point);
119 points.insert(index, point);
120 updateLayout(m_points, points, index);
120 updateLayout(m_points, points, index);
121 update();
121 update();
122 }
122 }
123
123
124 void XYChartItem::handlePointsAdded(int start, int end)
124 void XYChartItem::handlePointsAdded(int start, int end)
125 {
125 {
126 if (m_series->model() == 0) {
126 if (m_series->model() == 0) {
127 for (int i = start; i <= end; i++)
127 for (int i = start; i <= end; i++)
128 handlePointAdded(i);
128 handlePointAdded(i);
129 } else {
129 } else {
130 // series uses model as a data source
130 // series uses model as a data source
131 int first = m_series->mapFirst();
131 int first = m_series->mapFirst();
132 int count = m_series->mapCount();
132 int count = m_series->mapCount();
133 int addedCount = end - start + 1;
133 int addedCount = end - start + 1;
134 if (count != -1 && start >= first + count) {
134 if (count != -1 && start >= first + count) {
135 return;
135 return;
136 }
136 }
137
137
138 // adding items to unlimited map
138 // adding items to unlimited map
139 else if (count == -1 && start >= first) {
139 else if (count == -1 && start >= first) {
140 for (int i = start; i <= end; i++)
140 for (int i = start; i <= end; i++)
141 handlePointAdded(i - first);
141 handlePointAdded(i - first);
142 } else if (count == - 1 && start < first) {
142 } else if (count == - 1 && start < first) {
143 // not all newly added items
143 // not all newly added items
144 for (int i = first; i < first + addedCount; i++)
144 for (int i = first; i < first + addedCount; i++)
145 handlePointAdded(i - first);
145 handlePointAdded(i - first);
146 }
146 }
147 // commented out code below does the same thing, but its more confusing.
147 // commented out code below does the same thing, but its more confusing.
148 // } else if (count == -1) {
148 // } else if (count == -1) {
149 // int begin = qMax(start, first);
149 // int begin = qMax(start, first);
150 // for (int i = begin; i < begin + (end - start + 1); i++)
150 // for (int i = begin; i < begin + (end - start + 1); i++)
151 // handlePointAdded(i - first);
151 // handlePointAdded(i - first);
152 // }
152 // }
153
153
154 // adding items to limited map
154 // adding items to limited map
155 else if (start >= first) {
155 else if (start >= first) {
156 // remove the items that will no longer fit into the map
156 // remove the items that will no longer fit into the map
157 // int toRemove = addedCount - (count - points().size());
157 // int toRemove = addedCount - (count - points().size());
158 for (int i = start; i <= end; i++) {
158 for (int i = start; i <= end; i++) {
159 handlePointAdded(i - first);
159 handlePointAdded(i - first);
160 }
160 }
161 if (m_points.size() > count)
161 if (m_points.size() > count)
162 for (int i = m_points.size() - 1; i >= count; i--)
162 for (int i = m_points.size() - 1; i >= count; i--)
163 handlePointRemoved(i);
163 handlePointRemoved(i);
164 // update();
164 // update();
165 } else {
165 } else {
166 //
166 //
167 for (int i = first; i < first + addedCount; i++) {
167 for (int i = first; i < first + addedCount; i++) {
168 handlePointAdded(i - first);
168 handlePointAdded(i - first);
169 }
169 }
170 if (m_points.size() > count)
170 if (m_points.size() > count)
171 for (int i = m_points.size() - 1; i >= count; i--)
171 for (int i = m_points.size() - 1; i >= count; i--)
172 handlePointRemoved(i);
172 handlePointRemoved(i);
173 }
173 }
174 }
174 }
175 }
175 }
176
176
177 void XYChartItem::handlePointRemoved(int index)
177 void XYChartItem::handlePointRemoved(int index)
178 {
178 {
179 if (m_series->model() == 0) {
179 if (m_series->model() == 0) {
180 Q_ASSERT(index<m_series->count() + 1);
180 Q_ASSERT(index<m_series->count() + 1);
181 Q_ASSERT(index>=0);
181 Q_ASSERT(index>=0);
182 }
182 }
183 QVector<QPointF> points = m_points;
183 QVector<QPointF> points = m_points;
184 points.remove(index);
184 points.remove(index);
185 updateLayout(m_points, points, index);
185 updateLayout(m_points, points, index);
186 update();
186 update();
187 }
187 }
188
188
189 void XYChartItem::handlePointsRemoved(int start, int end)
189 void XYChartItem::handlePointsRemoved(int start, int end)
190 {
190 {
191 Q_UNUSED(start)
191 Q_UNUSED(start)
192 Q_UNUSED(end)
192 Q_UNUSED(end)
193 if (m_series->model() == 0) {
193 if (m_series->model() == 0) {
194 for (int i = end; i >= start; i--)
194 for (int i = end; i >= start; i--)
195 handlePointRemoved(i);
195 handlePointRemoved(i);
196 } else {
196 } else {
197 // series uses model as a data source
197 // series uses model as a data source
198 int first = m_series->mapFirst();
198 int first = m_series->mapFirst();
199 int count = m_series->mapCount();
199 int count = m_series->mapCount();
200 int removedCount = end - start + 1;
200 int removedCount = end - start + 1;
201 if (count != -1 && start >= first + count) {
201 if (count != -1 && start >= first + count) {
202 return;
202 return;
203 }
203 }
204
204
205 // removing items from unlimited map
205 // removing items from unlimited map
206 else if (count == -1 && start >= first) {
206 else if (count == -1 && start >= first) {
207 for (int i = end; i >= start; i--)
207 for (int i = end; i >= start; i--)
208 handlePointRemoved(i - first);
208 handlePointRemoved(i - first);
209 } else if (count == - 1 && start < first) {
209 } else if (count == - 1 && start < first) {
210 // not all removed items
210 // not all removed items
211 for (int i = first + removedCount - 1; i >= first; i--)
211 for (int i = first + removedCount - 1; i >= first; i--)
212 handlePointRemoved(i - first);
212 handlePointRemoved(i - first);
213 }
213 }
214
214
215 // removing items from limited map
215 // removing items from limited map
216 else if (start >= first) {
216 else if (start >= first) {
217 //
217 //
218 int lastExisting = qMin(first + m_points.size() - 1, end);
218 int lastExisting = qMin(first + m_points.size() - 1, end);
219 for (int i = lastExisting; i >= start; i--) {
219 for (int i = lastExisting; i >= start; i--) {
220 handlePointRemoved(i - first);
220 handlePointRemoved(i - first);
221 }
221 }
222
222
223 // the map is limited, so after removing the items some new items may have fall into the map
223 // the map is limited, so after removing the items some new items may have fall within the mapped area
224 int itemsAvailable;
224 int itemsAvailable;
225 if (m_series->mapOrientation() == Qt::Vertical)
225 if (m_series->mapOrientation() == Qt::Vertical)
226 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
226 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
227 else
227 else
228 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
228 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
229 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
229 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
230 int currentSize = m_points.size();
230 int currentSize = m_points.size();
231 if (itemsAvailable > 0)
231 if (itemsAvailable > 0)
232 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
232 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
233 handlePointAdded(i);
233 handlePointAdded(i);
234 } else {
234 } else {
235 // TODO:
235 // first removed item lays before the mapped area
236 int toRemove = qMin(m_points.size() - 1, removedCount);
236 int toRemove = qMin(m_points.size() - 1, removedCount);
237 for (int i = first; i < first + toRemove; i++)
237 for (int i = first; i < first + toRemove; i++)
238 handlePointRemoved(0);
238 handlePointRemoved(0);
239
239
240 // the map is limited, so after removing the items some new items may have fall into the map
240 // the map is limited, so after removing the items some new items may have fall into the map
241 int itemsAvailable;
241 int itemsAvailable;
242 if (m_series->mapOrientation() == Qt::Vertical)
242 if (m_series->mapOrientation() == Qt::Vertical)
243 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
243 itemsAvailable = m_series->model()->rowCount() - first - m_points.size();
244 else
244 else
245 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
245 itemsAvailable = m_series->model()->columnCount() - first - m_points.size();
246 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
246 int toBeAdded = qMin(itemsAvailable, count - m_points.size());
247 int currentSize = m_points.size();
247 int currentSize = m_points.size();
248 if (itemsAvailable > 0)
248 if (itemsAvailable > 0)
249 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
249 for (int i = m_points.size(); i < currentSize + toBeAdded; i++)
250 handlePointAdded(i);
250 handlePointAdded(i);
251 }
251 }
252 }
252 }
253
253
254 }
254 }
255
255
256 void XYChartItem::handlePointReplaced(int index)
256 void XYChartItem::handlePointReplaced(int index)
257 {
257 {
258 Q_ASSERT(index<m_series->count());
258 Q_ASSERT(index<m_series->count());
259 Q_ASSERT(index>=0);
259 Q_ASSERT(index>=0);
260 QPointF point = calculateGeometryPoint(index);
260 QPointF point = calculateGeometryPoint(index);
261 QVector<QPointF> points = m_points;
261 QVector<QPointF> points = m_points;
262 points.replace(index,point);
262 points.replace(index,point);
263 updateLayout(m_points,points,index);
263 updateLayout(m_points,points,index);
264 update();
264 update();
265 }
265 }
266
266
267 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
267 void XYChartItem::handleDomainChanged(qreal minX, qreal maxX, qreal minY, qreal maxY)
268 {
268 {
269 m_minX=minX;
269 m_minX=minX;
270 m_maxX=maxX;
270 m_maxX=maxX;
271 m_minY=minY;
271 m_minY=minY;
272 m_maxY=maxY;
272 m_maxY=maxY;
273
273
274 if (isEmpty()) return;
274 if (isEmpty()) return;
275 QVector<QPointF> points = calculateGeometryPoints();
275 QVector<QPointF> points = calculateGeometryPoints();
276 updateLayout(m_points,points);
276 updateLayout(m_points,points);
277 update();
277 update();
278 }
278 }
279
279
280 void XYChartItem::handleGeometryChanged(const QRectF &rect)
280 void XYChartItem::handleGeometryChanged(const QRectF &rect)
281 {
281 {
282 Q_ASSERT(rect.isValid());
282 Q_ASSERT(rect.isValid());
283 m_size=rect.size();
283 m_size=rect.size();
284 m_clipRect=rect.translated(-rect.topLeft());
284 m_clipRect=rect.translated(-rect.topLeft());
285 setPos(rect.topLeft());
285 setPos(rect.topLeft());
286
286
287 if (isEmpty()) return;
287 if (isEmpty()) return;
288 QVector<QPointF> points = calculateGeometryPoints();
288 QVector<QPointF> points = calculateGeometryPoints();
289 updateLayout(m_points,points);
289 updateLayout(m_points,points);
290 update();
290 update();
291 }
291 }
292
292
293
293
294 bool XYChartItem::isEmpty()
294 bool XYChartItem::isEmpty()
295 {
295 {
296 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
296 return !m_clipRect.isValid() || qFuzzyIsNull(m_maxX - m_minX) || qFuzzyIsNull(m_maxY - m_minY);
297 }
297 }
298
298
299 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
299 void XYChartItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
300 {
300 {
301 emit clicked(calculateDomainPoint(event->pos()));
301 emit clicked(calculateDomainPoint(event->pos()));
302 }
302 }
303
303
304 #include "moc_xychartitem_p.cpp"
304 #include "moc_xychartitem_p.cpp"
305
305
306 QTCOMMERCIALCHART_END_NAMESPACE
306 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,276 +1,276
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "customtablemodel.h"
21 #include "customtablemodel.h"
22 #include <QVector>
22 #include <QVector>
23 #include <QTime>
23 #include <QTime>
24 #include <QRect>
24 #include <QRect>
25 #include <QColor>
25 #include <QColor>
26
26
27 CustomTableModel::CustomTableModel(QObject *parent) :
27 CustomTableModel::CustomTableModel(QObject *parent) :
28 QAbstractTableModel(parent)
28 QAbstractTableModel(parent)
29 {
29 {
30 // m_points.append(QPointF(10, 50));
30 // m_points.append(QPointF(10, 50));
31 // m_labels.append("Apples");
31 // m_labels.append("Apples");
32 // m_points.append(QPointF(60, 70));
32 // m_points.append(QPointF(60, 70));
33 // m_labels.append("Oranges");
33 // m_labels.append("Oranges");
34 // m_points.append(QPointF(110, 50));
34 // m_points.append(QPointF(110, 50));
35 // m_labels.append("Bananas");
35 // m_labels.append("Bananas");
36 // m_points.append(QPointF(140, 40));
36 // m_points.append(QPointF(140, 40));
37 // m_labels.append("Lemons");
37 // m_labels.append("Lemons");
38 // m_points.append(QPointF(200, 150));
38 // m_points.append(QPointF(200, 150));
39 // m_labels.append("Plums");
39 // m_labels.append("Plums");
40 // m_points.append(QPointF(225, 75));
40 // m_points.append(QPointF(225, 75));
41 // m_labels.append("Pearls");
41 // m_labels.append("Pearls");
42
42
43 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
43 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
44
44
45 // m_data
45 // m_data
46 for (int i = 0; i < 6; i++)
46 for (int i = 0; i < 8; i++)
47 {
47 {
48 QVector<qreal>* dataVec = new QVector<qreal>(6);
48 QVector<qreal>* dataVec = new QVector<qreal>(6);
49 // QVector<QColor>* colorVec = new QVector<QColor>(6);
49 // QVector<QColor>* colorVec = new QVector<QColor>(6);
50 for (int k = 0; k < dataVec->size(); k++)
50 for (int k = 0; k < dataVec->size(); k++)
51 {
51 {
52 if (k%2 == 0)
52 if (k%2 == 0)
53 dataVec->replace(k, i * 50 + qrand()%20);
53 dataVec->replace(k, i * 50 + qrand()%20);
54 else
54 else
55 dataVec->replace(k, qrand()%100);
55 dataVec->replace(k, qrand()%100);
56 // colorVec->replace(k, QColor(Qt::white));
56 // colorVec->replace(k, QColor(Qt::white));
57 }
57 }
58 m_data.append(dataVec);
58 m_data.append(dataVec);
59 m_labels.append(QString("Row: %1").arg((i + 1)));
59 m_labels.append(QString("Row: %1").arg((i + 1)));
60 // m_rowsColors.append(colorVec);
60 // m_rowsColors.append(colorVec);
61 }
61 }
62 }
62 }
63
63
64 int CustomTableModel::rowCount(const QModelIndex & parent) const
64 int CustomTableModel::rowCount(const QModelIndex & parent) const
65 {
65 {
66 Q_UNUSED(parent)
66 Q_UNUSED(parent)
67 // return m_points.count();
67 // return m_points.count();
68 return m_data.count();
68 return m_data.count();
69 }
69 }
70
70
71 int CustomTableModel::columnCount(const QModelIndex & parent) const
71 int CustomTableModel::columnCount(const QModelIndex & parent) const
72 {
72 {
73 Q_UNUSED(parent)
73 Q_UNUSED(parent)
74 // return 3;
74 // return 3;
75 return 6;
75 return 6;
76 }
76 }
77
77
78 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation, int role ) const
78 QVariant CustomTableModel::headerData (int section, Qt::Orientation orientation, int role ) const
79 {
79 {
80 if (role != Qt::DisplayRole)
80 if (role != Qt::DisplayRole)
81 return QVariant();
81 return QVariant();
82
82
83 if (orientation == Qt::Horizontal)
83 if (orientation == Qt::Horizontal)
84 {
84 {
85 switch(section)
85 switch(section)
86 {
86 {
87 // case 0:
87 // case 0:
88 // return "x";
88 // return "x";
89 // case 1:
89 // case 1:
90 // return "y";
90 // return "y";
91 // case 2:
91 // case 2:
92 case 6:
92 case 6:
93 return "Fruit";
93 return "Fruit";
94 default:
94 default:
95 if (section%2 == 0)
95 if (section%2 == 0)
96 return "x";
96 return "x";
97 else
97 else
98 return "y";
98 return "y";
99 // return "What?";
99 // return "What?";
100 }
100 }
101 }
101 }
102 else
102 else
103 return QString("%1").arg(section /*+ 1*/);
103 return QString("%1").arg(section /*+ 1*/);
104 }
104 }
105
105
106 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
106 QVariant CustomTableModel::data(const QModelIndex & index, int role) const
107 {
107 {
108 if (role == Qt::DisplayRole)
108 if (role == Qt::DisplayRole)
109 {
109 {
110 switch(index.column())
110 switch(index.column())
111 {
111 {
112 // case 0:
112 // case 0:
113 // return m_points[index.row()].x();
113 // return m_points[index.row()].x();
114 // case 1:
114 // case 1:
115 // return m_points[index.row()].y();
115 // return m_points[index.row()].y();
116 // case 2:
116 // case 2:
117 case 6:
117 case 6:
118 return m_labels[index.row()];
118 return m_labels[index.row()];
119 default:
119 default:
120 return m_data[index.row()]->at(index.column());
120 return m_data[index.row()]->at(index.column());
121 break;
121 break;
122 }
122 }
123 }
123 }
124 else if (role == Qt::EditRole)
124 else if (role == Qt::EditRole)
125 {
125 {
126 switch(index.column())
126 switch(index.column())
127 {
127 {
128 // case 0:
128 // case 0:
129 // return m_points[index.row()].x();
129 // return m_points[index.row()].x();
130 // case 1:
130 // case 1:
131 // return m_points[index.row()].y();
131 // return m_points[index.row()].y();
132 // case 2:
132 // case 2:
133 case 6:
133 case 6:
134 return m_labels[index.row()];
134 return m_labels[index.row()];
135 default:
135 default:
136 return m_data[index.row()]->at(index.column());
136 return m_data[index.row()]->at(index.column());
137 break;
137 break;
138 }
138 }
139 }
139 }
140 else if (role == Qt::BackgroundRole)
140 else if (role == Qt::BackgroundRole)
141 {
141 {
142 QRect rect;
142 QRect rect;
143 foreach(rect, m_mapping)
143 foreach(rect, m_mapping)
144 if(rect.contains(index.column(), index.row()))
144 if(rect.contains(index.column(), index.row()))
145 return QColor(m_mapping.key(rect));
145 return QColor(m_mapping.key(rect));
146
146
147 // cell not mapped return white color
147 // cell not mapped return white color
148 return QColor(Qt::white);
148 return QColor(Qt::white);
149 }
149 }
150 return QVariant();
150 return QVariant();
151 }
151 }
152
152
153 bool CustomTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
153 bool CustomTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
154 {
154 {
155 if (index.isValid() && role == Qt::EditRole)
155 if (index.isValid() && role == Qt::EditRole)
156 {
156 {
157 switch(index.column())
157 switch(index.column())
158 {
158 {
159 // case 0:
159 // case 0:
160 // m_points[index.row()].setX(value.toDouble());
160 // m_points[index.row()].setX(value.toDouble());
161 // break;
161 // break;
162 // case 1:
162 // case 1:
163 // m_points[index.row()].setY(value.toDouble());
163 // m_points[index.row()].setY(value.toDouble());
164 // break;
164 // break;
165 // case 2:
165 // case 2:
166 case 6:
166 case 6:
167 m_labels.replace(index.row(), value.toString());
167 m_labels.replace(index.row(), value.toString());
168 break;
168 break;
169 default:
169 default:
170 m_data[index.row()]->replace(index.column(), value.toDouble());
170 m_data[index.row()]->replace(index.column(), value.toDouble());
171 break;
171 break;
172 // return false;
172 // return false;
173 }
173 }
174 emit dataChanged(index, index);
174 emit dataChanged(index, index);
175 return true;
175 return true;
176 }
176 }
177 // else if (role == Qt::BackgroundRole)
177 // else if (role == Qt::BackgroundRole)
178 // {
178 // {
179 // m_rowsColors[index.row()]->replace(index.column(), value.value<QColor>());
179 // m_rowsColors[index.row()]->replace(index.column(), value.value<QColor>());
180 // return true;
180 // return true;
181 // }
181 // }
182 return false;
182 return false;
183 }
183 }
184
184
185 Qt::ItemFlags CustomTableModel::flags ( const QModelIndex & index ) const
185 Qt::ItemFlags CustomTableModel::flags ( const QModelIndex & index ) const
186 {
186 {
187 // if (!index.isValid())
187 // if (!index.isValid())
188 // return Qt::ItemIsEnabled;
188 // return Qt::ItemIsEnabled;
189 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
189 return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
190 }
190 }
191
191
192 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & parent)
192 bool CustomTableModel::insertRows ( int row, int count, const QModelIndex & parent)
193 {
193 {
194 Q_UNUSED(parent)
194 Q_UNUSED(parent)
195
195
196 if (row < 0)
196 if (row < 0)
197 row = 0;
197 row = 0;
198 beginInsertRows(QModelIndex(), row /*dataTable.count()*/, row + count - 1);
198 beginInsertRows(QModelIndex(), row /*dataTable.count()*/, row + count - 1);
199 for (int i = row; i < row + count; i++)
199 for (int i = row; i < row + count; i++)
200 {
200 {
201 // m_points.insert(row, QPointF(10,20));
201 // m_points.insert(row, QPointF(10,20));
202 QVector<qreal>* dataVec = new QVector<qreal>(6);
202 QVector<qreal>* dataVec = new QVector<qreal>(6);
203 QVector<QColor>* colorVec = new QVector<QColor>(6);
203 QVector<QColor>* colorVec = new QVector<QColor>(6);
204 for (int k = 0; k < dataVec->size(); k++)
204 for (int k = 0; k < dataVec->size(); k++)
205 {
205 {
206 if (k%2 == 0)
206 if (k%2 == 0)
207 // dataVec->replace(k, i * 50 + qrand()%20);
207 // dataVec->replace(k, i * 50 + qrand()%20);
208 {
208 {
209 int difference = 0;
209 int difference = 0;
210 if (i < m_data.size())
210 if (i < m_data.size())
211 {
211 {
212 if (i - 1 >= 0)
212 if (i - 1 >= 0)
213 {
213 {
214 if (row > 0)
214 if (row > 0)
215 difference = (int)((qAbs(m_data[i]->at(k) - m_data[row - 1]->at(k)))/count);
215 difference = (int)((qAbs(m_data[i]->at(k) - m_data[row - 1]->at(k)))/count);
216 else
216 else
217 difference = (int)((qAbs(m_data[i]->at(k)/count)));
217 difference = (int)((qAbs(m_data[i]->at(k)/count)));
218 dataVec->replace(k, m_data[i - 1]->at(k) + qrand()%qMax(1, difference));
218 dataVec->replace(k, m_data[i - 1]->at(k) + qrand()%qMax(1, difference));
219 }
219 }
220 else
220 else
221 dataVec->replace(k, qrand()%40 + 10);
221 dataVec->replace(k, qrand()%40 + 10);
222 }
222 }
223 else
223 else
224 {
224 {
225 if (i - 1 >= 0)
225 if (i - 1 >= 0)
226 {
226 {
227 dataVec->replace(k, m_data[i - 1]->at(k) + qrand()%40 + 10);
227 dataVec->replace(k, m_data[i - 1]->at(k) + qrand()%40 + 10);
228 }
228 }
229 else
229 else
230 {
230 {
231 dataVec->replace(k, qrand()%40 + 10);
231 dataVec->replace(k, qrand()%40 + 10);
232 }
232 }
233 }
233 }
234 }
234 }
235 else
235 else
236 dataVec->replace(k, qrand()%100);
236 dataVec->replace(k, qrand()%100);
237 colorVec->replace(k, QColor(Qt::white));
237 colorVec->replace(k, QColor(Qt::white));
238 }
238 }
239 m_data.insert(i, dataVec);
239 m_data.insert(i, dataVec);
240 m_labels.insert(i,(QString("Row: %1").arg(i + 1)));
240 m_labels.insert(i,(QString("Row: %1").arg(i + 1)));
241 // m_rowsColors.insert(i, colorVec);
241 // m_rowsColors.insert(i, colorVec);
242 }
242 }
243 endInsertRows();
243 endInsertRows();
244 return true;
244 return true;
245 }
245 }
246
246
247 bool CustomTableModel::removeRows ( int row, int count, const QModelIndex & parent)
247 bool CustomTableModel::removeRows ( int row, int count, const QModelIndex & parent)
248 {
248 {
249 if (row > this->rowCount() - 1)
249 if (row > this->rowCount() - 1)
250 return false;
250 return false;
251 if (row < 0)
251 if (row < 0)
252 row = 0;
252 row = 0;
253 if (row + count > rowCount())
253 if (row + count > rowCount())
254 return false;
254 return false;
255 beginRemoveRows(parent, row, row + count - 1);
255 beginRemoveRows(parent, row, row + count - 1);
256 for (int i = row; i < row + count; i++)
256 for (int i = row; i < row + count; i++)
257 {
257 {
258 // m_points.removeAt(row);
258 // m_points.removeAt(row);
259 QVector<qreal>* item = m_data.at(row);
259 QVector<qreal>* item = m_data.at(row);
260 m_data.removeAt(row);
260 m_data.removeAt(row);
261 delete item;
261 delete item;
262 m_labels.removeAt(row);
262 m_labels.removeAt(row);
263 }
263 }
264 endRemoveRows();
264 endRemoveRows();
265 return true;
265 return true;
266 }
266 }
267
267
268 void CustomTableModel::addMapping(QString color, QRect area)
268 void CustomTableModel::addMapping(QString color, QRect area)
269 {
269 {
270 m_mapping.insertMulti(color, area);
270 m_mapping.insertMulti(color, area);
271 }
271 }
272
272
273 void CustomTableModel::addMapping(QString color, int left, int top, int right, int bottom)
273 void CustomTableModel::addMapping(QString color, int left, int top, int right, int bottom)
274 {
274 {
275 addMapping(color, QRect(QPoint(left, top), QPoint(right, bottom)));
275 addMapping(color, QRect(QPoint(left, top), QPoint(right, bottom)));
276 }
276 }
@@ -1,342 +1,375
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "tablewidget.h"
21 #include "tablewidget.h"
22 #include <QGridLayout>
22 #include <QGridLayout>
23 #include <QTableView>
23 #include <QTableView>
24 #include <QChart>
24 #include <QStyledItemDelegate>
25 #include <QStyledItemDelegate>
25 #include <QLineSeries>
26 #include <QLineSeries>
26 #include <QSplineSeries>
27 #include <QSplineSeries>
27 #include <QScatterSeries>
28 #include <QScatterSeries>
28 #include "customtablemodel.h"
29 #include "customtablemodel.h"
29 #include <QPieSeries>
30 #include <QPieSeries>
30 #include <QPieSlice>
31 #include <QPieSlice>
31 #include <QAreaSeries>
32 #include <QAreaSeries>
32 #include <QBarSeries>
33 #include <QBarSeries>
33 #include <QBarSet>
34 #include <QBarSet>
34 #include <QPushButton>
35 #include <QPushButton>
35 #include <QRadioButton>
36 #include <QRadioButton>
36 #include <QLabel>
37 #include <QLabel>
37 #include <QSpinBox>
38 #include <QSpinBox>
38 #include <QTime>
39 #include <QTime>
39
40
40 TableWidget::TableWidget(QWidget *parent)
41 TableWidget::TableWidget(QWidget *parent)
41 : QWidget(parent)
42 : QWidget(parent),specialPie(0)
42 {
43 {
43 setGeometry(100, 100, 1000, 600);
44 setGeometry(1900, 100, 1000, 600);
44 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
45 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
45 // create simple model for storing data
46 // create simple model for storing data
46 // user's table data model
47 // user's table data model
47 m_model = new CustomTableModel;
48 m_model = new CustomTableModel;
48 m_tableView = new QTableView;
49 m_tableView = new QTableView;
49 m_tableView->setModel(m_model);
50 m_tableView->setModel(m_model);
50 m_tableView->setMinimumHeight(300);
51 m_tableView->setMinimumHeight(300);
51 // tableView->setMinimumSize(340, 480);
52 // tableView->setMinimumSize(340, 480);
52 // tableView->setItemDelegate(new QStyledItemDelegate);
53 // tableView->setItemDelegate(new QStyledItemDelegate);
53 m_chart = new QChart;
54 m_chart = new QChart;
54 m_chart->legend()->setVisible(true);
55 m_chart->legend()->setVisible(true);
55 // m_chart->setAnimationOptions(QChart::SeriesAnimations);
56 m_chart->setAnimationOptions(QChart::SeriesAnimations);
56 m_chartView = new QChartView(m_chart);
57 m_chartView = new QChartView(m_chart);
57 m_chartView->setRenderHint(QPainter::Antialiasing);
58 m_chartView->setRenderHint(QPainter::Antialiasing);
58 m_chartView->setMinimumSize(640, 480);
59 m_chartView->setMinimumSize(640, 480);
59
60
60 // add, remove data buttons
61 // add, remove data buttons
61 QPushButton* addRowAboveButton = new QPushButton("Add row above");
62 QPushButton* addRowAboveButton = new QPushButton("Add row above");
62 connect(addRowAboveButton, SIGNAL(clicked()), this, SLOT(addRowAbove()));
63 connect(addRowAboveButton, SIGNAL(clicked()), this, SLOT(addRowAbove()));
63
64
64 QPushButton* addRowBelowButton = new QPushButton("Add row below");
65 QPushButton* addRowBelowButton = new QPushButton("Add row below");
65 connect(addRowBelowButton, SIGNAL(clicked()), this, SLOT(addRowBelow()));
66 connect(addRowBelowButton, SIGNAL(clicked()), this, SLOT(addRowBelow()));
66
67
67 QPushButton* removeRowButton = new QPushButton("Remove row");
68 QPushButton* removeRowButton = new QPushButton("Remove row");
68 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
69 connect(removeRowButton, SIGNAL(clicked()), this, SLOT(removeRow()));
69
70
71 QPushButton* specialPieButton = new QPushButton("Test pie");
72 connect(specialPieButton, SIGNAL(clicked()), this, SLOT(testPie()));
73
74
70 QLabel *spinBoxLabel = new QLabel("Rows affected:");
75 QLabel *spinBoxLabel = new QLabel("Rows affected:");
71
76
72 // spin box for setting number of affected items (add, remove)
77 // spin box for setting number of affected items (add, remove)
73 m_linesCountSpinBox = new QSpinBox;
78 m_linesCountSpinBox = new QSpinBox;
74 m_linesCountSpinBox->setRange(1, 10);
79 m_linesCountSpinBox->setRange(1, 10);
75 m_linesCountSpinBox->setValue(1);
80 m_linesCountSpinBox->setValue(1);
76
81
77 // buttons layout
82 // buttons layout
78 QVBoxLayout* buttonsLayout = new QVBoxLayout;
83 QVBoxLayout* buttonsLayout = new QVBoxLayout;
79 buttonsLayout->addWidget(spinBoxLabel);
84 buttonsLayout->addWidget(spinBoxLabel);
80 buttonsLayout->addWidget(m_linesCountSpinBox);
85 buttonsLayout->addWidget(m_linesCountSpinBox);
81 buttonsLayout->addWidget(addRowAboveButton);
86 buttonsLayout->addWidget(addRowAboveButton);
82 buttonsLayout->addWidget(addRowBelowButton);
87 buttonsLayout->addWidget(addRowBelowButton);
83 buttonsLayout->addWidget(removeRowButton);
88 buttonsLayout->addWidget(removeRowButton);
89 buttonsLayout->addWidget(specialPieButton);
84 buttonsLayout->addStretch();
90 buttonsLayout->addStretch();
85
91
86 // chart type radio buttons
92 // chart type radio buttons
87 m_lineRadioButton = new QRadioButton("Line");
93 m_lineRadioButton = new QRadioButton("Line");
88 m_splineRadioButton = new QRadioButton("Spline");
94 m_splineRadioButton = new QRadioButton("Spline");
89 m_scatterRadioButton = new QRadioButton("Scatter");
95 m_scatterRadioButton = new QRadioButton("Scatter");
90 m_pieRadioButton = new QRadioButton("Pie");
96 m_pieRadioButton = new QRadioButton("Pie");
91 m_areaRadioButton = new QRadioButton("Area");
97 m_areaRadioButton = new QRadioButton("Area");
92 m_barRadioButton = new QRadioButton("Bar");
98 m_barRadioButton = new QRadioButton("Bar");
93
99
94 connect(m_lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
100 connect(m_lineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
95 connect(m_splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
101 connect(m_splineRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
96 connect(m_scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
102 connect(m_scatterRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
97 connect(m_pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
103 connect(m_pieRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
98 connect(m_areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
104 connect(m_areaRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
99 connect(m_barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
105 connect(m_barRadioButton, SIGNAL(toggled(bool)), this, SLOT(updateChartType(bool)));
100 m_lineRadioButton->setChecked(true);
106 m_lineRadioButton->setChecked(true);
101
107
102 // radio buttons layout
108 // radio buttons layout
103 QVBoxLayout* radioLayout = new QVBoxLayout;
109 QVBoxLayout* radioLayout = new QVBoxLayout;
104 radioLayout->addWidget(m_lineRadioButton);
110 radioLayout->addWidget(m_lineRadioButton);
105 radioLayout->addWidget(m_splineRadioButton);
111 radioLayout->addWidget(m_splineRadioButton);
106 radioLayout->addWidget(m_scatterRadioButton);
112 radioLayout->addWidget(m_scatterRadioButton);
107 radioLayout->addWidget(m_pieRadioButton);
113 radioLayout->addWidget(m_pieRadioButton);
108 radioLayout->addWidget(m_areaRadioButton);
114 radioLayout->addWidget(m_areaRadioButton);
109 radioLayout->addWidget(m_barRadioButton);
115 radioLayout->addWidget(m_barRadioButton);
110 radioLayout->addStretch();
116 radioLayout->addStretch();
111
117
112 // create main layout
118 // create main layout
113 QGridLayout* mainLayout = new QGridLayout;
119 QGridLayout* mainLayout = new QGridLayout;
114 mainLayout->addLayout(buttonsLayout, 1, 1);
120 mainLayout->addLayout(buttonsLayout, 1, 1);
115 mainLayout->addLayout(radioLayout, 2, 1);
121 mainLayout->addLayout(radioLayout, 2, 1);
116 mainLayout->addWidget(m_tableView, 1, 0);
122 mainLayout->addWidget(m_tableView, 1, 0);
117 mainLayout->addWidget(m_chartView, 2, 0);
123 mainLayout->addWidget(m_chartView, 2, 0);
118 setLayout(mainLayout);
124 setLayout(mainLayout);
119 m_lineRadioButton->setFocus();
125 m_lineRadioButton->setFocus();
120 }
126 }
121
127
122 void TableWidget::addRowAbove()
128 void TableWidget::addRowAbove()
123 {
129 {
124 m_model->insertRows(m_tableView->currentIndex().row(), m_linesCountSpinBox->value());
130 m_model->insertRows(m_tableView->currentIndex().row(), m_linesCountSpinBox->value());
125
131
126 }
132 }
127
133
128 void TableWidget::addRowBelow()
134 void TableWidget::addRowBelow()
129 {
135 {
130 m_model->insertRows(m_tableView->currentIndex().row() + 1, m_linesCountSpinBox->value());
136 m_model->insertRows(m_tableView->currentIndex().row() + 1, m_linesCountSpinBox->value());
131
137
132 }
138 }
133
139
134 void TableWidget::removeRow()
140 void TableWidget::removeRow()
135 {
141 {
136 m_model->removeRows(m_tableView->currentIndex().row(), qMin(m_model->rowCount() - m_tableView->currentIndex().row(), m_linesCountSpinBox->value()));
142 m_model->removeRows(m_tableView->currentIndex().row(), qMin(m_model->rowCount() - m_tableView->currentIndex().row(), m_linesCountSpinBox->value()));
137 }
143 }
138
144
139 void TableWidget::updateChartType(bool toggle)
145 void TableWidget::updateChartType(bool toggle)
140 {
146 {
141 // this if is needed, so that the function is only called once.
147 // this if is needed, so that the function is only called once.
142 // For the radioButton that was enabled.
148 // For the radioButton that was enabled.
143 if (toggle) {
149 if (toggle) {
150 specialPie = 0;
144 m_chart->removeAllSeries();
151 m_chart->removeAllSeries();
145 m_chart->axisX()->setNiceNumbersEnabled(false);
152 m_chart->axisX()->setNiceNumbersEnabled(false);
146 m_chart->axisY()->setNiceNumbersEnabled(false);
153 m_chart->axisY()->setNiceNumbersEnabled(false);
147
154
148 // renable axes of the chart (pie hides them)
155 // renable axes of the chart (pie hides them)
149 // x axis
156 // x axis
150 QAxis *axis = m_chart->axisX();
157 QAxis *axis = m_chart->axisX();
151 axis->setAxisVisible(true);
158 axis->setAxisVisible(true);
152 axis->setGridLineVisible(true);
159 axis->setGridLineVisible(true);
153 axis->setLabelsVisible(true);
160 axis->setLabelsVisible(true);
154
161
155 // y axis
162 // y axis
156 axis = m_chart->axisY();
163 axis = m_chart->axisY();
157 axis->setAxisVisible(true);
164 axis->setAxisVisible(true);
158 axis->setGridLineVisible(true);
165 axis->setGridLineVisible(true);
159 axis->setLabelsVisible(true);
166 axis->setLabelsVisible(true);
160
167
161 m_model->clearMapping();
168 m_model->clearMapping();
162
169
163 QString seriesColorHex = "#000000";
170 QString seriesColorHex = "#000000";
164 QPen pen;
171 QPen pen;
165 pen.setWidth(2);
172 pen.setWidth(2);
166
173
167 if (m_lineRadioButton->isChecked())
174 if (m_lineRadioButton->isChecked())
168 {
175 {
169 // series 1
176 // series 1
170 m_series = new QLineSeries;
177 m_series = new QLineSeries;
171 m_series->setModel(m_model);
178 m_series->setModel(m_model);
172 m_series->setModelMapping(0,1, Qt::Vertical);
179 m_series->setModelMapping(0,1, Qt::Vertical);
173 m_series->setModelMappingRange(4, 4);
180 m_series->setModelMappingRange(4, 4);
174 m_chart->addSeries(m_series);
181 m_chart->addSeries(m_series);
175 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
182 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
176 m_model->addMapping(seriesColorHex, QRect(0, 4, 2, 4));
183 m_model->addMapping(seriesColorHex, QRect(0, 4, 2, 4));
177
184
178 // series 2
185 // series 2
179 m_series = new QLineSeries;
186 m_series = new QLineSeries;
180 m_series->setModel(m_model);
187 m_series->setModel(m_model);
181 m_series->setModelMapping(2,3, Qt::Vertical);
188 m_series->setModelMapping(2,3, Qt::Vertical);
182 m_chart->addSeries(m_series);
189 m_chart->addSeries(m_series);
183 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
190 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
184 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
191 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
185
192
186 // series 3
193 // series 3
187 m_series = new QLineSeries;
194 m_series = new QLineSeries;
188 m_series->setModel(m_model);
195 m_series->setModel(m_model);
189 m_series->setModelMapping(4,5, Qt::Vertical);
196 m_series->setModelMapping(4,5, Qt::Vertical);
190 m_series->setModelMappingRange(2, -1);
197 m_series->setModelMappingRange(2, -1);
191 m_chart->addSeries(m_series);
198 m_chart->addSeries(m_series);
192 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
199 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
193 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
200 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
194 }
201 }
195 else if (m_splineRadioButton->isChecked())
202 else if (m_splineRadioButton->isChecked())
196 {
203 {
197 // series 1
204 // series 1
198 m_series = new QSplineSeries;
205 m_series = new QSplineSeries;
199 m_series->setModel(m_model);
206 m_series->setModel(m_model);
200 m_series->setModelMapping(0,1, Qt::Vertical);
207 m_series->setModelMapping(0,1, Qt::Vertical);
201 // m_series->setModelMappingRange(1, 4);
208 // m_series->setModelMappingRange(1, 4);
202 // series->setModelMapping(0,1, Qt::Horizontal);
209 // series->setModelMapping(0,1, Qt::Horizontal);
203 m_chart->addSeries(m_series);
210 m_chart->addSeries(m_series);
204 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
211 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
205 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 4));
212 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 4));
206
213
207 // series 2
214 // series 2
208 m_series = new QSplineSeries;
215 m_series = new QSplineSeries;
209 m_series->setModel(m_model);
216 m_series->setModel(m_model);
210 m_series->setModelMapping(2,3, Qt::Vertical);
217 m_series->setModelMapping(2,3, Qt::Vertical);
211 // m_series->setModelMappingRange(0, 0);
218 // m_series->setModelMappingRange(0, 0);
212 // series->setModelMapping(2,3, Qt::Horizontal);
219 // series->setModelMapping(2,3, Qt::Horizontal);
213 m_chart->addSeries(m_series);
220 m_chart->addSeries(m_series);
214 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
221 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
215 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
222 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
216
223
217 // series 3
224 // series 3
218 m_series = new QSplineSeries;
225 m_series = new QSplineSeries;
219 m_series->setModel(m_model);
226 m_series->setModel(m_model);
220 m_series->setModelMapping(4,5, Qt::Vertical);
227 m_series->setModelMapping(4,5, Qt::Vertical);
221 // m_series->setModelMappingRange(2, 0);
228 // m_series->setModelMappingRange(2, 0);
222 // series->setModelMapping(4,5, Qt::Horizontal);
229 // series->setModelMapping(4,5, Qt::Horizontal);
223 m_chart->addSeries(m_series);
230 m_chart->addSeries(m_series);
224 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
231 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
225 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
232 m_model->addMapping(seriesColorHex, QRect(4, 2, 2, 1000));
226 }
233 }
227 else if (m_scatterRadioButton->isChecked())
234 else if (m_scatterRadioButton->isChecked())
228 {
235 {
229 // series 1
236 // series 1
230 m_series = new QScatterSeries;
237 m_series = new QScatterSeries;
231 m_series->setModel(m_model);
238 m_series->setModel(m_model);
232 m_series->setModelMapping(0,1, Qt::Vertical);
239 m_series->setModelMapping(0,1, Qt::Vertical);
233 // m_series->setModelMappingRange(2, 0);
240 // m_series->setModelMappingRange(2, 0);
234 // series->setModelMapping(0,1, Qt::Horizontal);
241 // series->setModelMapping(0,1, Qt::Horizontal);
235 m_chart->addSeries(m_series);
242 m_chart->addSeries(m_series);
236
243
237 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
244 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
238 m_model->addMapping(seriesColorHex, QRect(0, 2, 2, 1000));
245 m_model->addMapping(seriesColorHex, QRect(0, 2, 2, 1000));
239
246
240 // series 2
247 // series 2
241 m_series = new QScatterSeries;
248 m_series = new QScatterSeries;
242 m_series->setModel(m_model);
249 m_series->setModel(m_model);
243 m_series->setModelMapping(2,3, Qt::Vertical);
250 m_series->setModelMapping(2,3, Qt::Vertical);
244 // m_series->setModelMappingRange(1, 6);
251 // m_series->setModelMappingRange(1, 6);
245 // series->setModelMapping(2,3, Qt::Horizontal);
252 // series->setModelMapping(2,3, Qt::Horizontal);
246 m_chart->addSeries(m_series);
253 m_chart->addSeries(m_series);
247
254
248 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
255 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
249 m_model->addMapping(seriesColorHex, QRect(2, 1, 2, 6));
256 m_model->addMapping(seriesColorHex, QRect(2, 1, 2, 6));
250
257
251 // series 3
258 // series 3
252 m_series = new QScatterSeries;
259 m_series = new QScatterSeries;
253 m_series->setModel(m_model);
260 m_series->setModel(m_model);
254 m_series->setModelMapping(4,5, Qt::Vertical);
261 m_series->setModelMapping(4,5, Qt::Vertical);
255 // series->setModelMapping(4,5, Qt::Horizontal);
262 // series->setModelMapping(4,5, Qt::Horizontal);
256 m_chart->addSeries(m_series);
263 m_chart->addSeries(m_series);
257 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
264 seriesColorHex = "#" + QString::number(m_series->brush().color().rgb(), 16).right(6).toUpper();
258 m_model->addMapping(seriesColorHex, QRect(4, 0, 2, 1000));
265 m_model->addMapping(seriesColorHex, QRect(4, 0, 2, 1000));
259 }
266 }
260 else if (m_pieRadioButton->isChecked())
267 else if (m_pieRadioButton->isChecked())
261 {
268 {
262 // pie 1
269 // pie 1
263 QPieSeries* pieSeries = new QPieSeries;
270 QPieSeries* pieSeries = new QPieSeries;
264 pieSeries->setModel(m_model);
271 pieSeries->setModel(m_model);
272 pieSeries->setModelMappingRange(3, 3);
265 pieSeries->setModelMapping(0,0, Qt::Vertical);
273 pieSeries->setModelMapping(0,0, Qt::Vertical);
266 pieSeries->setLabelsVisible(true);
274 pieSeries->setLabelsVisible(true);
267 pieSeries->setPieSize(0.4);
275 pieSeries->setPieSize(0.35);
268 pieSeries->setHorizontalPosition(0.2);
276 pieSeries->setHorizontalPosition(0.2);
269 pieSeries->setVerticalPosition(0.35);
277 pieSeries->setVerticalPosition(0.3);
270
278
271 m_chart->addSeries(pieSeries);
279 m_chart->addSeries(pieSeries);
272 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
280 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
273 m_model->addMapping(seriesColorHex, QRect(0, 0, 1, 1000));
281 m_model->addMapping(seriesColorHex, QRect(0, 3, 1, 3));
274
282
275 // pie 2
283 // pie 2
276 pieSeries = new QPieSeries;
284 pieSeries = new QPieSeries;
277 pieSeries->setModel(m_model);
285 pieSeries->setModel(m_model);
286 pieSeries->setModelMappingRange(2, -1);
278 pieSeries->setModelMapping(1,1, Qt::Vertical);
287 pieSeries->setModelMapping(1,1, Qt::Vertical);
279 pieSeries->setLabelsVisible(true);
288 pieSeries->setLabelsVisible(true);
280 pieSeries->setPieSize(0.4);
289 pieSeries->setPieSize(0.35);
281 pieSeries->setHorizontalPosition(0.8);
290 pieSeries->setHorizontalPosition(0.8);
282 pieSeries->setVerticalPosition(0.35);
291 pieSeries->setVerticalPosition(0.3);
283 m_chart->addSeries(pieSeries);
292 m_chart->addSeries(pieSeries);
284 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
293 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
285 m_model->addMapping(seriesColorHex, QRect(1, 0, 1, 1000));
294 m_model->addMapping(seriesColorHex, QRect(1, 2, 1, 1000));
286
295
287 // pie 3
296 // pie 3
288 pieSeries = new QPieSeries;
297 pieSeries = new QPieSeries;
289 pieSeries->setModel(m_model);
298 pieSeries->setModel(m_model);
290 pieSeries->setModelMapping(2,2, Qt::Vertical);
299 pieSeries->setModelMapping(2,2, Qt::Vertical);
291 pieSeries->setLabelsVisible(true);
300 pieSeries->setLabelsVisible(true);
292 pieSeries->setPieSize(0.4);
301 pieSeries->setPieSize(0.35);
293 pieSeries->setHorizontalPosition(0.5);
302 pieSeries->setHorizontalPosition(0.2);
294 pieSeries->setVerticalPosition(0.65);
303 pieSeries->setVerticalPosition(0.75);
295 m_chart->addSeries(pieSeries);
304 m_chart->addSeries(pieSeries);
296 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
305 seriesColorHex = "#" + QString::number(pieSeries->slices().at(pieSeries->slices().count()/2)->brush().color().rgb(), 16).right(6).toUpper();
297 m_model->addMapping(seriesColorHex, QRect(2, 0, 1, 1000));
306 m_model->addMapping(seriesColorHex, QRect(2, 0, 1, 1000));
307
308 // special pie
309 specialPie = new QPieSeries;
310 specialPie->append(17, "1");
311 specialPie->append(45, "2");
312 specialPie->append(77, "3");
313 specialPie->append(37, "4");
314 specialPie->append(27, "5");
315 specialPie->append(47, "6");
316 specialPie->setPieSize(0.35);
317 specialPie->setHorizontalPosition(0.8);
318 specialPie->setVerticalPosition(0.75);
319 specialPie->setLabelsVisible(true);
320 m_chart->addSeries(specialPie);
298 }
321 }
299 else if (m_areaRadioButton->isChecked())
322 else if (m_areaRadioButton->isChecked())
300 {
323 {
301 QLineSeries* upperLineSeries = new QLineSeries;
324 QLineSeries* upperLineSeries = new QLineSeries;
302 upperLineSeries->setModel(m_model);
325 upperLineSeries->setModel(m_model);
303 upperLineSeries->setModelMapping(0, 1, Qt::Vertical);
326 upperLineSeries->setModelMapping(0, 1, Qt::Vertical);
304 // upperLineSeries->setModelMappingRange(1, 5);
327 // upperLineSeries->setModelMappingRange(1, 5);
305 QLineSeries* lowerLineSeries = new QLineSeries;
328 QLineSeries* lowerLineSeries = new QLineSeries;
306 lowerLineSeries->setModel(m_model);
329 lowerLineSeries->setModel(m_model);
307 lowerLineSeries->setModelMapping(2, 3, Qt::Vertical);
330 lowerLineSeries->setModelMapping(2, 3, Qt::Vertical);
308 QAreaSeries* areaSeries = new QAreaSeries(upperLineSeries, lowerLineSeries);
331 QAreaSeries* areaSeries = new QAreaSeries(upperLineSeries, lowerLineSeries);
309 m_chart->addSeries(areaSeries);
332 m_chart->addSeries(areaSeries);
310 seriesColorHex = "#" + QString::number(areaSeries->brush().color().rgb(), 16).right(6).toUpper();
333 seriesColorHex = "#" + QString::number(areaSeries->brush().color().rgb(), 16).right(6).toUpper();
311 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 5));
334 m_model->addMapping(seriesColorHex, QRect(0, 1, 2, 5));
312 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
335 m_model->addMapping(seriesColorHex, QRect(2, 0, 2, 1000));
313 }
336 }
314 else if (m_barRadioButton->isChecked())
337 else if (m_barRadioButton->isChecked())
315 {
338 {
316 QBarSeries* barSeries = new QBarSeries(QStringList());
339 QBarSeries* barSeries = new QBarSeries(QStringList());
317 barSeries->setModel(m_model);
340 barSeries->setModel(m_model);
341 // barSeries->setModelMappingRange(2, 5);
318 barSeries->setModelMapping(5, 2, 4, Qt::Vertical);
342 barSeries->setModelMapping(5, 2, 4, Qt::Vertical);
319 m_chart->addSeries(barSeries);
343 m_chart->addSeries(barSeries);
320 QList<QBarSet*> barsets = barSeries->barSets();
344 QList<QBarSet*> barsets = barSeries->barSets();
321 for (int i = 0; i < barsets.count(); i++) {
345 for (int i = 0; i < barsets.count(); i++) {
322 seriesColorHex = "#" + QString::number(barsets.at(i)->brush().color().rgb(), 16).right(6).toUpper();
346 seriesColorHex = "#" + QString::number(barsets.at(i)->brush().color().rgb(), 16).right(6).toUpper();
323 m_model->addMapping(seriesColorHex, QRect(2 + i, 0, 1, 1000));
347 m_model->addMapping(seriesColorHex, QRect(2 + i, 0, 1, 1000));
324 }
348 }
325 }
349 }
326
350
327
351
328 if (!m_barRadioButton->isChecked())
352 if (!m_barRadioButton->isChecked())
329 m_chart->axisX()->setRange(0, 500);
353 m_chart->axisX()->setRange(0, 500);
330 m_chart->axisY()->setRange(0, 120);
354 // m_chart->axisY()->setRange(0, 120);
331 m_chart->legend()->setVisible(true);
355 m_chart->legend()->setVisible(true);
332
356
333 // repaint table view colors
357 // repaint table view colors
334 m_tableView->repaint();
358 m_tableView->repaint();
335 m_tableView->setFocus();
359 m_tableView->setFocus();
336 }
360 }
337 }
361 }
338
362
363 void TableWidget::testPie()
364 {
365 if (specialPie) {
366 specialPie->remove(specialPie->slices().at(2));
367 // specialPie->insert(4, new QPieSlice(45, "Hello"));//specialPie->slices.at(2));
368 specialPie->append(4, "heloo");
369 }
370 }
371
339 TableWidget::~TableWidget()
372 TableWidget::~TableWidget()
340 {
373 {
341
374
342 }
375 }
@@ -1,65 +1,69
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef TABLEWIDGET_H
21 #ifndef TABLEWIDGET_H
22 #define TABLEWIDGET_H
22 #define TABLEWIDGET_H
23
23
24 #include <QtGui/QWidget>
24 #include <QtGui/QWidget>
25 //#include <QChartGlobal>
25 #include "qchartview.h"
26 #include "qchartview.h"
26 #include "qxyseries.h"
27 //#include "qxyseries.h"
27
28 //#include <QPieSeries>
28 QTCOMMERCIALCHART_USE_NAMESPACE
29
29
30 class CustomTableModel;
30 class CustomTableModel;
31 class QTableView;
31 class QTableView;
32 class QRadioButton;
32 class QRadioButton;
33 class QSpinBox;
33 class QSpinBox;
34
34
35 QTCOMMERCIALCHART_USE_NAMESPACE
36
35 class TableWidget : public QWidget
37 class TableWidget : public QWidget
36 {
38 {
37 Q_OBJECT
39 Q_OBJECT
38
40
39 public:
41 public:
40 TableWidget(QWidget *parent = 0);
42 TableWidget(QWidget *parent = 0);
41 ~TableWidget();
43 ~TableWidget();
42
44
43
45
44 public slots:
46 public slots:
45 void addRowAbove();
47 void addRowAbove();
46 void addRowBelow();
48 void addRowBelow();
47 void removeRow();
49 void removeRow();
48 void updateChartType(bool toggle);
50 void updateChartType(bool toggle);
51 void testPie();
49
52
50 private:
53 private:
51 QChartView* m_chartView;
54 QChartView* m_chartView;
52 QChart* m_chart;
55 QChart* m_chart;
53 QXYSeries* m_series;
56 QXYSeries* m_series;
54 CustomTableModel* m_model;
57 CustomTableModel* m_model;
55 QTableView* m_tableView;
58 QTableView* m_tableView;
56 QRadioButton* m_lineRadioButton;
59 QRadioButton* m_lineRadioButton;
57 QRadioButton* m_splineRadioButton;
60 QRadioButton* m_splineRadioButton;
58 QRadioButton* m_scatterRadioButton;
61 QRadioButton* m_scatterRadioButton;
59 QRadioButton* m_pieRadioButton;
62 QRadioButton* m_pieRadioButton;
60 QRadioButton* m_areaRadioButton;
63 QRadioButton* m_areaRadioButton;
61 QRadioButton* m_barRadioButton;
64 QRadioButton* m_barRadioButton;
62 QSpinBox* m_linesCountSpinBox;
65 QSpinBox* m_linesCountSpinBox;
66 QPieSeries* specialPie;
63 };
67 };
64
68
65 #endif // TABLEWIDGET_H
69 #endif // TABLEWIDGET_H
General Comments 0
You need to be logged in to leave comments. Login now