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