##// END OF EJS Templates
Fixed: QAbstractItemModel could be forward declaration
Marek Rosa -
r862:203182eed8aa
parent child
Show More
@@ -1,444 +1,445
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 <QDebug>
21 #include <QDebug>
22 #include "qbarseries.h"
22 #include "qbarseries.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "barchartmodel_p.h"
24 #include "barchartmodel_p.h"
25 #include <QAbstractItemModel>
25
26
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
28
28 /*!
29 /*!
29 \class QBarSeries
30 \class QBarSeries
30 \brief part of QtCommercial chart API.
31 \brief part of QtCommercial chart API.
31
32
32 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
33 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
33 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
34 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
34 by QStringList.
35 by QStringList.
35
36
36 \mainclass
37 \mainclass
37
38
38 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
39 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
39 */
40 */
40
41
41 /*!
42 /*!
42 \fn virtual QSeriesType QBarSeries::type() const
43 \fn virtual QSeriesType QBarSeries::type() const
43 \brief Returns type of series.
44 \brief Returns type of series.
44 \sa QSeries, QSeriesType
45 \sa QSeries, QSeriesType
45 */
46 */
46
47
47 /*!
48 /*!
48 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
49 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
49 \brief \internal \a pos \a tip
50 \brief \internal \a pos \a tip
50 */
51 */
51
52
52 /*!
53 /*!
53 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
54 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
54 QBarSeries is QObject which is a child of a \a parent.
55 QBarSeries is QObject which is a child of a \a parent.
55 */
56 */
56 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) : QSeries(parent),
57 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) : QSeries(parent),
57 m_internalModel(new BarChartModel(categories, this))
58 m_internalModel(new BarChartModel(categories, this))
58 {
59 {
59 m_model = 0;
60 m_model = 0;
60 m_mapCategories = -1;
61 m_mapCategories = -1;
61 m_mapBarBottom = -1;
62 m_mapBarBottom = -1;
62 m_mapBarTop = -1;
63 m_mapBarTop = -1;
63 m_mapFirst = 0;
64 m_mapFirst = 0;
64 m_mapCount = 0;
65 m_mapCount = 0;
65 m_mapOrientation = Qt::Vertical;
66 m_mapOrientation = Qt::Vertical;
66 }
67 }
67
68
68 /*!
69 /*!
69 Adds a set of bars to series. Takes ownership of \a set.
70 Adds a set of bars to series. Takes ownership of \a set.
70 Connects the clicked(QString, Qt::MouseButtons) signal
71 Connects the clicked(QString, Qt::MouseButtons) signal
71 of \a set to this series
72 of \a set to this series
72 */
73 */
73 void QBarSeries::appendBarSet(QBarSet *set)
74 void QBarSeries::appendBarSet(QBarSet *set)
74 {
75 {
75 m_internalModel->appendBarSet(set);
76 m_internalModel->appendBarSet(set);
76 connect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
77 connect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
77 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
78 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
78 emit restructuredBars();
79 emit restructuredBars();
79 }
80 }
80
81
81 /*!
82 /*!
82 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
83 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
83 Disconnects the clicked(QString, Qt::MouseButtons) signal
84 Disconnects the clicked(QString, Qt::MouseButtons) signal
84 of \a set from this series
85 of \a set from this series
85 */
86 */
86 void QBarSeries::removeBarSet(QBarSet *set)
87 void QBarSeries::removeBarSet(QBarSet *set)
87 {
88 {
88 disconnect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
89 disconnect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
89 m_internalModel->removeBarSet(set);
90 m_internalModel->removeBarSet(set);
90 emit restructuredBars();
91 emit restructuredBars();
91 }
92 }
92
93
93 /*!
94 /*!
94 Adds a list of barsets to series. Takes ownership of \a sets.
95 Adds a list of barsets to series. Takes ownership of \a sets.
95 Connects the clicked(QString, Qt::MouseButtons) signals
96 Connects the clicked(QString, Qt::MouseButtons) signals
96 of \a sets to this series
97 of \a sets to this series
97 */
98 */
98 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
99 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
99 {
100 {
100 foreach (QBarSet* barset, sets) {
101 foreach (QBarSet* barset, sets) {
101 m_internalModel->appendBarSet(barset);
102 m_internalModel->appendBarSet(barset);
102 connect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
103 connect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
103 connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
104 connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
104 }
105 }
105 emit restructuredBars();
106 emit restructuredBars();
106 }
107 }
107
108
108 /*!
109 /*!
109 Removes a list of barsets from series. Releases ownership of \a set. Doesnt delete \a sets.
110 Removes a list of barsets from series. Releases ownership of \a set. Doesnt delete \a sets.
110 Disconnects the clicked(QString, Qt::MouseButtons) signal
111 Disconnects the clicked(QString, Qt::MouseButtons) signal
111 of \a sets from this series
112 of \a sets from this series
112 */
113 */
113 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
114 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
114 {
115 {
115 foreach (QBarSet* barset, sets) {
116 foreach (QBarSet* barset, sets) {
116 disconnect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
117 disconnect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
117 m_internalModel->removeBarSet(barset);
118 m_internalModel->removeBarSet(barset);
118 }
119 }
119 emit restructuredBars();
120 emit restructuredBars();
120 }
121 }
121
122
122 void QBarSeries::insertBarSet(int i, QBarSet *set)
123 void QBarSeries::insertBarSet(int i, QBarSet *set)
123 {
124 {
124 m_internalModel->insertBarSet(i, set);
125 m_internalModel->insertBarSet(i, set);
125 // emit barsetChanged();
126 // emit barsetChanged();
126 }
127 }
127
128
128 void QBarSeries::insertCategory(int i, QString category)
129 void QBarSeries::insertCategory(int i, QString category)
129 {
130 {
130 m_internalModel->insertCategory(i, category);
131 m_internalModel->insertCategory(i, category);
131 }
132 }
132
133
133 void QBarSeries::removeCategory(int i)
134 void QBarSeries::removeCategory(int i)
134 {
135 {
135 m_internalModel->removeCategory(i);
136 m_internalModel->removeCategory(i);
136 }
137 }
137
138
138 /*!
139 /*!
139 Returns number of sets in series.
140 Returns number of sets in series.
140 */
141 */
141 int QBarSeries::barsetCount() const
142 int QBarSeries::barsetCount() const
142 {
143 {
143 // if(m_model)
144 // if(m_model)
144 // return m_mapBarTop - m_mapBarBottom;
145 // return m_mapBarTop - m_mapBarBottom;
145 // else
146 // else
146 return m_internalModel->barsetCount();
147 return m_internalModel->barsetCount();
147 }
148 }
148
149
149 /*!
150 /*!
150 Returns number of categories in series
151 Returns number of categories in series
151 */
152 */
152 int QBarSeries::categoryCount() const
153 int QBarSeries::categoryCount() const
153 {
154 {
154 return m_internalModel->categoryCount();
155 return m_internalModel->categoryCount();
155 }
156 }
156
157
157 /*!
158 /*!
158 Returns a list of sets in series. Keeps ownership of sets.
159 Returns a list of sets in series. Keeps ownership of sets.
159 */
160 */
160 QList<QBarSet*> QBarSeries::barSets() const
161 QList<QBarSet*> QBarSeries::barSets() const
161 {
162 {
162 return m_internalModel->barSets();
163 return m_internalModel->barSets();
163 }
164 }
164
165
165 /*!
166 /*!
166 \internal \a index
167 \internal \a index
167 */
168 */
168 QBarSet* QBarSeries::barsetAt(int index)
169 QBarSet* QBarSeries::barsetAt(int index)
169 {
170 {
170 return m_internalModel->barsetAt(index);
171 return m_internalModel->barsetAt(index);
171 }
172 }
172
173
173 /*!
174 /*!
174 \internal \a category
175 \internal \a category
175 */
176 */
176 QString QBarSeries::categoryName(int category)
177 QString QBarSeries::categoryName(int category)
177 {
178 {
178 return m_internalModel->categoryName(category);
179 return m_internalModel->categoryName(category);
179 }
180 }
180
181
181 /*!
182 /*!
182 Enables or disables tooltip depending on parameter \a enabled.
183 Enables or disables tooltip depending on parameter \a enabled.
183 Tooltip shows the name of set, when mouse is hovering on top of bar.
184 Tooltip shows the name of set, when mouse is hovering on top of bar.
184 Calling without parameter \a enabled, enables the tooltip
185 Calling without parameter \a enabled, enables the tooltip
185 */
186 */
186 void QBarSeries::setToolTipEnabled(bool enabled)
187 void QBarSeries::setToolTipEnabled(bool enabled)
187 {
188 {
188 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
189 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
189 if (enabled) {
190 if (enabled) {
190 for (int i=0; i<m_internalModel->barsetCount(); i++) {
191 for (int i=0; i<m_internalModel->barsetCount(); i++) {
191 QBarSet *set = m_internalModel->barsetAt(i);
192 QBarSet *set = m_internalModel->barsetAt(i);
192 connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
193 connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
193 }
194 }
194 } else {
195 } else {
195 for (int i=0; i<m_internalModel->barsetCount(); i++) {
196 for (int i=0; i<m_internalModel->barsetCount(); i++) {
196 QBarSet *set = m_internalModel->barsetAt(i);
197 QBarSet *set = m_internalModel->barsetAt(i);
197 disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
198 disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
198 }
199 }
199 }
200 }
200 }
201 }
201
202
202
203
203 /*!
204 /*!
204 \internal \a category
205 \internal \a category
205 */
206 */
206 void QBarSeries::barsetClicked(QString category, Qt::MouseButtons button)
207 void QBarSeries::barsetClicked(QString category, Qt::MouseButtons button)
207 {
208 {
208 emit clicked(qobject_cast<QBarSet*>(sender()), category, button);
209 emit clicked(qobject_cast<QBarSet*>(sender()), category, button);
209 }
210 }
210
211
211 /*!
212 /*!
212 \internal
213 \internal
213 */
214 */
214 qreal QBarSeries::min()
215 qreal QBarSeries::min()
215 {
216 {
216 return m_internalModel->min();
217 return m_internalModel->min();
217 }
218 }
218
219
219 /*!
220 /*!
220 \internal
221 \internal
221 */
222 */
222 qreal QBarSeries::max()
223 qreal QBarSeries::max()
223 {
224 {
224 return m_internalModel->max();
225 return m_internalModel->max();
225 }
226 }
226
227
227 /*!
228 /*!
228 \internal \a set \a category
229 \internal \a set \a category
229 */
230 */
230 qreal QBarSeries::valueAt(int set, int category)
231 qreal QBarSeries::valueAt(int set, int category)
231 {
232 {
232 return m_internalModel->valueAt(set, category);
233 return m_internalModel->valueAt(set, category);
233 }
234 }
234
235
235 /*!
236 /*!
236 \internal \a set \a category
237 \internal \a set \a category
237 */
238 */
238 qreal QBarSeries::percentageAt(int set, int category)
239 qreal QBarSeries::percentageAt(int set, int category)
239 {
240 {
240 return m_internalModel->percentageAt(set, category);
241 return m_internalModel->percentageAt(set, category);
241 }
242 }
242
243
243 /*!
244 /*!
244 \internal \a category
245 \internal \a category
245 */
246 */
246 qreal QBarSeries::categorySum(int category)
247 qreal QBarSeries::categorySum(int category)
247 {
248 {
248 return m_internalModel->categorySum(category);
249 return m_internalModel->categorySum(category);
249 }
250 }
250
251
251 /*!
252 /*!
252 \internal \a category
253 \internal \a category
253 */
254 */
254 qreal QBarSeries::absoluteCategorySum(int category)
255 qreal QBarSeries::absoluteCategorySum(int category)
255 {
256 {
256 return m_internalModel->absoluteCategorySum(category);
257 return m_internalModel->absoluteCategorySum(category);
257 }
258 }
258
259
259 /*!
260 /*!
260 \internal
261 \internal
261 */
262 */
262 qreal QBarSeries::maxCategorySum()
263 qreal QBarSeries::maxCategorySum()
263 {
264 {
264 return m_internalModel->maxCategorySum();
265 return m_internalModel->maxCategorySum();
265 }
266 }
266
267
267 /*!
268 /*!
268 \internal
269 \internal
269 */
270 */
270 BarChartModel& QBarSeries::model()
271 BarChartModel& QBarSeries::model()
271 {
272 {
272 return *m_internalModel;
273 return *m_internalModel;
273 }
274 }
274
275
275 bool QBarSeries::setModel(QAbstractItemModel *model)
276 bool QBarSeries::setModel(QAbstractItemModel *model)
276 {
277 {
277 // disconnect signals from old model
278 // disconnect signals from old model
278 if(m_model)
279 if(m_model)
279 {
280 {
280 disconnect(m_model, 0, this, 0);
281 disconnect(m_model, 0, this, 0);
281 m_mapCategories = -1;
282 m_mapCategories = -1;
282 m_mapBarBottom = -1;
283 m_mapBarBottom = -1;
283 m_mapBarTop = -1;
284 m_mapBarTop = -1;
284 m_mapFirst = 0;
285 m_mapFirst = 0;
285 m_mapCount = 0;
286 m_mapCount = 0;
286 m_mapOrientation = Qt::Vertical;
287 m_mapOrientation = Qt::Vertical;
287 }
288 }
288
289
289 // set new model
290 // set new model
290 if(model)
291 if(model)
291 {
292 {
292 m_model = model;
293 m_model = model;
293 return true;
294 return true;
294 }
295 }
295 else
296 else
296 {
297 {
297 m_model = 0;
298 m_model = 0;
298 return false;
299 return false;
299 }
300 }
300 }
301 }
301
302
302 // TODO
303 // TODO
303 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
304 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
304 {
305 {
305 if (!m_model)
306 if (!m_model)
306 return;
307 return;
307
308
308 m_mapCategories = categories;
309 m_mapCategories = categories;
309 m_mapBarBottom = bottomBoundry;
310 m_mapBarBottom = bottomBoundry;
310 m_mapBarTop = topBoundry;
311 m_mapBarTop = topBoundry;
311 // m_mapFirst = 1;
312 // m_mapFirst = 1;
312 m_mapOrientation = orientation;
313 m_mapOrientation = orientation;
313
314
314 // connect the signals
315 // connect the signals
315 if (m_mapOrientation == Qt::Vertical) {
316 if (m_mapOrientation == Qt::Vertical) {
316 m_mapCount = m_model->rowCount() - m_mapFirst;
317 m_mapCount = m_model->rowCount() - m_mapFirst;
317 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
318 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
318 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
319 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
319 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)),
320 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)),
320 this, SLOT(modelDataAdded(QModelIndex,int,int)));
321 this, SLOT(modelDataAdded(QModelIndex,int,int)));
321 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
322 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
322 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
323 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
323 } else {
324 } else {
324 m_mapCount = m_model->columnCount() - m_mapFirst;
325 m_mapCount = m_model->columnCount() - m_mapFirst;
325 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
326 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
326 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
327 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
327 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)),
328 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)),
328 this, SLOT(modelDataAdded(QModelIndex,int,int)));
329 this, SLOT(modelDataAdded(QModelIndex,int,int)));
329 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
330 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
330 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
331 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
331 }
332 }
332
333
333
334
334 // create the initial bars
335 // create the initial bars
335 delete m_internalModel;
336 delete m_internalModel;
336 if (m_mapOrientation == Qt::Vertical) {
337 if (m_mapOrientation == Qt::Vertical) {
337 QStringList categories;
338 QStringList categories;
338 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
339 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
339 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
340 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
340 m_internalModel = new BarChartModel(categories, this);
341 m_internalModel = new BarChartModel(categories, this);
341
342
342 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
343 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
343 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
344 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
344 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
345 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
345 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
346 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
346 appendBarSet(barSet);
347 appendBarSet(barSet);
347 }
348 }
348 } else {
349 } else {
349 QStringList categories;
350 QStringList categories;
350 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
351 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
351 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
352 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
352 m_internalModel = new BarChartModel(categories, this);
353 m_internalModel = new BarChartModel(categories, this);
353
354
354 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
355 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
355 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
356 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
356 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
357 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
357 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
358 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
358 appendBarSet(barSet);
359 appendBarSet(barSet);
359 }
360 }
360 }
361 }
361 }
362 }
362
363
363 void QBarSeries::setModelMappingShift(int first, int count)
364 void QBarSeries::setModelMappingShift(int first, int count)
364 {
365 {
365 m_mapFirst = first;
366 m_mapFirst = first;
366 m_mapCount = count;
367 m_mapCount = count;
367 }
368 }
368
369
369 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
370 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
370 {
371 {
371 Q_UNUSED(bottomRight)
372 Q_UNUSED(bottomRight)
372
373
373 if (m_mapOrientation == Qt::Vertical)
374 if (m_mapOrientation == Qt::Vertical)
374 {
375 {
375 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
376 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
376 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
377 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
377 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
378 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
378 }
379 }
379 else
380 else
380 {
381 {
381 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
382 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
382 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
383 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
383 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
384 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
384 }
385 }
385 }
386 }
386
387
387 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
388 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
388 {
389 {
389 if (m_mapOrientation == Qt::Vertical) {
390 if (m_mapOrientation == Qt::Vertical) {
390 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
391 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
391 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
392 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
392 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
393 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
393 }
394 }
394 } else {
395 } else {
395 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
396 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
396 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
397 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
397 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
398 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
398 }
399 }
399 }
400 }
400 emit restructuredBars();
401 emit restructuredBars();
401 }
402 }
402
403
403 void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end)
404 void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end)
404 {
405 {
405 Q_UNUSED(parent)
406 Q_UNUSED(parent)
406 Q_UNUSED(end)
407 Q_UNUSED(end)
407
408
408 removeCategory(start - m_mapFirst);
409 removeCategory(start - m_mapFirst);
409 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
410 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
410 {
411 {
411 barsetAt(i)->removeValue(start - m_mapFirst);
412 barsetAt(i)->removeValue(start - m_mapFirst);
412 }
413 }
413 emit restructuredBars();
414 emit restructuredBars();
414 }
415 }
415
416
416 void QBarSeries::barsetChanged()
417 void QBarSeries::barsetChanged()
417 {
418 {
418 emit updatedBars();
419 emit updatedBars();
419 }
420 }
420
421
421 QBarCategories QBarSeries::categories() const
422 QBarCategories QBarSeries::categories() const
422 {
423 {
423 QBarCategories categories;
424 QBarCategories categories;
424 int count = m_internalModel->categoryCount();
425 int count = m_internalModel->categoryCount();
425 for (int i=1; i <= count; i++) {
426 for (int i=1; i <= count; i++) {
426 categories.insert(i, m_internalModel->categoryName(i - 1));
427 categories.insert(i, m_internalModel->categoryName(i - 1));
427 }
428 }
428 return categories;
429 return categories;
429 }
430 }
430
431
431 /*!
432 /*!
432 Sets the visibility of labels in series to \a visible
433 Sets the visibility of labels in series to \a visible
433 */
434 */
434 void QBarSeries::setLabelsVisible(bool visible)
435 void QBarSeries::setLabelsVisible(bool visible)
435 {
436 {
436 foreach (QBarSet* s, barSets()) {
437 foreach (QBarSet* s, barSets()) {
437 s->setLabelsVisible(visible);
438 s->setLabelsVisible(visible);
438 }
439 }
439 }
440 }
440
441
441
442
442 #include "moc_qbarseries.cpp"
443 #include "moc_qbarseries.cpp"
443
444
444 QTCOMMERCIALCHART_END_NAMESPACE
445 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,694 +1,695
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 "qpieseriesprivate_p.h"
22 #include "qpieseriesprivate_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "pieslicedata_p.h"
24 #include "pieslicedata_p.h"
25 #include <QAbstractItemModel>
25 #include <QDebug>
26 #include <QDebug>
26
27
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
29
29 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
30 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
30 :QObject(parent),
31 :QObject(parent),
31 q_ptr(parent),
32 q_ptr(parent),
32 m_pieRelativeHorPos(0.5),
33 m_pieRelativeHorPos(0.5),
33 m_pieRelativeVerPos(0.5),
34 m_pieRelativeVerPos(0.5),
34 m_pieRelativeSize(0.7),
35 m_pieRelativeSize(0.7),
35 m_pieStartAngle(0),
36 m_pieStartAngle(0),
36 m_pieEndAngle(360),
37 m_pieEndAngle(360),
37 m_total(0),
38 m_total(0),
38 m_mapValues(0),
39 m_mapValues(0),
39 m_mapLabels(0),
40 m_mapLabels(0),
40 m_mapOrientation(Qt::Horizontal)
41 m_mapOrientation(Qt::Horizontal)
41 {
42 {
42
43
43 }
44 }
44
45
45 QPieSeriesPrivate::~QPieSeriesPrivate()
46 QPieSeriesPrivate::~QPieSeriesPrivate()
46 {
47 {
47
48
48 }
49 }
49
50
50 void QPieSeriesPrivate::updateDerivativeData()
51 void QPieSeriesPrivate::updateDerivativeData()
51 {
52 {
52 m_total = 0;
53 m_total = 0;
53
54
54 // nothing to do?
55 // nothing to do?
55 if (m_slices.count() == 0)
56 if (m_slices.count() == 0)
56 return;
57 return;
57
58
58 // calculate total
59 // calculate total
59 foreach (QPieSlice* s, m_slices)
60 foreach (QPieSlice* s, m_slices)
60 m_total += s->value();
61 m_total += s->value();
61
62
62 // nothing to show..
63 // nothing to show..
63 if (qFuzzyIsNull(m_total))
64 if (qFuzzyIsNull(m_total))
64 return;
65 return;
65
66
66 // update slice attributes
67 // update slice attributes
67 qreal sliceAngle = m_pieStartAngle;
68 qreal sliceAngle = m_pieStartAngle;
68 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
69 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
69 QVector<QPieSlice*> changed;
70 QVector<QPieSlice*> changed;
70 foreach (QPieSlice* s, m_slices) {
71 foreach (QPieSlice* s, m_slices) {
71
72
72 PieSliceData data = PieSliceData::data(s);
73 PieSliceData data = PieSliceData::data(s);
73 data.m_percentage = s->value() / m_total;
74 data.m_percentage = s->value() / m_total;
74 data.m_angleSpan = pieSpan * data.m_percentage;
75 data.m_angleSpan = pieSpan * data.m_percentage;
75 data.m_startAngle = sliceAngle;
76 data.m_startAngle = sliceAngle;
76 sliceAngle += data.m_angleSpan;
77 sliceAngle += data.m_angleSpan;
77
78
78 if (PieSliceData::data(s) != data) {
79 if (PieSliceData::data(s) != data) {
79 PieSliceData::data(s) = data;
80 PieSliceData::data(s) = data;
80 changed << s;
81 changed << s;
81 }
82 }
82 }
83 }
83
84
84 // emit signals
85 // emit signals
85 foreach (QPieSlice* s, changed)
86 foreach (QPieSlice* s, changed)
86 PieSliceData::data(s).emitChangedSignal(s);
87 PieSliceData::data(s).emitChangedSignal(s);
87 }
88 }
88
89
89 void QPieSeriesPrivate::sliceChanged()
90 void QPieSeriesPrivate::sliceChanged()
90 {
91 {
91 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
92 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
92 updateDerivativeData();
93 updateDerivativeData();
93 }
94 }
94
95
95 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
96 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
96 {
97 {
97 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
98 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
98 Q_ASSERT(m_slices.contains(slice));
99 Q_ASSERT(m_slices.contains(slice));
99 Q_Q(QPieSeries);
100 Q_Q(QPieSeries);
100 emit q->clicked(slice, buttons);
101 emit q->clicked(slice, buttons);
101 }
102 }
102
103
103 void QPieSeriesPrivate::sliceHoverEnter()
104 void QPieSeriesPrivate::sliceHoverEnter()
104 {
105 {
105 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
106 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
106 Q_ASSERT(m_slices.contains(slice));
107 Q_ASSERT(m_slices.contains(slice));
107 Q_Q(QPieSeries);
108 Q_Q(QPieSeries);
108 emit q->hoverEnter(slice);
109 emit q->hoverEnter(slice);
109 }
110 }
110
111
111 void QPieSeriesPrivate::sliceHoverLeave()
112 void QPieSeriesPrivate::sliceHoverLeave()
112 {
113 {
113 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
114 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
114 Q_ASSERT(m_slices.contains(slice));
115 Q_ASSERT(m_slices.contains(slice));
115 Q_Q(QPieSeries);
116 Q_Q(QPieSeries);
116 emit q->hoverLeave(slice);
117 emit q->hoverLeave(slice);
117 }
118 }
118
119
119 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
120 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
120 {
121 {
121 Q_UNUSED(bottomRight)
122 Q_UNUSED(bottomRight)
122 Q_Q(QPieSeries);
123 Q_Q(QPieSeries);
123
124
124 if (m_mapOrientation == Qt::Vertical)
125 if (m_mapOrientation == Qt::Vertical)
125 {
126 {
126 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
127 // slices().at(topLeft.row())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
127 if (topLeft.column() == m_mapValues)
128 if (topLeft.column() == m_mapValues)
128 if (m_mapValues == m_mapLabels)
129 if (m_mapValues == m_mapLabels)
129 {
130 {
130 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
131 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
131 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
132 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
132 }
133 }
133 else
134 else
134 {
135 {
135 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
136 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
136 }
137 }
137 else if (topLeft.column() == m_mapLabels)
138 else if (topLeft.column() == m_mapLabels)
138 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
139 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
139 }
140 }
140 else
141 else
141 {
142 {
142 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
143 // slices().at(topLeft.column())->setValue(m_model->data(m_model->index(topLeft.row(), topLeft.column()), Qt::DisplayRole).toDouble());
143 if (topLeft.row() == m_mapValues)
144 if (topLeft.row() == m_mapValues)
144 if (m_mapValues == m_mapLabels)
145 if (m_mapValues == m_mapLabels)
145 {
146 {
146 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
147 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
147 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
148 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
148 }
149 }
149 else
150 else
150 {
151 {
151 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
152 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
152 }
153 }
153 else if (topLeft.row() == m_mapLabels)
154 else if (topLeft.row() == m_mapLabels)
154 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
155 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
155 }
156 }
156 }
157 }
157
158
158 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
159 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
159 {
160 {
160 Q_UNUSED(parent)
161 Q_UNUSED(parent)
161 Q_UNUSED(end)
162 Q_UNUSED(end)
162 Q_Q(QPieSeries);
163 Q_Q(QPieSeries);
163
164
164 QPieSlice* newSlice = new QPieSlice;
165 QPieSlice* newSlice = new QPieSlice;
165 newSlice->setLabelVisible(true);
166 newSlice->setLabelVisible(true);
166 if (m_mapOrientation == Qt::Vertical)
167 if (m_mapOrientation == Qt::Vertical)
167 {
168 {
168 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
169 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
169 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
170 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
170 }
171 }
171 else
172 else
172 {
173 {
173 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
174 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
174 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
175 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
175 }
176 }
176
177
177 q->insert(start, newSlice);
178 q->insert(start, newSlice);
178 }
179 }
179
180
180 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
181 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
181 {
182 {
182 Q_UNUSED(parent)
183 Q_UNUSED(parent)
183 Q_UNUSED(end)
184 Q_UNUSED(end)
184 Q_Q(QPieSeries);
185 Q_Q(QPieSeries);
185 q->remove(m_slices.at(start));
186 q->remove(m_slices.at(start));
186 }
187 }
187
188
188
189
189
190
190 /*!
191 /*!
191 \class QPieSeries
192 \class QPieSeries
192 \brief Pie series API for QtCommercial Charts
193 \brief Pie series API for QtCommercial Charts
193
194
194 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
195 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
195 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
196 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
196 The actual slice size is determined by that relative value.
197 The actual slice size is determined by that relative value.
197
198
198 By default the pie is defined as a full pie but it can be a partial pie.
199 By default the pie is defined as a full pie but it can be a partial pie.
199 This can be done by setting a starting angle and angle span to the series.
200 This can be done by setting a starting angle and angle span to the series.
200 */
201 */
201
202
202 /*!
203 /*!
203 Constructs a series object which is a child of \a parent.
204 Constructs a series object which is a child of \a parent.
204 */
205 */
205 QPieSeries::QPieSeries(QObject *parent) :
206 QPieSeries::QPieSeries(QObject *parent) :
206 QSeries(parent),
207 QSeries(parent),
207 d_ptr(new QPieSeriesPrivate(this))
208 d_ptr(new QPieSeriesPrivate(this))
208 {
209 {
209
210
210 }
211 }
211
212
212 /*!
213 /*!
213 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
214 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
214 */
215 */
215 QPieSeries::~QPieSeries()
216 QPieSeries::~QPieSeries()
216 {
217 {
217 // NOTE: d_prt destroyed by QObject
218 // NOTE: d_prt destroyed by QObject
218 }
219 }
219
220
220 /*!
221 /*!
221 Returns QChartSeries::SeriesTypePie.
222 Returns QChartSeries::SeriesTypePie.
222 */
223 */
223 QSeries::QSeriesType QPieSeries::type() const
224 QSeries::QSeriesType QPieSeries::type() const
224 {
225 {
225 return QSeries::SeriesTypePie;
226 return QSeries::SeriesTypePie;
226 }
227 }
227
228
228 /*!
229 /*!
229 Sets an array of \a slices to the series replacing the existing slices.
230 Sets an array of \a slices to the series replacing the existing slices.
230 Slice ownership is passed to the series.
231 Slice ownership is passed to the series.
231 */
232 */
232 void QPieSeries::replace(QList<QPieSlice*> slices)
233 void QPieSeries::replace(QList<QPieSlice*> slices)
233 {
234 {
234 clear();
235 clear();
235 append(slices);
236 append(slices);
236 }
237 }
237
238
238 /*!
239 /*!
239 Adds an array of \a slices to the series.
240 Adds an array of \a slices to the series.
240 Slice ownership is passed to the series.
241 Slice ownership is passed to the series.
241 */
242 */
242 void QPieSeries::append(QList<QPieSlice*> slices)
243 void QPieSeries::append(QList<QPieSlice*> slices)
243 {
244 {
244 Q_D(QPieSeries);
245 Q_D(QPieSeries);
245
246
246 foreach (QPieSlice* s, slices) {
247 foreach (QPieSlice* s, slices) {
247 s->setParent(this);
248 s->setParent(this);
248 d->m_slices << s;
249 d->m_slices << s;
249 }
250 }
250
251
251 d->updateDerivativeData();
252 d->updateDerivativeData();
252
253
253 foreach (QPieSlice* s, slices) {
254 foreach (QPieSlice* s, slices) {
254 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
255 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
255 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
256 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
256 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
257 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
257 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
258 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
258 }
259 }
259
260
260 emit added(slices);
261 emit added(slices);
261 }
262 }
262
263
263 /*!
264 /*!
264 Adds a single \a slice to the series.
265 Adds a single \a slice to the series.
265 Slice ownership is passed to the series.
266 Slice ownership is passed to the series.
266 */
267 */
267 void QPieSeries::append(QPieSlice* slice)
268 void QPieSeries::append(QPieSlice* slice)
268 {
269 {
269 append(QList<QPieSlice*>() << slice);
270 append(QList<QPieSlice*>() << slice);
270 }
271 }
271
272
272 /*!
273 /*!
273 Adds a single \a slice to the series and returns a reference to the series.
274 Adds a single \a slice to the series and returns a reference to the series.
274 Slice ownership is passed to the series.
275 Slice ownership is passed to the series.
275 */
276 */
276 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
277 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
277 {
278 {
278 append(slice);
279 append(slice);
279 return *this;
280 return *this;
280 }
281 }
281
282
282
283
283 /*!
284 /*!
284 Appends a single slice to the series with give \a value and \a name.
285 Appends a single slice to the series with give \a value and \a name.
285 Slice ownership is passed to the series.
286 Slice ownership is passed to the series.
286 */
287 */
287 QPieSlice* QPieSeries::append(qreal value, QString name)
288 QPieSlice* QPieSeries::append(qreal value, QString name)
288 {
289 {
289 QPieSlice* slice = new QPieSlice(value, name);
290 QPieSlice* slice = new QPieSlice(value, name);
290 append(slice);
291 append(slice);
291 return slice;
292 return slice;
292 }
293 }
293
294
294 /*!
295 /*!
295 Inserts a single \a slice to the series before the slice at \a index position.
296 Inserts a single \a slice to the series before the slice at \a index position.
296 Slice ownership is passed to the series.
297 Slice ownership is passed to the series.
297 */
298 */
298 void QPieSeries::insert(int index, QPieSlice* slice)
299 void QPieSeries::insert(int index, QPieSlice* slice)
299 {
300 {
300 Q_D(QPieSeries);
301 Q_D(QPieSeries);
301 Q_ASSERT(index <= d->m_slices.count());
302 Q_ASSERT(index <= d->m_slices.count());
302 slice->setParent(this);
303 slice->setParent(this);
303 d->m_slices.insert(index, slice);
304 d->m_slices.insert(index, slice);
304
305
305 d->updateDerivativeData();
306 d->updateDerivativeData();
306
307
307 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
308 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
308 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
309 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
309 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
310 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
310 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
311 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
311
312
312 emit added(QList<QPieSlice*>() << slice);
313 emit added(QList<QPieSlice*>() << slice);
313 }
314 }
314
315
315 /*!
316 /*!
316 Removes a single \a slice from the series and deletes the slice.
317 Removes a single \a slice from the series and deletes the slice.
317
318
318 Do not reference this pointer after this call.
319 Do not reference this pointer after this call.
319 */
320 */
320 void QPieSeries::remove(QPieSlice* slice)
321 void QPieSeries::remove(QPieSlice* slice)
321 {
322 {
322 Q_D(QPieSeries);
323 Q_D(QPieSeries);
323 if (!d->m_slices.removeOne(slice)) {
324 if (!d->m_slices.removeOne(slice)) {
324 Q_ASSERT(0); // TODO: how should this be reported?
325 Q_ASSERT(0); // TODO: how should this be reported?
325 return;
326 return;
326 }
327 }
327
328
328 d->updateDerivativeData();
329 d->updateDerivativeData();
329
330
330 emit removed(QList<QPieSlice*>() << slice);
331 emit removed(QList<QPieSlice*>() << slice);
331
332
332 delete slice;
333 delete slice;
333 slice = 0;
334 slice = 0;
334 }
335 }
335
336
336 /*!
337 /*!
337 Clears all slices from the series.
338 Clears all slices from the series.
338 */
339 */
339 void QPieSeries::clear()
340 void QPieSeries::clear()
340 {
341 {
341 Q_D(QPieSeries);
342 Q_D(QPieSeries);
342 if (d->m_slices.count() == 0)
343 if (d->m_slices.count() == 0)
343 return;
344 return;
344
345
345 QList<QPieSlice*> slices = d->m_slices;
346 QList<QPieSlice*> slices = d->m_slices;
346 foreach (QPieSlice* s, d->m_slices) {
347 foreach (QPieSlice* s, d->m_slices) {
347 d->m_slices.removeOne(s);
348 d->m_slices.removeOne(s);
348 delete s;
349 delete s;
349 }
350 }
350
351
351 d->updateDerivativeData();
352 d->updateDerivativeData();
352
353
353 emit removed(slices);
354 emit removed(slices);
354 }
355 }
355
356
356 /*!
357 /*!
357 Counts the number of the slices in this series.
358 Counts the number of the slices in this series.
358 */
359 */
359 int QPieSeries::count() const
360 int QPieSeries::count() const
360 {
361 {
361 Q_D(const QPieSeries);
362 Q_D(const QPieSeries);
362 return d->m_slices.count();
363 return d->m_slices.count();
363 }
364 }
364
365
365 /*!
366 /*!
366 Returns true is the series is empty.
367 Returns true is the series is empty.
367 */
368 */
368 bool QPieSeries::isEmpty() const
369 bool QPieSeries::isEmpty() const
369 {
370 {
370 Q_D(const QPieSeries);
371 Q_D(const QPieSeries);
371 return d->m_slices.isEmpty();
372 return d->m_slices.isEmpty();
372 }
373 }
373
374
374 /*!
375 /*!
375 Returns a list of slices that belong to this series.
376 Returns a list of slices that belong to this series.
376 */
377 */
377 QList<QPieSlice*> QPieSeries::slices() const
378 QList<QPieSlice*> QPieSeries::slices() const
378 {
379 {
379 Q_D(const QPieSeries);
380 Q_D(const QPieSeries);
380 return d->m_slices;
381 return d->m_slices;
381 }
382 }
382
383
383 /*!
384 /*!
384 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
385 Sets the center position of the pie by \a relativeHorizontalPosition and \a relativeVerticalPosition.
385
386
386 The factors are relative to the chart rectangle where:
387 The factors are relative to the chart rectangle where:
387
388
388 \a relativeHorizontalPosition 0.0 means the absolute left.
389 \a relativeHorizontalPosition 0.0 means the absolute left.
389 \a relativeHorizontalPosition 1.0 means the absolute right.
390 \a relativeHorizontalPosition 1.0 means the absolute right.
390 \a relativeVerticalPosition 0.0 means the absolute top.
391 \a relativeVerticalPosition 0.0 means the absolute top.
391 \a relativeVerticalPosition 1.0 means the absolute bottom.
392 \a relativeVerticalPosition 1.0 means the absolute bottom.
392
393
393 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
394 By default both values are 0.5 which puts the pie in the middle of the chart rectangle.
394
395
395 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
396 \sa pieHorizontalPosition(), pieVerticalPosition(), setPieSize()
396 */
397 */
397 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
398 void QPieSeries::setPiePosition(qreal relativeHorizontalPosition, qreal relativeVerticalPosition)
398 {
399 {
399 Q_D(QPieSeries);
400 Q_D(QPieSeries);
400 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
401 if (relativeHorizontalPosition < 0.0 || relativeHorizontalPosition > 1.0 ||
401 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
402 relativeVerticalPosition < 0.0 || relativeVerticalPosition > 1.0)
402 return;
403 return;
403
404
404 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativeHorizontalPosition) ||
405 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativeHorizontalPosition) ||
405 !qFuzzyIsNull(d->m_pieRelativeVerPos - relativeVerticalPosition)) {
406 !qFuzzyIsNull(d->m_pieRelativeVerPos - relativeVerticalPosition)) {
406 d->m_pieRelativeHorPos = relativeHorizontalPosition;
407 d->m_pieRelativeHorPos = relativeHorizontalPosition;
407 d->m_pieRelativeVerPos = relativeVerticalPosition;
408 d->m_pieRelativeVerPos = relativeVerticalPosition;
408 emit piePositionChanged();
409 emit piePositionChanged();
409 }
410 }
410 }
411 }
411
412
412 /*!
413 /*!
413 Gets the horizontal position of the pie.
414 Gets the horizontal position of the pie.
414
415
415 The returned value is relative to the chart rectangle where:
416 The returned value is relative to the chart rectangle where:
416
417
417 0.0 means the absolute left.
418 0.0 means the absolute left.
418 1.0 means the absolute right.
419 1.0 means the absolute right.
419
420
420 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
421 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
421
422
422 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
423 \sa setPiePosition(), pieVerticalPosition(), setPieSize()
423 */
424 */
424 qreal QPieSeries::pieHorizontalPosition() const
425 qreal QPieSeries::pieHorizontalPosition() const
425 {
426 {
426 Q_D(const QPieSeries);
427 Q_D(const QPieSeries);
427 return d->m_pieRelativeHorPos;
428 return d->m_pieRelativeHorPos;
428 }
429 }
429
430
430 /*!
431 /*!
431 Gets the vertical position position of the pie.
432 Gets the vertical position position of the pie.
432
433
433 The returned value is relative to the chart rectangle where:
434 The returned value is relative to the chart rectangle where:
434
435
435 0.0 means the absolute top.
436 0.0 means the absolute top.
436 1.0 means the absolute bottom.
437 1.0 means the absolute bottom.
437
438
438 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
439 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
439
440
440 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
441 \sa setPiePosition(), pieHorizontalPosition(), setPieSize()
441 */
442 */
442 qreal QPieSeries::pieVerticalPosition() const
443 qreal QPieSeries::pieVerticalPosition() const
443 {
444 {
444 Q_D(const QPieSeries);
445 Q_D(const QPieSeries);
445 return d->m_pieRelativeVerPos;
446 return d->m_pieRelativeVerPos;
446 }
447 }
447
448
448 /*!
449 /*!
449 Sets the relative size of the pie.
450 Sets the relative size of the pie.
450
451
451 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
452 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
452
453
453 Default value is 0.7.
454 Default value is 0.7.
454
455
455 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
456 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
456 */
457 */
457 void QPieSeries::setPieSize(qreal relativeSize)
458 void QPieSeries::setPieSize(qreal relativeSize)
458 {
459 {
459 Q_D(QPieSeries);
460 Q_D(QPieSeries);
460 if (relativeSize < 0.0 || relativeSize > 1.0)
461 if (relativeSize < 0.0 || relativeSize > 1.0)
461 return;
462 return;
462
463
463 if (!qFuzzyIsNull(d->m_pieRelativeSize- relativeSize)) {
464 if (!qFuzzyIsNull(d->m_pieRelativeSize- relativeSize)) {
464 d->m_pieRelativeSize = relativeSize;
465 d->m_pieRelativeSize = relativeSize;
465 emit pieSizeChanged();
466 emit pieSizeChanged();
466 }
467 }
467 }
468 }
468
469
469 /*!
470 /*!
470 Gets the relative size of the pie.
471 Gets the relative size of the pie.
471
472
472 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
473 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
473
474
474 Default value is 0.7.
475 Default value is 0.7.
475
476
476 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
477 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
477 */
478 */
478 qreal QPieSeries::pieSize() const
479 qreal QPieSeries::pieSize() const
479 {
480 {
480 Q_D(const QPieSeries);
481 Q_D(const QPieSeries);
481 return d->m_pieRelativeSize;
482 return d->m_pieRelativeSize;
482 }
483 }
483
484
484
485
485 /*!
486 /*!
486 Sets the end angle of the pie.
487 Sets the end angle of the pie.
487
488
488 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
489 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
489
490
490 \a angle must be less than pie end angle. Default value is 0.
491 \a angle must be less than pie end angle. Default value is 0.
491
492
492 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
493 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
493 */
494 */
494 void QPieSeries::setPieStartAngle(qreal angle)
495 void QPieSeries::setPieStartAngle(qreal angle)
495 {
496 {
496 Q_D(QPieSeries);
497 Q_D(QPieSeries);
497
498
498 if (angle < 0 || angle > 360 || angle > d->m_pieEndAngle)
499 if (angle < 0 || angle > 360 || angle > d->m_pieEndAngle)
499 return;
500 return;
500
501
501 if (!qFuzzyIsNull(angle - d->m_pieStartAngle)) {
502 if (!qFuzzyIsNull(angle - d->m_pieStartAngle)) {
502 d->m_pieStartAngle = angle;
503 d->m_pieStartAngle = angle;
503 d->updateDerivativeData();
504 d->updateDerivativeData();
504 }
505 }
505 }
506 }
506
507
507 /*!
508 /*!
508 Gets the start angle of the pie.
509 Gets the start angle of the pie.
509
510
510 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
511 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
511
512
512 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
513 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
513 */
514 */
514 qreal QPieSeries::pieStartAngle() const
515 qreal QPieSeries::pieStartAngle() const
515 {
516 {
516 Q_D(const QPieSeries);
517 Q_D(const QPieSeries);
517 return d->m_pieStartAngle;
518 return d->m_pieStartAngle;
518 }
519 }
519
520
520 /*!
521 /*!
521 Sets the end angle of the pie.
522 Sets the end angle of the pie.
522
523
523 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
524 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
524
525
525 \a angle must be greater than start angle.
526 \a angle must be greater than start angle.
526
527
527 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
528 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
528 */
529 */
529 void QPieSeries::setPieEndAngle(qreal angle)
530 void QPieSeries::setPieEndAngle(qreal angle)
530 {
531 {
531 Q_D(QPieSeries);
532 Q_D(QPieSeries);
532
533
533 if (angle < 0 || angle > 360 || angle < d->m_pieStartAngle)
534 if (angle < 0 || angle > 360 || angle < d->m_pieStartAngle)
534 return;
535 return;
535
536
536 if (!qFuzzyIsNull(angle - d->m_pieEndAngle)) {
537 if (!qFuzzyIsNull(angle - d->m_pieEndAngle)) {
537 d->m_pieEndAngle = angle;
538 d->m_pieEndAngle = angle;
538 d->updateDerivativeData();
539 d->updateDerivativeData();
539 }
540 }
540 }
541 }
541
542
542 /*!
543 /*!
543 Returns the end angle of the pie.
544 Returns the end angle of the pie.
544
545
545 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
546 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
546
547
547 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
548 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
548 */
549 */
549 qreal QPieSeries::pieEndAngle() const
550 qreal QPieSeries::pieEndAngle() const
550 {
551 {
551 Q_D(const QPieSeries);
552 Q_D(const QPieSeries);
552 return d->m_pieEndAngle;
553 return d->m_pieEndAngle;
553 }
554 }
554
555
555 /*!
556 /*!
556 Sets the all the slice labels \a visible or invisible.
557 Sets the all the slice labels \a visible or invisible.
557
558
558 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
559 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
559 */
560 */
560 void QPieSeries::setLabelsVisible(bool visible)
561 void QPieSeries::setLabelsVisible(bool visible)
561 {
562 {
562 Q_D(QPieSeries);
563 Q_D(QPieSeries);
563 foreach (QPieSlice* s, d->m_slices)
564 foreach (QPieSlice* s, d->m_slices)
564 s->setLabelVisible(visible);
565 s->setLabelVisible(visible);
565 }
566 }
566
567
567 /*!
568 /*!
568 Returns the sum of all slice values in this series.
569 Returns the sum of all slice values in this series.
569
570
570 \sa QPieSlice::value(), QPieSlice::setValue()
571 \sa QPieSlice::value(), QPieSlice::setValue()
571 */
572 */
572 qreal QPieSeries::total() const
573 qreal QPieSeries::total() const
573 {
574 {
574 Q_D(const QPieSeries);
575 Q_D(const QPieSeries);
575 return d->m_total;
576 return d->m_total;
576 }
577 }
577
578
578 /*!
579 /*!
579 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
580 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
580
581
581 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
582 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
582
583
583 \sa QPieSlice::clicked()
584 \sa QPieSlice::clicked()
584 */
585 */
585
586
586 /*!
587 /*!
587 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
588 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
588
589
589 This signal is emitted when user has hovered over a \a slice.
590 This signal is emitted when user has hovered over a \a slice.
590
591
591 \sa QPieSlice::hoverEnter()
592 \sa QPieSlice::hoverEnter()
592 */
593 */
593
594
594 /*!
595 /*!
595 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
596 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
596
597
597 This signal is emitted when user has hovered away from a \a slice.
598 This signal is emitted when user has hovered away from a \a slice.
598
599
599 \sa QPieSlice::hoverLeave()
600 \sa QPieSlice::hoverLeave()
600 */
601 */
601
602
602 /*!
603 /*!
603 \fn void QPieSeries::added(QList<QPieSlice*> slices)
604 \fn void QPieSeries::added(QList<QPieSlice*> slices)
604
605
605 This signal is emitted when \a slices has been added to the series.
606 This signal is emitted when \a slices has been added to the series.
606
607
607 \sa append(), insert()
608 \sa append(), insert()
608 */
609 */
609
610
610 /*!
611 /*!
611 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
612 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
612
613
613 This signal is emitted when \a slices has been removed from the series.
614 This signal is emitted when \a slices has been removed from the series.
614
615
615 \sa remove(), clear()
616 \sa remove(), clear()
616 */
617 */
617
618
618 /*!
619 /*!
619 \fn void QPieSeries::piePositionChanged()
620 \fn void QPieSeries::piePositionChanged()
620
621
621 This signal is emitted when pie position has changed.
622 This signal is emitted when pie position has changed.
622
623
623 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
624 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
624 */
625 */
625
626
626 /*!
627 /*!
627 \fn void QPieSeries::pieSizeChanged()
628 \fn void QPieSeries::pieSizeChanged()
628
629
629 This signal is emitted when pie size has changed.
630 This signal is emitted when pie size has changed.
630
631
631 \sa pieSize(), setPieSize()
632 \sa pieSize(), setPieSize()
632 */
633 */
633
634
634 bool QPieSeries::setModel(QAbstractItemModel* model)
635 bool QPieSeries::setModel(QAbstractItemModel* model)
635 {
636 {
636 Q_D(QPieSeries);
637 Q_D(QPieSeries);
637 // disconnect signals from old model
638 // disconnect signals from old model
638 if(m_model)
639 if(m_model)
639 {
640 {
640 disconnect(m_model, 0, this, 0);
641 disconnect(m_model, 0, this, 0);
641 d->m_mapValues = -1;
642 d->m_mapValues = -1;
642 d->m_mapLabels = -1;
643 d->m_mapLabels = -1;
643 d->m_mapOrientation = Qt::Vertical;
644 d->m_mapOrientation = Qt::Vertical;
644 }
645 }
645
646
646 // set new model
647 // set new model
647 if(model)
648 if(model)
648 {
649 {
649 m_model = model;
650 m_model = model;
650 return true;
651 return true;
651 }
652 }
652 else
653 else
653 {
654 {
654 m_model = 0;
655 m_model = 0;
655 return false;
656 return false;
656 }
657 }
657 }
658 }
658
659
659 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
660 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
660 {
661 {
661 Q_D(QPieSeries);
662 Q_D(QPieSeries);
662
663
663 if (m_model == 0)
664 if (m_model == 0)
664 return;
665 return;
665
666
666 d->m_mapValues = modelValuesLine;
667 d->m_mapValues = modelValuesLine;
667 d->m_mapLabels = modelLabelsLine;
668 d->m_mapLabels = modelLabelsLine;
668 d->m_mapOrientation = orientation;
669 d->m_mapOrientation = orientation;
669
670
670 // connect the signals
671 // connect the signals
671 if (d->m_mapOrientation == Qt::Vertical) {
672 if (d->m_mapOrientation == Qt::Vertical) {
672 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
673 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
673 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
674 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
674 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
675 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
675 } else {
676 } else {
676 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
677 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
677 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
678 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
678 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
679 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
679 }
680 }
680
681
681 // create the initial slices set
682 // create the initial slices set
682 if (d->m_mapOrientation == Qt::Vertical) {
683 if (d->m_mapOrientation == Qt::Vertical) {
683 for (int i = 0; i < m_model->rowCount(); i++)
684 for (int i = 0; i < m_model->rowCount(); i++)
684 append(m_model->data(m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
685 append(m_model->data(m_model->index(i, d->m_mapValues), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(i, d->m_mapLabels), Qt::DisplayRole).toString());
685 } else {
686 } else {
686 for (int i = 0; i < m_model->columnCount(); i++)
687 for (int i = 0; i < m_model->columnCount(); i++)
687 append(m_model->data(m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
688 append(m_model->data(m_model->index(d->m_mapValues, i), Qt::DisplayRole).toDouble(), m_model->data(m_model->index(d->m_mapLabels, i), Qt::DisplayRole).toString());
688 }
689 }
689 }
690 }
690
691
691 #include "moc_qpieseries.cpp"
692 #include "moc_qpieseries.cpp"
692 #include "moc_qpieseriesprivate_p.cpp"
693 #include "moc_qpieseriesprivate_p.cpp"
693
694
694 QTCOMMERCIALCHART_END_NAMESPACE
695 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,66 +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 QSERIES_H
21 #ifndef QSERIES_H
22 #define QSERIES_H
22 #define QSERIES_H
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <QObject>
25 #include <QObject>
26 #include <QAbstractItemModel>
26 //#include <QAbstractItemModel>
27 #include <QPen>
27 #include <QPen>
28
28
29 class QAbstractItemModel;
30 class QModelIndex;
31
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
33
31 class QTCOMMERCIALCHART_EXPORT QSeries : public QObject
34 class QTCOMMERCIALCHART_EXPORT QSeries : public QObject
32 {
35 {
33 Q_OBJECT
36 Q_OBJECT
34 public:
37 public:
35 enum QSeriesType {
38 enum QSeriesType {
36 SeriesTypeLine,
39 SeriesTypeLine,
37 SeriesTypeArea,
40 SeriesTypeArea,
38 SeriesTypeBar,
41 SeriesTypeBar,
39 SeriesTypeStackedBar,
42 SeriesTypeStackedBar,
40 SeriesTypePercentBar,
43 SeriesTypePercentBar,
41 SeriesTypePie,
44 SeriesTypePie,
42 SeriesTypeScatter,
45 SeriesTypeScatter,
43 SeriesTypeSpline
46 SeriesTypeSpline
44 };
47 };
45
48
46 protected:
49 protected:
47 QSeries(QObject *parent = 0) : QObject(parent) {m_model = 0;}
50 QSeries(QObject *parent = 0) : QObject(parent) {m_model = 0;}
48
51
49 public:
52 public:
50 virtual ~QSeries() {}
53 virtual ~QSeries() {}
51 virtual QSeriesType type() const = 0;
54 virtual QSeriesType type() const = 0;
52 // TODO
55 // TODO
53 virtual bool setModel(QAbstractItemModel* /*model*/) { return false; }
56 virtual bool setModel(QAbstractItemModel* /*model*/) { return false; }
54 void setName(QString name) { m_name = name; }
57 void setName(QString name) { m_name = name; }
55 QString name() const { return m_name; }
58 QString name() const { return m_name; }
56
59
57 protected:
60 protected:
58 QAbstractItemModel* m_model;
61 QAbstractItemModel* m_model;
59
62
60 private:
63 private:
61 QString m_name;
64 QString m_name;
62 };
65 };
63
66
64 QTCOMMERCIALCHART_END_NAMESPACE
67 QTCOMMERCIALCHART_END_NAMESPACE
65
68
66 #endif
69 #endif
@@ -1,511 +1,512
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 "qxyseries.h"
21 #include "qxyseries.h"
22 #include <QAbstractItemModel>
22
23
23 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24
25
25 /*!
26 /*!
26 \class QXYSeries
27 \class QXYSeries
27 \brief The QXYSeries class is a base class for line, spline and scatter series.
28 \brief The QXYSeries class is a base class for line, spline and scatter series.
28 */
29 */
29
30
30 /*!
31 /*!
31 \fn QPen QXYSeries::pen() const
32 \fn QPen QXYSeries::pen() const
32 \brief Returns pen used to draw points for series.
33 \brief Returns pen used to draw points for series.
33 \sa setPen()
34 \sa setPen()
34 */
35 */
35
36
36 /*!
37 /*!
37 \fn QBrush QXYSeries::brush() const
38 \fn QBrush QXYSeries::brush() const
38 \brief Returns brush used to draw points for series.
39 \brief Returns brush used to draw points for series.
39 \sa setBrush()
40 \sa setBrush()
40 */
41 */
41
42
42 /*!
43 /*!
43 \fn void QXYSeries::clicked(const QPointF& point)
44 \fn void QXYSeries::clicked(const QPointF& point)
44 \brief Signal is emitted when user clicks the \a point on chart.
45 \brief Signal is emitted when user clicks the \a point on chart.
45 */
46 */
46
47
47 /*!
48 /*!
48 \fn void QXYSeries::pointReplaced(int index)
49 \fn void QXYSeries::pointReplaced(int index)
49 \brief \internal \a index
50 \brief \internal \a index
50 */
51 */
51
52
52 /*!
53 /*!
53 \fn void QXYSeries::pointAdded(int index)
54 \fn void QXYSeries::pointAdded(int index)
54 \brief \internal \a index
55 \brief \internal \a index
55 */
56 */
56
57
57 /*!
58 /*!
58 \fn void QXYSeries::pointRemoved(int index)
59 \fn void QXYSeries::pointRemoved(int index)
59 \brief \internal \a index
60 \brief \internal \a index
60 */
61 */
61
62
62 /*!
63 /*!
63 \fn void QXYSeries::updated()
64 \fn void QXYSeries::updated()
64 \brief \internal
65 \brief \internal
65 */
66 */
66
67
67 /*!
68 /*!
68 Constructs empty series object which is a child of \a parent.
69 Constructs empty series object which is a child of \a parent.
69 When series object is added to QChartView or QChart instance ownerships is transfered.
70 When series object is added to QChartView or QChart instance ownerships is transfered.
70 */
71 */
71 QXYSeries::QXYSeries(QObject *parent):QSeries(parent)
72 QXYSeries::QXYSeries(QObject *parent):QSeries(parent)
72 {
73 {
73 m_mapX = -1;
74 m_mapX = -1;
74 m_mapY = -1;
75 m_mapY = -1;
75 m_mapFirst = 0;
76 m_mapFirst = 0;
76 m_mapCount = 0;
77 m_mapCount = 0;
77 m_mapLimited = false;
78 m_mapLimited = false;
78 m_mapOrientation = Qt::Vertical;
79 m_mapOrientation = Qt::Vertical;
79 // m_mapYOrientation = Qt::Vertical;
80 // m_mapYOrientation = Qt::Vertical;
80 }
81 }
81 /*!
82 /*!
82 Destroys the object. Series added to QChartView or QChart instances are owned by those,
83 Destroys the object. Series added to QChartView or QChart instances are owned by those,
83 and are deleted when mentioned object are destroyed.
84 and are deleted when mentioned object are destroyed.
84 */
85 */
85 QXYSeries::~QXYSeries()
86 QXYSeries::~QXYSeries()
86 {
87 {
87 }
88 }
88
89
89 /*!
90 /*!
90 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
91 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
91 */
92 */
92 void QXYSeries::append(qreal x,qreal y)
93 void QXYSeries::append(qreal x,qreal y)
93 {
94 {
94 Q_ASSERT(m_x.size() == m_y.size());
95 Q_ASSERT(m_x.size() == m_y.size());
95 m_x<<x;
96 m_x<<x;
96 m_y<<y;
97 m_y<<y;
97 emit pointAdded(m_x.size()-1);
98 emit pointAdded(m_x.size()-1);
98 }
99 }
99
100
100 /*!
101 /*!
101 This is an overloaded function.
102 This is an overloaded function.
102 Adds data \a point to the series. Points are connected with lines on the chart.
103 Adds data \a point to the series. Points are connected with lines on the chart.
103 */
104 */
104 void QXYSeries::append(const QPointF &point)
105 void QXYSeries::append(const QPointF &point)
105 {
106 {
106 append(point.x(),point.y());
107 append(point.x(),point.y());
107 }
108 }
108
109
109 /*!
110 /*!
110 This is an overloaded function.
111 This is an overloaded function.
111 Adds list of data \a points to the series. Points are connected with lines on the chart.
112 Adds list of data \a points to the series. Points are connected with lines on the chart.
112 */
113 */
113 void QXYSeries::append(const QList<QPointF> points)
114 void QXYSeries::append(const QList<QPointF> points)
114 {
115 {
115 foreach(const QPointF& point , points) {
116 foreach(const QPointF& point , points) {
116 append(point.x(),point.y());
117 append(point.x(),point.y());
117 }
118 }
118 }
119 }
119
120
120 /*!
121 /*!
121 Modifies \a y value for given \a x a value.
122 Modifies \a y value for given \a x a value.
122 */
123 */
123 void QXYSeries::replace(qreal x,qreal y)
124 void QXYSeries::replace(qreal x,qreal y)
124 {
125 {
125 int index = m_x.indexOf(x);
126 int index = m_x.indexOf(x);
126 m_x[index] = x;
127 m_x[index] = x;
127 m_y[index] = y;
128 m_y[index] = y;
128 emit pointReplaced(index);
129 emit pointReplaced(index);
129 }
130 }
130
131
131 /*!
132 /*!
132 This is an overloaded function.
133 This is an overloaded function.
133 Replaces current y value of for given \a point x value with \a point y value.
134 Replaces current y value of for given \a point x value with \a point y value.
134 */
135 */
135 void QXYSeries::replace(const QPointF &point)
136 void QXYSeries::replace(const QPointF &point)
136 {
137 {
137 replace(point.x(),point.y());
138 replace(point.x(),point.y());
138 }
139 }
139
140
140 /*!
141 /*!
141 Removes first \a x value and related y value.
142 Removes first \a x value and related y value.
142 */
143 */
143 void QXYSeries::remove(qreal x)
144 void QXYSeries::remove(qreal x)
144 {
145 {
145 int index = m_x.indexOf(x);
146 int index = m_x.indexOf(x);
146
147
147 if (index == -1) return;
148 if (index == -1) return;
148
149
149 m_x.remove(index);
150 m_x.remove(index);
150 m_y.remove(index);
151 m_y.remove(index);
151
152
152 emit pointRemoved(index);
153 emit pointRemoved(index);
153 }
154 }
154
155
155 /*!
156 /*!
156 Removes current \a x and \a y value.
157 Removes current \a x and \a y value.
157 */
158 */
158 void QXYSeries::remove(qreal x,qreal y)
159 void QXYSeries::remove(qreal x,qreal y)
159 {
160 {
160 int index =-1;
161 int index =-1;
161 do {
162 do {
162 index = m_x.indexOf(x,index+1);
163 index = m_x.indexOf(x,index+1);
163 } while (index !=-1 && m_y.at(index)!=y);
164 } while (index !=-1 && m_y.at(index)!=y);
164
165
165 if (index==-1) return;
166 if (index==-1) return;
166
167
167 m_x.remove(index);
168 m_x.remove(index);
168 m_y.remove(index);
169 m_y.remove(index);
169 emit pointRemoved(index);
170 emit pointRemoved(index);
170 }
171 }
171
172
172 /*!
173 /*!
173 Removes current \a point x value. Note \a point y value is ignored.
174 Removes current \a point x value. Note \a point y value is ignored.
174 */
175 */
175 void QXYSeries::remove(const QPointF &point)
176 void QXYSeries::remove(const QPointF &point)
176 {
177 {
177 remove(point.x(),point.y());
178 remove(point.x(),point.y());
178 }
179 }
179
180
180 /*!
181 /*!
181 Removes all data points from the series.
182 Removes all data points from the series.
182 */
183 */
183 void QXYSeries::removeAll()
184 void QXYSeries::removeAll()
184 {
185 {
185 m_x.clear();
186 m_x.clear();
186 m_y.clear();
187 m_y.clear();
187 }
188 }
188
189
189 /*!
190 /*!
190 \internal \a pos
191 \internal \a pos
191 */
192 */
192 qreal QXYSeries::x(int pos) const
193 qreal QXYSeries::x(int pos) const
193 {
194 {
194 if (m_model) {
195 if (m_model) {
195 if (m_mapOrientation == Qt::Vertical)
196 if (m_mapOrientation == Qt::Vertical)
196 // consecutive data is read from model's column
197 // consecutive data is read from model's column
197 return m_model->data(m_model->index(pos + m_mapFirst, m_mapX), Qt::DisplayRole).toDouble();
198 return m_model->data(m_model->index(pos + m_mapFirst, m_mapX), Qt::DisplayRole).toDouble();
198 else
199 else
199 // consecutive data is read from model's row
200 // consecutive data is read from model's row
200 return m_model->data(m_model->index(m_mapX, pos + m_mapFirst), Qt::DisplayRole).toDouble();
201 return m_model->data(m_model->index(m_mapX, pos + m_mapFirst), Qt::DisplayRole).toDouble();
201 } else {
202 } else {
202 // model is not specified, return the data from series' internal data store
203 // model is not specified, return the data from series' internal data store
203 return m_x.at(pos);
204 return m_x.at(pos);
204 }
205 }
205 }
206 }
206
207
207 /*!
208 /*!
208 \internal \a pos
209 \internal \a pos
209 */
210 */
210 qreal QXYSeries::y(int pos) const
211 qreal QXYSeries::y(int pos) const
211 {
212 {
212 if (m_model) {
213 if (m_model) {
213 if (m_mapOrientation == Qt::Vertical)
214 if (m_mapOrientation == Qt::Vertical)
214 // consecutive data is read from model's column
215 // consecutive data is read from model's column
215 return m_model->data(m_model->index(pos + m_mapFirst, m_mapY), Qt::DisplayRole).toDouble();
216 return m_model->data(m_model->index(pos + m_mapFirst, m_mapY), Qt::DisplayRole).toDouble();
216 else
217 else
217 // consecutive data is read from model's row
218 // consecutive data is read from model's row
218 return m_model->data(m_model->index(m_mapY, pos + m_mapFirst), Qt::DisplayRole).toDouble();
219 return m_model->data(m_model->index(m_mapY, pos + m_mapFirst), Qt::DisplayRole).toDouble();
219 } else {
220 } else {
220 // model is not specified, return the data from series' internal data store
221 // model is not specified, return the data from series' internal data store
221 return m_y.at(pos);
222 return m_y.at(pos);
222 }
223 }
223 }
224 }
224
225
225 /*!
226 /*!
226 Returns number of data points within series.
227 Returns number of data points within series.
227 */
228 */
228 int QXYSeries::count() const
229 int QXYSeries::count() const
229 {
230 {
230 Q_ASSERT(m_x.size() == m_y.size());
231 Q_ASSERT(m_x.size() == m_y.size());
231
232
232 if (m_model) {
233 if (m_model) {
233 if (m_mapOrientation == Qt::Vertical) {
234 if (m_mapOrientation == Qt::Vertical) {
234 // data is in a column. Return the number of mapped items if the model's column have enough items
235 // data is in a column. Return the number of mapped items if the model's column have enough items
235 // or the number of items that can be mapped
236 // or the number of items that can be mapped
236 if (m_mapLimited)
237 if (m_mapLimited)
237 return qMin(m_mapCount, qMax(m_model->rowCount() - m_mapFirst, 0));
238 return qMin(m_mapCount, qMax(m_model->rowCount() - m_mapFirst, 0));
238 else
239 else
239 return qMax(m_model->rowCount() - m_mapFirst, 0);
240 return qMax(m_model->rowCount() - m_mapFirst, 0);
240 } else {
241 } else {
241 // data is in a row. Return the number of mapped items if the model's row have enough items
242 // data is in a row. Return the number of mapped items if the model's row have enough items
242 // or the number of items that can be mapped
243 // or the number of items that can be mapped
243 if (m_mapLimited)
244 if (m_mapLimited)
244 return qMin(m_mapCount, qMax(m_model->columnCount() - m_mapFirst, 0));
245 return qMin(m_mapCount, qMax(m_model->columnCount() - m_mapFirst, 0));
245 else
246 else
246 return qMax(m_model->columnCount() - m_mapFirst, 0);
247 return qMax(m_model->columnCount() - m_mapFirst, 0);
247 }
248 }
248 }
249 }
249
250
250 // model is not specified, return the number of points in the series internal data store
251 // model is not specified, return the number of points in the series internal data store
251 return m_x.size();
252 return m_x.size();
252 }
253 }
253
254
254 /*!
255 /*!
255 Returns the data points of the series.
256 Returns the data points of the series.
256 */
257 */
257 QList<QPointF> QXYSeries::data()
258 QList<QPointF> QXYSeries::data()
258 {
259 {
259 QList<QPointF> data;
260 QList<QPointF> data;
260 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
261 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
261 data.append(QPointF(m_x.at(i), m_y.at(i)));
262 data.append(QPointF(m_x.at(i), m_y.at(i)));
262 return data;
263 return data;
263 }
264 }
264
265
265
266
266 /*!
267 /*!
267 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
268 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
268 pen from chart theme is used.
269 pen from chart theme is used.
269 \sa QChart::setChartTheme()
270 \sa QChart::setChartTheme()
270 */
271 */
271 void QXYSeries::setPen(const QPen &pen)
272 void QXYSeries::setPen(const QPen &pen)
272 {
273 {
273 if (pen != m_pen) {
274 if (pen != m_pen) {
274 m_pen = pen;
275 m_pen = pen;
275 emit updated();
276 emit updated();
276 }
277 }
277 }
278 }
278
279
279 /*!
280 /*!
280 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
281 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
281 from chart theme setting is used.
282 from chart theme setting is used.
282 \sa QChart::setChartTheme()
283 \sa QChart::setChartTheme()
283 */
284 */
284
285
285 void QXYSeries::setBrush(const QBrush &brush)
286 void QXYSeries::setBrush(const QBrush &brush)
286 {
287 {
287 if (brush != m_brush) {
288 if (brush != m_brush) {
288 m_brush = brush;
289 m_brush = brush;
289 emit updated();
290 emit updated();
290 }
291 }
291 }
292 }
292
293
293
294
294 /*!
295 /*!
295 Stream operator for adding a data \a point to the series.
296 Stream operator for adding a data \a point to the series.
296 \sa append()
297 \sa append()
297 */
298 */
298
299
299 QXYSeries& QXYSeries::operator<< (const QPointF &point)
300 QXYSeries& QXYSeries::operator<< (const QPointF &point)
300 {
301 {
301 append(point);
302 append(point);
302 return *this;
303 return *this;
303 }
304 }
304
305
305
306
306 /*!
307 /*!
307 Stream operator for adding a list of \a points to the series.
308 Stream operator for adding a list of \a points to the series.
308 \sa append()
309 \sa append()
309 */
310 */
310
311
311 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
312 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
312 {
313 {
313 append(points);
314 append(points);
314 return *this;
315 return *this;
315 }
316 }
316
317
317
318
318 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
319 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
319 {
320 {
320 Q_UNUSED(bottomRight)
321 Q_UNUSED(bottomRight)
321
322
322 if (m_mapOrientation == Qt::Vertical) {
323 if (m_mapOrientation == Qt::Vertical) {
323 if (topLeft.row() >= m_mapFirst && (!m_mapLimited || topLeft.row() < m_mapFirst + m_mapCount))
324 if (topLeft.row() >= m_mapFirst && (!m_mapLimited || topLeft.row() < m_mapFirst + m_mapCount))
324 emit pointReplaced(topLeft.row() - m_mapFirst);
325 emit pointReplaced(topLeft.row() - m_mapFirst);
325 } else {
326 } else {
326 if (topLeft.column() >= m_mapFirst && (!m_mapLimited || topLeft.column() < m_mapFirst + m_mapCount))
327 if (topLeft.column() >= m_mapFirst && (!m_mapLimited || topLeft.column() < m_mapFirst + m_mapCount))
327 emit pointReplaced(topLeft.column() - m_mapFirst);
328 emit pointReplaced(topLeft.column() - m_mapFirst);
328 }
329 }
329 }
330 }
330
331
331 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
332 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
332 {
333 {
333 Q_UNUSED(parent)
334 Q_UNUSED(parent)
334 // Q_UNUSED(end)
335 // Q_UNUSED(end)
335
336
336 if (m_mapLimited) {
337 if (m_mapLimited) {
337 if (start >= m_mapFirst + m_mapCount) {
338 if (start >= m_mapFirst + m_mapCount) {
338 // the added data is below mapped area
339 // the added data is below mapped area
339 // therefore it has no relevance
340 // therefore it has no relevance
340 return;
341 return;
341 } else {
342 } else {
342 // the added data is in the mapped area or before it and update is needed
343 // the added data is in the mapped area or before it and update is needed
343
344
344 // check how many mapped items there is currently (before new items are added)
345 // check how many mapped items there is currently (before new items are added)
345 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
346 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
346 // internal storage before new ones can be added
347 // internal storage before new ones can be added
347
348
348 int itemsToRemove = qMin(count() - qMax(start - m_mapFirst, 0), end - start + 1);
349 int itemsToRemove = qMin(count() - qMax(start - m_mapFirst, 0), end - start + 1);
349 if (m_mapCount == count()) {
350 if (m_mapCount == count()) {
350 for (int i = 0; i < itemsToRemove; i++)
351 for (int i = 0; i < itemsToRemove; i++)
351 emit pointRemoved(qMin(end, count()) - i);
352 emit pointRemoved(qMin(end, count()) - i);
352 }
353 }
353 }
354 }
354 } else {
355 } else {
355 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
356 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
356 // nothing to do
357 // nothing to do
357 // emit pointAdded(qMax(start - m_mapFirst, 0));
358 // emit pointAdded(qMax(start - m_mapFirst, 0));
358 }
359 }
359 }
360 }
360
361
361 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
362 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
362 {
363 {
363 Q_UNUSED(parent)
364 Q_UNUSED(parent)
364 // Q_UNUSED(end)
365 // Q_UNUSED(end)
365
366
366 if (m_mapLimited) {
367 if (m_mapLimited) {
367 if (start >= m_mapFirst + m_mapCount) {
368 if (start >= m_mapFirst + m_mapCount) {
368 // the added data is below mapped area
369 // the added data is below mapped area
369 // therefore it has no relevance
370 // therefore it has no relevance
370 return;
371 return;
371 } else {
372 } else {
372 // the added data is in the mapped area or before it
373 // the added data is in the mapped area or before it
373 // update needed
374 // update needed
374 if (count() > 0) {
375 if (count() > 0) {
375 int toBeAdded = qMin(m_mapCount - (start - m_mapFirst), end - start + 1);
376 int toBeAdded = qMin(m_mapCount - (start - m_mapFirst), end - start + 1);
376 for (int i = 0; i < toBeAdded; i++)
377 for (int i = 0; i < toBeAdded; i++)
377 if (start + i >= m_mapFirst)
378 if (start + i >= m_mapFirst)
378 emit pointAdded(start + i);
379 emit pointAdded(start + i);
379 }
380 }
380 }
381 }
381 } else {
382 } else {
382 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
383 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
383 for (int i = 0; i < end - start + 1; i++)
384 for (int i = 0; i < end - start + 1; i++)
384 emit pointAdded(start + i);
385 emit pointAdded(start + i);
385 }
386 }
386 }
387 }
387
388
388 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
389 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
389 {
390 {
390 Q_UNUSED(parent)
391 Q_UNUSED(parent)
391 // Q_UNUSED(end)
392 // Q_UNUSED(end)
392
393
393 if (m_mapLimited) {
394 if (m_mapLimited) {
394 if (start >= m_mapFirst + m_mapCount) {
395 if (start >= m_mapFirst + m_mapCount) {
395 // the removed data is below mapped area
396 // the removed data is below mapped area
396 // therefore it has no relevance
397 // therefore it has no relevance
397 return;
398 return;
398 } else {
399 } else {
399 // the removed data is in the mapped area or before it
400 // the removed data is in the mapped area or before it
400 // update needed
401 // update needed
401
402
402 // check how many items need to be removed from the xychartitem storage
403 // check how many items need to be removed from the xychartitem storage
403 // the number equals the number of items that are removed and that lay before
404 // the number equals the number of items that are removed and that lay before
404 // or in the mapped area. Items that lay beyond the map do not count
405 // or in the mapped area. Items that lay beyond the map do not count
405 // the max is the current number of items in storage (count())
406 // the max is the current number of items in storage (count())
406 int itemsToRemove = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
407 int itemsToRemove = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
407 for (int i = 0; i < itemsToRemove; i++)
408 for (int i = 0; i < itemsToRemove; i++)
408 emit pointRemoved(start);
409 emit pointRemoved(start);
409 }
410 }
410 } else {
411 } else {
411 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
412 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
412 for (int i = 0; i < end - start + 1; i++)
413 for (int i = 0; i < end - start + 1; i++)
413 emit pointRemoved(start);
414 emit pointRemoved(start);
414 }
415 }
415 }
416 }
416
417
417 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
418 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
418 {
419 {
419 Q_UNUSED(parent)
420 Q_UNUSED(parent)
420 Q_UNUSED(end)
421 Q_UNUSED(end)
421
422
422 // how many items there were before data was removed
423 // how many items there were before data was removed
423 // int oldCount = count() - 1;
424 // int oldCount = count() - 1;
424
425
425 if (m_mapLimited) {
426 if (m_mapLimited) {
426 if (start >= m_mapFirst + m_mapCount) {
427 if (start >= m_mapFirst + m_mapCount) {
427 // the removed data is below mapped area
428 // the removed data is below mapped area
428 // therefore it has no relevance
429 // therefore it has no relevance
429 return;
430 return;
430 } else {
431 } else {
431 // if the current items count in the whole model is bigger than the index of the last item
432 // if the current items count in the whole model is bigger than the index of the last item
432 // that was removed than it means there are some extra items available
433 // that was removed than it means there are some extra items available
433
434
434 int removedItemsCount = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
435 int removedItemsCount = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
435 int extraItemsAvailable = 0;
436 int extraItemsAvailable = 0;
436 if (m_mapOrientation == Qt::Vertical) {
437 if (m_mapOrientation == Qt::Vertical) {
437 extraItemsAvailable = qMax(m_model->rowCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
438 extraItemsAvailable = qMax(m_model->rowCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
438 } else {
439 } else {
439 extraItemsAvailable = qMax(m_model->columnCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
440 extraItemsAvailable = qMax(m_model->columnCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
440 }
441 }
441
442
442 // if there are excess items available (below the mapped area) use them to repopulate mapped area
443 // if there are excess items available (below the mapped area) use them to repopulate mapped area
443 int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
444 int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
444 for (int k = 0; k < toBeAdded; k++)
445 for (int k = 0; k < toBeAdded; k++)
445 emit pointAdded(m_mapFirst + m_mapCount - removedItemsCount + k);
446 emit pointAdded(m_mapFirst + m_mapCount - removedItemsCount + k);
446 }
447 }
447 } else {
448 } else {
448 // data was removed from XYSeries interal storage. Nothing more to do
449 // data was removed from XYSeries interal storage. Nothing more to do
449 }
450 }
450 }
451 }
451
452
452 bool QXYSeries::setModel(QAbstractItemModel *model) {
453 bool QXYSeries::setModel(QAbstractItemModel *model) {
453
454
454 // disconnect signals from old model
455 // disconnect signals from old model
455 if (m_model) {
456 if (m_model) {
456 disconnect(m_model, 0, this, 0);
457 disconnect(m_model, 0, this, 0);
457 m_mapX = -1;
458 m_mapX = -1;
458 m_mapY = -1;
459 m_mapY = -1;
459 m_mapFirst = 0;
460 m_mapFirst = 0;
460 m_mapCount = 0;
461 m_mapCount = 0;
461 m_mapLimited = false;
462 m_mapLimited = false;
462 m_mapOrientation = Qt::Vertical;
463 m_mapOrientation = Qt::Vertical;
463 }
464 }
464
465
465 // set new model
466 // set new model
466 if (model) {
467 if (model) {
467 m_model = model;
468 m_model = model;
468 return true;
469 return true;
469 } else {
470 } else {
470 m_model = 0;
471 m_model = 0;
471 return false;
472 return false;
472 }
473 }
473 }
474 }
474
475
475 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
476 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
476 {
477 {
477 if (m_model == 0)
478 if (m_model == 0)
478 return;
479 return;
479 m_mapX = modelX;
480 m_mapX = modelX;
480 m_mapY = modelY;
481 m_mapY = modelY;
481 m_mapFirst = 0;
482 m_mapFirst = 0;
482 m_mapOrientation = orientation;
483 m_mapOrientation = orientation;
483 if (m_mapOrientation == Qt::Vertical) {
484 if (m_mapOrientation == Qt::Vertical) {
484 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
485 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
485 connect(m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
486 connect(m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
486 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
487 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
487 connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
488 connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
488 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
489 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
489 } else {
490 } else {
490 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
491 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
491 connect(m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
492 connect(m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
492 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
493 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
493 connect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
494 connect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
494 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
495 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
495 }
496 }
496 }
497 }
497
498
498 void QXYSeries::setModelMappingShift(int first, int count)
499 void QXYSeries::setModelMappingShift(int first, int count)
499 {
500 {
500 m_mapFirst = first;
501 m_mapFirst = first;
501 if (count == 0) {
502 if (count == 0) {
502 m_mapLimited = false;
503 m_mapLimited = false;
503 } else {
504 } else {
504 m_mapCount = count;
505 m_mapCount = count;
505 m_mapLimited = true;
506 m_mapLimited = true;
506 }
507 }
507 }
508 }
508
509
509 #include "moc_qxyseries.cpp"
510 #include "moc_qxyseries.cpp"
510
511
511 QTCOMMERCIALCHART_END_NAMESPACE
512 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now