##// END OF EJS Templates
Added documentation for model related funtions
Marek Rosa -
r900:4e59f6549e80
parent child
Show More
@@ -1,84 +1,82
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "tablewidget.h"
21 #include "tablewidget.h"
22 #include "customtablemodel.h"
22 #include "customtablemodel.h"
23 #include <QGridLayout>
23 #include <QGridLayout>
24 #include <QTableView>
24 #include <QTableView>
25 #include <QChart>
25 #include <QChart>
26 #include <QChartView>
26 #include <QChartView>
27 #include <QLineSeries>
27 #include <QLineSeries>
28
28
29 QTCOMMERCIALCHART_USE_NAMESPACE
29 QTCOMMERCIALCHART_USE_NAMESPACE
30
30
31 TableWidget::TableWidget(QWidget *parent)
31 TableWidget::TableWidget(QWidget *parent)
32 : QWidget(parent)
32 : QWidget(parent)
33 {
33 {
34 // create simple model for storing data
34 // create simple model for storing data
35 // user's table data model
35 // user's table data model
36 CustomTableModel *model = new CustomTableModel;
36 CustomTableModel *model = new CustomTableModel;
37
37
38 // create table view and add model to it
38 // create table view and add model to it
39 QTableView *tableView = new QTableView;
39 QTableView *tableView = new QTableView;
40 tableView->setModel(model);
40 tableView->setModel(model);
41 // tableView->
42 // tableView->setMinimumWidth(200);
43 tableView->setColumnWidth(0, 56);
41 tableView->setColumnWidth(0, 56);
44 tableView->setColumnWidth(1, 56);
42 tableView->setColumnWidth(1, 56);
45 tableView->setColumnWidth(2, 56);
43 tableView->setColumnWidth(2, 56);
46 tableView->setColumnWidth(3, 56);
44 tableView->setColumnWidth(3, 56);
47
45
48 QChart *m_chart = new QChart;
46 QChart *m_chart = new QChart;
49 m_chart->setAnimationOptions(QChart::AllAnimations);
47 m_chart->setAnimationOptions(QChart::AllAnimations);
50 QChartView *m_chartView = new QChartView(m_chart);
48 QChartView *m_chartView = new QChartView(m_chart);
51 m_chartView->setRenderHint(QPainter::Antialiasing);
49 m_chartView->setRenderHint(QPainter::Antialiasing);
52 m_chartView->setMinimumSize(640, 480);
50 m_chartView->setMinimumSize(640, 480);
53
51
54 // for storing color hex from the series
52 // for storing color hex from the series
55 QString seriesColorHex = "#000000";
53 QString seriesColorHex = "#000000";
56
54
57 // series 1
55 // series 1
58 QLineSeries *m_series = new QLineSeries;
56 QLineSeries *m_series = new QLineSeries;
59 m_series->setModel(model);
57 m_series->setModel(model);
60 m_series->setModelMapping(0, 1, Qt::Vertical);
58 m_series->setModelMapping(0, 1, Qt::Vertical);
61 m_chart->addSeries(m_series);
59 m_chart->addSeries(m_series);
62
60
63 // get the color of the series and use it for showing the mapped area
61 // get the color of the series and use it for showing the mapped area
64 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
62 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
65 model->addMapping(seriesColorHex, QRect(0, 0, 2, model->rowCount()));
63 model->addMapping(seriesColorHex, QRect(0, 0, 2, model->rowCount()));
66
64
67 // series 2
65 // series 2
68 m_series = new QLineSeries;
66 m_series = new QLineSeries;
69 m_series->setModel(model);
67 m_series->setModel(model);
70 m_series->setModelMapping(2,3, Qt::Vertical);
68 m_series->setModelMapping(2,3, Qt::Vertical);
71 m_chart->addSeries(m_series);
69 m_chart->addSeries(m_series);
72
70
73 // get the color of the series and use it for showing the mapped area
71 // get the color of the series and use it for showing the mapped area
74 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
72 seriesColorHex = "#" + QString::number(m_series->pen().color().rgb(), 16).right(6).toUpper();
75 model->addMapping(seriesColorHex, QRect(2, 0, 2, model->rowCount()));
73 model->addMapping(seriesColorHex, QRect(2, 0, 2, model->rowCount()));
76
74
77 // create main layout
75 // create main layout
78 QGridLayout* mainLayout = new QGridLayout;
76 QGridLayout* mainLayout = new QGridLayout;
79 mainLayout->addWidget(tableView, 1, 0);
77 mainLayout->addWidget(tableView, 1, 0);
80 mainLayout->addWidget(m_chartView, 1, 1);
78 mainLayout->addWidget(m_chartView, 1, 1);
81 mainLayout->setColumnStretch(1, 1);
79 mainLayout->setColumnStretch(1, 1);
82 mainLayout->setColumnStretch(0, 0);
80 mainLayout->setColumnStretch(0, 0);
83 setLayout(mainLayout);
81 setLayout(mainLayout);
84 }
82 }
@@ -1,450 +1,459
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 #include <QAbstractItemModel>
26 #include <QModelIndex>
26 #include <QModelIndex>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 /*!
30 /*!
31 \class QBarSeries
31 \class QBarSeries
32 \brief part of QtCommercial chart API.
32 \brief part of QtCommercial chart API.
33
33
34 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
34 QBarSeries represents a series of data shown as bars. One QBarSeries can contain multible
35 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
35 QBarSet data sets. QBarSeries groups the data from sets to categories, which are defined
36 by QStringList.
36 by QStringList.
37
37
38 \mainclass
38 \mainclass
39
39
40 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
40 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
41 */
41 */
42
42
43 /*!
43 /*!
44 \fn virtual QSeriesType QBarSeries::type() const
44 \fn virtual QSeriesType QBarSeries::type() const
45 \brief Returns type of series.
45 \brief Returns type of series.
46 \sa QSeries, QSeriesType
46 \sa QSeries, QSeriesType
47 */
47 */
48
48
49 /*!
49 /*!
50 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
50 \fn void QBarSeries::showToolTip(QPoint pos, QString tip)
51 \brief \internal \a pos \a tip
51 \brief \internal \a pos \a tip
52 */
52 */
53
53
54 /*!
54 /*!
55 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
55 Constructs empty QBarSeries. Parameter \a categories defines the categories for chart.
56 QBarSeries is QObject which is a child of a \a parent.
56 QBarSeries is QObject which is a child of a \a parent.
57 */
57 */
58 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) : QSeries(parent),
58 QBarSeries::QBarSeries(QBarCategories categories, QObject *parent) : QSeries(parent),
59 m_internalModel(new BarChartModel(categories, this))
59 m_internalModel(new BarChartModel(categories, this))
60 {
60 {
61 m_model = 0;
61 m_model = 0;
62 m_mapCategories = -1;
62 m_mapCategories = -1;
63 m_mapBarBottom = -1;
63 m_mapBarBottom = -1;
64 m_mapBarTop = -1;
64 m_mapBarTop = -1;
65 m_mapFirst = 0;
65 m_mapFirst = 0;
66 m_mapCount = 0;
66 m_mapCount = 0;
67 m_mapOrientation = Qt::Vertical;
67 m_mapOrientation = Qt::Vertical;
68 }
68 }
69
69
70 /*!
70 /*!
71 Adds a set of bars to series. Takes ownership of \a set.
71 Adds a set of bars to series. Takes ownership of \a set.
72 Connects the clicked(QString, Qt::MouseButtons) signal
72 Connects the clicked(QString, Qt::MouseButtons) signal
73 of \a set to this series
73 of \a set to this series
74 */
74 */
75 void QBarSeries::appendBarSet(QBarSet *set)
75 void QBarSeries::appendBarSet(QBarSet *set)
76 {
76 {
77 m_internalModel->appendBarSet(set);
77 m_internalModel->appendBarSet(set);
78 connect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
78 connect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
79 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
79 connect(set, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
80 emit restructuredBars();
80 emit restructuredBars();
81 }
81 }
82
82
83 /*!
83 /*!
84 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
84 Removes a set of bars from series. Releases ownership of \a set. Doesnt delete \a set.
85 Disconnects the clicked(QString, Qt::MouseButtons) signal
85 Disconnects the clicked(QString, Qt::MouseButtons) signal
86 of \a set from this series
86 of \a set from this series
87 */
87 */
88 void QBarSeries::removeBarSet(QBarSet *set)
88 void QBarSeries::removeBarSet(QBarSet *set)
89 {
89 {
90 disconnect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
90 disconnect(set, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
91 m_internalModel->removeBarSet(set);
91 m_internalModel->removeBarSet(set);
92 emit restructuredBars();
92 emit restructuredBars();
93 }
93 }
94
94
95 /*!
95 /*!
96 Adds a list of barsets to series. Takes ownership of \a sets.
96 Adds a list of barsets to series. Takes ownership of \a sets.
97 Connects the clicked(QString, Qt::MouseButtons) signals
97 Connects the clicked(QString, Qt::MouseButtons) signals
98 of \a sets to this series
98 of \a sets to this series
99 */
99 */
100 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
100 void QBarSeries::appendBarSets(QList<QBarSet* > sets)
101 {
101 {
102 foreach (QBarSet* barset, sets) {
102 foreach (QBarSet* barset, sets) {
103 m_internalModel->appendBarSet(barset);
103 m_internalModel->appendBarSet(barset);
104 connect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
104 connect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
105 connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
105 connect(barset, SIGNAL(valueChanged()), this, SLOT(barsetChanged()));
106 }
106 }
107 emit restructuredBars();
107 emit restructuredBars();
108 }
108 }
109
109
110 /*!
110 /*!
111 Removes a list of barsets from series. Releases ownership of \a set. Doesnt delete \a sets.
111 Removes a list of barsets from series. Releases ownership of \a set. Doesnt delete \a sets.
112 Disconnects the clicked(QString, Qt::MouseButtons) signal
112 Disconnects the clicked(QString, Qt::MouseButtons) signal
113 of \a sets from this series
113 of \a sets from this series
114 */
114 */
115 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
115 void QBarSeries::removeBarSets(QList<QBarSet* > sets)
116 {
116 {
117 foreach (QBarSet* barset, sets) {
117 foreach (QBarSet* barset, sets) {
118 disconnect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
118 disconnect(barset, SIGNAL(clicked(QString,Qt::MouseButtons)), this, SLOT(barsetClicked(QString,Qt::MouseButtons)));
119 m_internalModel->removeBarSet(barset);
119 m_internalModel->removeBarSet(barset);
120 }
120 }
121 emit restructuredBars();
121 emit restructuredBars();
122 }
122 }
123
123
124 void QBarSeries::insertBarSet(int i, QBarSet *set)
124 void QBarSeries::insertBarSet(int i, QBarSet *set)
125 {
125 {
126 m_internalModel->insertBarSet(i, set);
126 m_internalModel->insertBarSet(i, set);
127 // emit barsetChanged();
127 // emit barsetChanged();
128 }
128 }
129
129
130 void QBarSeries::insertCategory(int i, QString category)
130 void QBarSeries::insertCategory(int i, QString category)
131 {
131 {
132 m_internalModel->insertCategory(i, category);
132 m_internalModel->insertCategory(i, category);
133 }
133 }
134
134
135 void QBarSeries::removeCategory(int i)
135 void QBarSeries::removeCategory(int i)
136 {
136 {
137 m_internalModel->removeCategory(i);
137 m_internalModel->removeCategory(i);
138 }
138 }
139
139
140 /*!
140 /*!
141 Returns number of sets in series.
141 Returns number of sets in series.
142 */
142 */
143 int QBarSeries::barsetCount() const
143 int QBarSeries::barsetCount() const
144 {
144 {
145 // if(m_model)
145 // if(m_model)
146 // return m_mapBarTop - m_mapBarBottom;
146 // return m_mapBarTop - m_mapBarBottom;
147 // else
147 // else
148 return m_internalModel->barsetCount();
148 return m_internalModel->barsetCount();
149 }
149 }
150
150
151 /*!
151 /*!
152 Returns number of categories in series
152 Returns number of categories in series
153 */
153 */
154 int QBarSeries::categoryCount() const
154 int QBarSeries::categoryCount() const
155 {
155 {
156 return m_internalModel->categoryCount();
156 return m_internalModel->categoryCount();
157 }
157 }
158
158
159 /*!
159 /*!
160 Returns a list of sets in series. Keeps ownership of sets.
160 Returns a list of sets in series. Keeps ownership of sets.
161 */
161 */
162 QList<QBarSet*> QBarSeries::barSets() const
162 QList<QBarSet*> QBarSeries::barSets() const
163 {
163 {
164 return m_internalModel->barSets();
164 return m_internalModel->barSets();
165 }
165 }
166
166
167 /*!
167 /*!
168 \internal \a index
168 \internal \a index
169 */
169 */
170 QBarSet* QBarSeries::barsetAt(int index)
170 QBarSet* QBarSeries::barsetAt(int index)
171 {
171 {
172 return m_internalModel->barsetAt(index);
172 return m_internalModel->barsetAt(index);
173 }
173 }
174
174
175 /*!
175 /*!
176 \internal \a category
176 \internal \a category
177 */
177 */
178 QString QBarSeries::categoryName(int category)
178 QString QBarSeries::categoryName(int category)
179 {
179 {
180 return m_internalModel->categoryName(category);
180 return m_internalModel->categoryName(category);
181 }
181 }
182
182
183 /*!
183 /*!
184 Enables or disables tooltip depending on parameter \a enabled.
184 Enables or disables tooltip depending on parameter \a enabled.
185 Tooltip shows the name of set, when mouse is hovering on top of bar.
185 Tooltip shows the name of set, when mouse is hovering on top of bar.
186 Calling without parameter \a enabled, enables the tooltip
186 Calling without parameter \a enabled, enables the tooltip
187 */
187 */
188 void QBarSeries::setToolTipEnabled(bool enabled)
188 void QBarSeries::setToolTipEnabled(bool enabled)
189 {
189 {
190 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
190 // TODO: what if we add sets after call to this function? Those sets won't have tooltip enabled.
191 if (enabled) {
191 if (enabled) {
192 for (int i=0; i<m_internalModel->barsetCount(); i++) {
192 for (int i=0; i<m_internalModel->barsetCount(); i++) {
193 QBarSet *set = m_internalModel->barsetAt(i);
193 QBarSet *set = m_internalModel->barsetAt(i);
194 connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
194 connect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
195 }
195 }
196 } else {
196 } else {
197 for (int i=0; i<m_internalModel->barsetCount(); i++) {
197 for (int i=0; i<m_internalModel->barsetCount(); i++) {
198 QBarSet *set = m_internalModel->barsetAt(i);
198 QBarSet *set = m_internalModel->barsetAt(i);
199 disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
199 disconnect(set, SIGNAL(showToolTip(QPoint,QString)), this, SIGNAL(showToolTip(QPoint,QString)));
200 }
200 }
201 }
201 }
202 }
202 }
203
203
204
204
205 /*!
205 /*!
206 \internal \a category
206 \internal \a category
207 */
207 */
208 void QBarSeries::barsetClicked(QString category, Qt::MouseButtons button)
208 void QBarSeries::barsetClicked(QString category, Qt::MouseButtons button)
209 {
209 {
210 emit clicked(qobject_cast<QBarSet*>(sender()), category, button);
210 emit clicked(qobject_cast<QBarSet*>(sender()), category, button);
211 }
211 }
212
212
213 /*!
213 /*!
214 \internal
214 \internal
215 */
215 */
216 qreal QBarSeries::min()
216 qreal QBarSeries::min()
217 {
217 {
218 return m_internalModel->min();
218 return m_internalModel->min();
219 }
219 }
220
220
221 /*!
221 /*!
222 \internal
222 \internal
223 */
223 */
224 qreal QBarSeries::max()
224 qreal QBarSeries::max()
225 {
225 {
226 return m_internalModel->max();
226 return m_internalModel->max();
227 }
227 }
228
228
229 /*!
229 /*!
230 \internal \a set \a category
230 \internal \a set \a category
231 */
231 */
232 qreal QBarSeries::valueAt(int set, int category)
232 qreal QBarSeries::valueAt(int set, int category)
233 {
233 {
234 return m_internalModel->valueAt(set, category);
234 return m_internalModel->valueAt(set, category);
235 }
235 }
236
236
237 /*!
237 /*!
238 \internal \a set \a category
238 \internal \a set \a category
239 */
239 */
240 qreal QBarSeries::percentageAt(int set, int category)
240 qreal QBarSeries::percentageAt(int set, int category)
241 {
241 {
242 return m_internalModel->percentageAt(set, category);
242 return m_internalModel->percentageAt(set, category);
243 }
243 }
244
244
245 /*!
245 /*!
246 \internal \a category
246 \internal \a category
247 */
247 */
248 qreal QBarSeries::categorySum(int category)
248 qreal QBarSeries::categorySum(int category)
249 {
249 {
250 return m_internalModel->categorySum(category);
250 return m_internalModel->categorySum(category);
251 }
251 }
252
252
253 /*!
253 /*!
254 \internal \a category
254 \internal \a category
255 */
255 */
256 qreal QBarSeries::absoluteCategorySum(int category)
256 qreal QBarSeries::absoluteCategorySum(int category)
257 {
257 {
258 return m_internalModel->absoluteCategorySum(category);
258 return m_internalModel->absoluteCategorySum(category);
259 }
259 }
260
260
261 /*!
261 /*!
262 \internal
262 \internal
263 */
263 */
264 qreal QBarSeries::maxCategorySum()
264 qreal QBarSeries::maxCategorySum()
265 {
265 {
266 return m_internalModel->maxCategorySum();
266 return m_internalModel->maxCategorySum();
267 }
267 }
268
268
269 /*!
269 /*!
270 \internal
270 \internal
271 */
271 */
272 BarChartModel& QBarSeries::modelInternal()
272 BarChartModel& QBarSeries::modelInternal()
273 {
273 {
274 return *m_internalModel;
274 return *m_internalModel;
275 }
275 }
276
276
277 /*!
277 /*!
278 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
278 \fn bool QBarSeries::setModel(QAbstractItemModel *model)
279 Sets the \a model to be used as a data source
279 Sets the \a model to be used as a data source
280 */
280 */
281 bool QBarSeries::setModel(QAbstractItemModel *model)
281 bool QBarSeries::setModel(QAbstractItemModel *model)
282 {
282 {
283 // disconnect signals from old model
283 // disconnect signals from old model
284 if(m_model)
284 if(m_model)
285 {
285 {
286 disconnect(m_model, 0, this, 0);
286 disconnect(m_model, 0, this, 0);
287 m_mapCategories = -1;
287 m_mapCategories = -1;
288 m_mapBarBottom = -1;
288 m_mapBarBottom = -1;
289 m_mapBarTop = -1;
289 m_mapBarTop = -1;
290 m_mapFirst = 0;
290 m_mapFirst = 0;
291 m_mapCount = 0;
291 m_mapCount = 0;
292 m_mapOrientation = Qt::Vertical;
292 m_mapOrientation = Qt::Vertical;
293 }
293 }
294
294
295 // set new model
295 // set new model
296 if(model)
296 if(model)
297 {
297 {
298 m_model = model;
298 m_model = model;
299 return true;
299 return true;
300 }
300 }
301 else
301 else
302 {
302 {
303 m_model = 0;
303 m_model = 0;
304 return false;
304 return false;
305 }
305 }
306 }
306 }
307
307
308 // TODO
308 /*!
309 \fn bool QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
310 Sets column/row specified by \a categories to be used as a list of bar series categories.
311 Parameter \a bottomBoundry indicates the column/row where the first bar set is located in the model.
312 Parameter \a topBoundry indicates the column/row where the last bar set is located in the model.
313 All the columns/rows inbetween those two values are also used as data for bar sets.
314 The \a orientation paramater specifies whether the data is in columns or in rows.
315 */
309 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
316 void QBarSeries::setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation)
310 {
317 {
311 if (!m_model)
318 if (!m_model)
312 return;
319 return;
313
320
314 m_mapCategories = categories;
321 m_mapCategories = categories;
315 m_mapBarBottom = bottomBoundry;
322 m_mapBarBottom = bottomBoundry;
316 m_mapBarTop = topBoundry;
323 m_mapBarTop = topBoundry;
317 // m_mapFirst = 1;
324 // m_mapFirst = 1;
318 m_mapOrientation = orientation;
325 m_mapOrientation = orientation;
319
326
320 // connect the signals
327 // connect the signals
321 if (m_mapOrientation == Qt::Vertical) {
328 if (m_mapOrientation == Qt::Vertical) {
322 m_mapCount = m_model->rowCount() - m_mapFirst;
329 m_mapCount = m_model->rowCount() - m_mapFirst;
323 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
330 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
324 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
331 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
325 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)),
332 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)),
326 this, SLOT(modelDataAdded(QModelIndex,int,int)));
333 this, SLOT(modelDataAdded(QModelIndex,int,int)));
327 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
334 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)),
328 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
335 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
329 } else {
336 } else {
330 m_mapCount = m_model->columnCount() - m_mapFirst;
337 m_mapCount = m_model->columnCount() - m_mapFirst;
331 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
338 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
332 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
339 this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
333 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)),
340 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)),
334 this, SLOT(modelDataAdded(QModelIndex,int,int)));
341 this, SLOT(modelDataAdded(QModelIndex,int,int)));
335 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
342 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)),
336 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
343 this, SLOT(modelDataRemoved(QModelIndex,int,int)));
337 }
344 }
338
345
339
340 // create the initial bars
346 // create the initial bars
341 delete m_internalModel;
347 delete m_internalModel;
342 if (m_mapOrientation == Qt::Vertical) {
348 if (m_mapOrientation == Qt::Vertical) {
343 QStringList categories;
349 QStringList categories;
344 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
350 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
345 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
351 categories << m_model->data(m_model->index(k, m_mapCategories), Qt::DisplayRole).toString();
346 m_internalModel = new BarChartModel(categories, this);
352 m_internalModel = new BarChartModel(categories, this);
347
353
348 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
354 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
349 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
355 QBarSet* barSet = new QBarSet(QString("Column: %1").arg(i + 1));
350 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
356 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
351 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
357 *barSet << m_model->data(m_model->index(m, i), Qt::DisplayRole).toDouble();
352 appendBarSet(barSet);
358 appendBarSet(barSet);
353 }
359 }
354 } else {
360 } else {
355 QStringList categories;
361 QStringList categories;
356 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
362 for (int k = m_mapFirst; k < m_mapFirst + m_mapCount; k++)
357 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
363 categories << m_model->data(m_model->index(m_mapCategories, k), Qt::DisplayRole).toString();
358 m_internalModel = new BarChartModel(categories, this);
364 m_internalModel = new BarChartModel(categories, this);
359
365
360 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
366 for (int i = m_mapBarBottom; i <= m_mapBarTop; i++) {
361 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
367 QBarSet* barSet = new QBarSet(QString("Row: %1").arg(i + 1));
362 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
368 for(int m = m_mapFirst; m < m_mapFirst + m_mapCount; m++)
363 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
369 *barSet << m_model->data(m_model->index(i, m), Qt::DisplayRole).toDouble();
364 appendBarSet(barSet);
370 appendBarSet(barSet);
365 }
371 }
366 }
372 }
367 }
373 }
368
374
369 void QBarSeries::setModelMappingShift(int first, int count)
375 /*!
370 {
376 \internal
371 m_mapFirst = first;
377 */
372 m_mapCount = count;
373 }
374
375 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
378 void QBarSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
376 {
379 {
377 Q_UNUSED(bottomRight)
380 Q_UNUSED(bottomRight)
378
381
379 if (m_mapOrientation == Qt::Vertical)
382 if (m_mapOrientation == Qt::Vertical)
380 {
383 {
381 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
384 // 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.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
385 if (topLeft.column() >= m_mapBarBottom && topLeft.column() <= m_mapBarTop && topLeft.row() >= m_mapFirst && topLeft.row() < m_mapFirst + m_mapCount)
383 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
386 barsetAt(topLeft.column() - m_mapBarBottom)->setValue(topLeft.row() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
384 }
387 }
385 else
388 else
386 {
389 {
387 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
390 // model update is relevant to BarSeries if the change was made to the part of the model that was mapped to BarSeries
388 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
391 if (topLeft.row() >= m_mapBarBottom && topLeft.row() <= m_mapBarTop && topLeft.column() >= m_mapFirst && topLeft.column() < m_mapFirst + m_mapCount)
389 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
392 barsetAt(topLeft.row() - m_mapBarBottom)->setValue(topLeft.column() - m_mapFirst, m_model->data(topLeft, Qt::DisplayRole).toDouble());
390 }
393 }
391 }
394 }
392
395
396 /*!
397 \internal
398 */
393 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
399 void QBarSeries::modelDataAdded(QModelIndex /*parent*/, int start, int /*end*/)
394 {
400 {
395 if (m_mapOrientation == Qt::Vertical) {
401 if (m_mapOrientation == Qt::Vertical) {
396 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
402 insertCategory(start - m_mapFirst, QString("Row: %1").arg(start + 1));
397 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
403 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
398 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
404 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(start, i), Qt::DisplayRole).toDouble());
399 }
405 }
400 } else {
406 } else {
401 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
407 insertCategory(start - m_mapFirst, QString("Column: %1").arg(start + 1));
402 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
408 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++) {
403 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
409 barsetAt(i)->insertValue(start - m_mapFirst, m_model->data(m_model->index(i, start), Qt::DisplayRole).toDouble());
404 }
410 }
405 }
411 }
406 emit restructuredBars();
412 emit restructuredBars();
407 }
413 }
408
414
415 /*!
416 \internal
417 */
409 void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end)
418 void QBarSeries::modelDataRemoved(QModelIndex parent, int start, int end)
410 {
419 {
411 Q_UNUSED(parent)
420 Q_UNUSED(parent)
412 Q_UNUSED(end)
421 Q_UNUSED(end)
413
422
414 removeCategory(start - m_mapFirst);
423 removeCategory(start - m_mapFirst);
415 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
424 for (int i = 0; i <= m_mapBarTop - m_mapBarBottom; i++)
416 {
425 {
417 barsetAt(i)->removeValue(start - m_mapFirst);
426 barsetAt(i)->removeValue(start - m_mapFirst);
418 }
427 }
419 emit restructuredBars();
428 emit restructuredBars();
420 }
429 }
421
430
422 void QBarSeries::barsetChanged()
431 void QBarSeries::barsetChanged()
423 {
432 {
424 emit updatedBars();
433 emit updatedBars();
425 }
434 }
426
435
427 QBarCategories QBarSeries::categories() const
436 QBarCategories QBarSeries::categories() const
428 {
437 {
429 QBarCategories categories;
438 QBarCategories categories;
430 int count = m_internalModel->categoryCount();
439 int count = m_internalModel->categoryCount();
431 for (int i=1; i <= count; i++) {
440 for (int i=1; i <= count; i++) {
432 categories.insert(i, m_internalModel->categoryName(i - 1));
441 categories.insert(i, m_internalModel->categoryName(i - 1));
433 }
442 }
434 return categories;
443 return categories;
435 }
444 }
436
445
437 /*!
446 /*!
438 Sets the visibility of labels in series to \a visible
447 Sets the visibility of labels in series to \a visible
439 */
448 */
440 void QBarSeries::setLabelsVisible(bool visible)
449 void QBarSeries::setLabelsVisible(bool visible)
441 {
450 {
442 foreach (QBarSet* s, barSets()) {
451 foreach (QBarSet* s, barSets()) {
443 s->setLabelsVisible(visible);
452 s->setLabelsVisible(visible);
444 }
453 }
445 }
454 }
446
455
447
456
448 #include "moc_qbarseries.cpp"
457 #include "moc_qbarseries.cpp"
449
458
450 QTCOMMERCIALCHART_END_NAMESPACE
459 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,120 +1,119
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #ifndef BARSERIES_H
21 #ifndef BARSERIES_H
22 #define BARSERIES_H
22 #define BARSERIES_H
23
23
24 #include <qseries.h>
24 #include <qseries.h>
25 #include <QStringList>
25 #include <QStringList>
26
26
27 class QModelIndex;
27 class QModelIndex;
28
28
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30
30
31 typedef QStringList QBarCategories;
31 typedef QStringList QBarCategories;
32
32
33 class QBarSet;
33 class QBarSet;
34 class BarChartModel;
34 class BarChartModel;
35 class BarCategory;
35 class BarCategory;
36
36
37 // Container for series
37 // Container for series
38 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
38 class QTCOMMERCIALCHART_EXPORT QBarSeries : public QSeries
39 {
39 {
40 Q_OBJECT
40 Q_OBJECT
41 public:
41 public:
42 QBarSeries(QStringList categories, QObject *parent = 0);
42 QBarSeries(QStringList categories, QObject *parent = 0);
43
43
44 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
44 virtual QSeriesType type() const { return QSeries::SeriesTypeBar; }
45
45
46 void appendBarSet(QBarSet *set); // Takes ownership of set
46 void appendBarSet(QBarSet *set); // Takes ownership of set
47 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
47 void removeBarSet(QBarSet *set); // Releases ownership, doesn't delete set
48 void appendBarSets(QList<QBarSet* > sets);
48 void appendBarSets(QList<QBarSet* > sets);
49 void removeBarSets(QList<QBarSet* > sets);
49 void removeBarSets(QList<QBarSet* > sets);
50 void insertBarSet(int i, QBarSet *set);
50 void insertBarSet(int i, QBarSet *set);
51 void insertCategory(int i, QString category);
51 void insertCategory(int i, QString category);
52 void removeCategory(int i);
52 void removeCategory(int i);
53 int barsetCount() const;
53 int barsetCount() const;
54 int categoryCount() const;
54 int categoryCount() const;
55 QList<QBarSet*> barSets() const;
55 QList<QBarSet*> barSets() const;
56 QBarCategories categories() const;
56 QBarCategories categories() const;
57
57
58 void setLabelsVisible(bool visible = true);
58 void setLabelsVisible(bool visible = true);
59
59
60 bool setModel(QAbstractItemModel *model);
60 bool setModel(QAbstractItemModel *model);
61 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
61 void setModelMapping(int categories, int bottomBoundry, int topBoundry, Qt::Orientation orientation = Qt::Vertical);
62 void setModelMappingShift(int first, int count);
63
62
64 public:
63 public:
65 // TODO: Functions below this are not part of api and will be moved
64 // TODO: Functions below this are not part of api and will be moved
66 // to private implementation, when we start using it
65 // to private implementation, when we start using it
67 // TODO: TO PIMPL --->
66 // TODO: TO PIMPL --->
68 QBarSet* barsetAt(int index);
67 QBarSet* barsetAt(int index);
69 QString categoryName(int category);
68 QString categoryName(int category);
70 qreal min();
69 qreal min();
71 qreal max();
70 qreal max();
72 qreal valueAt(int set, int category);
71 qreal valueAt(int set, int category);
73 qreal percentageAt(int set, int category);
72 qreal percentageAt(int set, int category);
74 qreal categorySum(int category);
73 qreal categorySum(int category);
75 qreal absoluteCategorySum(int category);
74 qreal absoluteCategorySum(int category);
76 qreal maxCategorySum();
75 qreal maxCategorySum();
77 BarChartModel& modelInternal();
76 BarChartModel& modelInternal();
78 // <--- TO PIMPL
77 // <--- TO PIMPL
79
78
80 Q_SIGNALS:
79 Q_SIGNALS:
81 void clicked(QBarSet *barset, QString category, Qt::MouseButtons button); // Up to user of api, what to do with these signals
80 void clicked(QBarSet *barset, QString category, Qt::MouseButtons button); // Up to user of api, what to do with these signals
82 void selected();
81 void selected();
83 //
82 //
84 void updatedBars();
83 void updatedBars();
85 void restructuredBars();
84 void restructuredBars();
86
85
87 // TODO: internal signals, these to private implementation.
86 // TODO: internal signals, these to private implementation.
88 // TODO: TO PIMPL --->
87 // TODO: TO PIMPL --->
89 void showToolTip(QPoint pos, QString tip);
88 void showToolTip(QPoint pos, QString tip);
90 // <--- TO PIMPL
89 // <--- TO PIMPL
91
90
92 public Q_SLOTS:
91 public Q_SLOTS:
93 void setToolTipEnabled(bool enabled = true); // enables tooltips
92 void setToolTipEnabled(bool enabled = true); // enables tooltips
94
93
95 // TODO: TO PIMPL --->
94 // TODO: TO PIMPL --->
96 void barsetClicked(QString category, Qt::MouseButtons button);
95 void barsetClicked(QString category, Qt::MouseButtons button);
97 // <--- TO PIMPL
96 // <--- TO PIMPL
98
97
99 private Q_SLOTS:
98 private Q_SLOTS:
100 // slots for updating bars when data in model changes
99 // slots for updating bars when data in model changes
101 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
100 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
102 void modelDataAdded(QModelIndex parent, int start, int end);
101 void modelDataAdded(QModelIndex parent, int start, int end);
103 void modelDataRemoved(QModelIndex parent, int start, int end);
102 void modelDataRemoved(QModelIndex parent, int start, int end);
104 void barsetChanged();
103 void barsetChanged();
105
104
106 protected:
105 protected:
107 BarChartModel *m_internalModel; // TODO: this may change... current "2 models" situation doesn't look good.
106 BarChartModel *m_internalModel; // TODO: this may change... current "2 models" situation doesn't look good.
108
107
109 // QAbstractItemModel* m_model;
108 // QAbstractItemModel* m_model;
110 int m_mapCategories;
109 int m_mapCategories;
111 int m_mapBarBottom;
110 int m_mapBarBottom;
112 int m_mapBarTop;
111 int m_mapBarTop;
113 int m_mapFirst;
112 int m_mapFirst;
114 int m_mapCount;
113 int m_mapCount;
115 Qt::Orientation m_mapOrientation;
114 Qt::Orientation m_mapOrientation;
116 };
115 };
117
116
118 QTCOMMERCIALCHART_END_NAMESPACE
117 QTCOMMERCIALCHART_END_NAMESPACE
119
118
120 #endif // BARSERIES_H
119 #endif // BARSERIES_H
@@ -1,706 +1,713
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 <QAbstractItemModel>
26 #include <QDebug>
26 #include <QDebug>
27
27
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29
29
30 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
30 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent)
31 :QObject(parent),
31 :QObject(parent),
32 q_ptr(parent),
32 q_ptr(parent),
33 m_pieRelativeHorPos(0.5),
33 m_pieRelativeHorPos(0.5),
34 m_pieRelativeVerPos(0.5),
34 m_pieRelativeVerPos(0.5),
35 m_pieRelativeSize(0.7),
35 m_pieRelativeSize(0.7),
36 m_pieStartAngle(0),
36 m_pieStartAngle(0),
37 m_pieEndAngle(360),
37 m_pieEndAngle(360),
38 m_total(0),
38 m_total(0),
39 m_mapValues(0),
39 m_mapValues(0),
40 m_mapLabels(0),
40 m_mapLabels(0),
41 m_mapOrientation(Qt::Horizontal)
41 m_mapOrientation(Qt::Horizontal)
42 {
42 {
43
43
44 }
44 }
45
45
46 QPieSeriesPrivate::~QPieSeriesPrivate()
46 QPieSeriesPrivate::~QPieSeriesPrivate()
47 {
47 {
48
48
49 }
49 }
50
50
51 void QPieSeriesPrivate::updateDerivativeData()
51 void QPieSeriesPrivate::updateDerivativeData()
52 {
52 {
53 m_total = 0;
53 m_total = 0;
54
54
55 // nothing to do?
55 // nothing to do?
56 if (m_slices.count() == 0)
56 if (m_slices.count() == 0)
57 return;
57 return;
58
58
59 // calculate total
59 // calculate total
60 foreach (QPieSlice* s, m_slices)
60 foreach (QPieSlice* s, m_slices)
61 m_total += s->value();
61 m_total += s->value();
62
62
63 // nothing to show..
63 // nothing to show..
64 if (qFuzzyIsNull(m_total))
64 if (qFuzzyIsNull(m_total))
65 return;
65 return;
66
66
67 // update slice attributes
67 // update slice attributes
68 qreal sliceAngle = m_pieStartAngle;
68 qreal sliceAngle = m_pieStartAngle;
69 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
69 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
70 QVector<QPieSlice*> changed;
70 QVector<QPieSlice*> changed;
71 foreach (QPieSlice* s, m_slices) {
71 foreach (QPieSlice* s, m_slices) {
72
72
73 PieSliceData data = PieSliceData::data(s);
73 PieSliceData data = PieSliceData::data(s);
74 data.m_percentage = s->value() / m_total;
74 data.m_percentage = s->value() / m_total;
75 data.m_angleSpan = pieSpan * data.m_percentage;
75 data.m_angleSpan = pieSpan * data.m_percentage;
76 data.m_startAngle = sliceAngle;
76 data.m_startAngle = sliceAngle;
77 sliceAngle += data.m_angleSpan;
77 sliceAngle += data.m_angleSpan;
78
78
79 if (PieSliceData::data(s) != data) {
79 if (PieSliceData::data(s) != data) {
80 PieSliceData::data(s) = data;
80 PieSliceData::data(s) = data;
81 changed << s;
81 changed << s;
82 }
82 }
83 }
83 }
84
84
85 // emit signals
85 // emit signals
86 foreach (QPieSlice* s, changed)
86 foreach (QPieSlice* s, changed)
87 PieSliceData::data(s).emitChangedSignal(s);
87 PieSliceData::data(s).emitChangedSignal(s);
88 }
88 }
89
89
90 void QPieSeriesPrivate::sliceChanged()
90 void QPieSeriesPrivate::sliceChanged()
91 {
91 {
92 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
92 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
93 updateDerivativeData();
93 updateDerivativeData();
94 }
94 }
95
95
96 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
96 void QPieSeriesPrivate::sliceClicked(Qt::MouseButtons buttons)
97 {
97 {
98 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
98 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
99 Q_ASSERT(m_slices.contains(slice));
99 Q_ASSERT(m_slices.contains(slice));
100 Q_Q(QPieSeries);
100 Q_Q(QPieSeries);
101 emit q->clicked(slice, buttons);
101 emit q->clicked(slice, buttons);
102 }
102 }
103
103
104 void QPieSeriesPrivate::sliceHoverEnter()
104 void QPieSeriesPrivate::sliceHoverEnter()
105 {
105 {
106 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
106 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
107 Q_ASSERT(m_slices.contains(slice));
107 Q_ASSERT(m_slices.contains(slice));
108 Q_Q(QPieSeries);
108 Q_Q(QPieSeries);
109 emit q->hoverEnter(slice);
109 emit q->hoverEnter(slice);
110 }
110 }
111
111
112 void QPieSeriesPrivate::sliceHoverLeave()
112 void QPieSeriesPrivate::sliceHoverLeave()
113 {
113 {
114 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
114 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
115 Q_ASSERT(m_slices.contains(slice));
115 Q_ASSERT(m_slices.contains(slice));
116 Q_Q(QPieSeries);
116 Q_Q(QPieSeries);
117 emit q->hoverLeave(slice);
117 emit q->hoverLeave(slice);
118 }
118 }
119
119
120 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
120 void QPieSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
121 {
121 {
122 Q_UNUSED(bottomRight)
122 Q_UNUSED(bottomRight)
123 Q_Q(QPieSeries);
123 Q_Q(QPieSeries);
124
124
125 if (m_mapOrientation == Qt::Vertical)
125 if (m_mapOrientation == Qt::Vertical)
126 {
126 {
127 if (topLeft.column() == m_mapValues)
127 if (topLeft.column() == m_mapValues)
128 if (m_mapValues == m_mapLabels)
128 if (m_mapValues == m_mapLabels)
129 {
129 {
130 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
130 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());
131 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
132 }
132 }
133 else
133 else
134 {
134 {
135 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
135 m_slices.at(topLeft.row())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
136 }
136 }
137 else if (topLeft.column() == m_mapLabels)
137 else if (topLeft.column() == m_mapLabels)
138 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
138 m_slices.at(topLeft.row())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
139 }
139 }
140 else
140 else
141 {
141 {
142 if (topLeft.row() == m_mapValues)
142 if (topLeft.row() == m_mapValues)
143 if (m_mapValues == m_mapLabels)
143 if (m_mapValues == m_mapLabels)
144 {
144 {
145 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
145 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
146 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
146 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
147 }
147 }
148 else
148 else
149 {
149 {
150 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
150 m_slices.at(topLeft.column())->setValue(q->m_model->data(topLeft, Qt::DisplayRole).toDouble());
151 }
151 }
152 else if (topLeft.row() == m_mapLabels)
152 else if (topLeft.row() == m_mapLabels)
153 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
153 m_slices.at(topLeft.column())->setLabel(q->m_model->data(topLeft, Qt::DisplayRole).toString());
154 }
154 }
155 }
155 }
156
156
157 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
157 void QPieSeriesPrivate::modelDataAdded(QModelIndex parent, int start, int end)
158 {
158 {
159 Q_UNUSED(parent)
159 Q_UNUSED(parent)
160 Q_UNUSED(end)
160 Q_UNUSED(end)
161 Q_Q(QPieSeries);
161 Q_Q(QPieSeries);
162
162
163 QPieSlice* newSlice = new QPieSlice;
163 QPieSlice* newSlice = new QPieSlice;
164 newSlice->setLabelVisible(true);
164 newSlice->setLabelVisible(true);
165 if (m_mapOrientation == Qt::Vertical)
165 if (m_mapOrientation == Qt::Vertical)
166 {
166 {
167 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
167 newSlice->setValue(q->m_model->data(q->m_model->index(start, m_mapValues), Qt::DisplayRole).toDouble());
168 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
168 newSlice->setLabel(q->m_model->data(q->m_model->index(start, m_mapLabels), Qt::DisplayRole).toString());
169 }
169 }
170 else
170 else
171 {
171 {
172 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
172 newSlice->setValue(q->m_model->data(q->m_model->index(m_mapValues, start), Qt::DisplayRole).toDouble());
173 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
173 newSlice->setLabel(q->m_model->data(q->m_model->index(m_mapLabels, start), Qt::DisplayRole).toString());
174 }
174 }
175
175
176 q->insert(start, newSlice);
176 q->insert(start, newSlice);
177 }
177 }
178
178
179 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
179 void QPieSeriesPrivate::modelDataRemoved(QModelIndex parent, int start, int end)
180 {
180 {
181 Q_UNUSED(parent)
181 Q_UNUSED(parent)
182 Q_UNUSED(end)
182 Q_UNUSED(end)
183 Q_Q(QPieSeries);
183 Q_Q(QPieSeries);
184 q->remove(m_slices.at(start));
184 q->remove(m_slices.at(start));
185 }
185 }
186
186
187 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
187 bool QPieSeriesPrivate::setRealValue(qreal &value, qreal newValue, qreal max, qreal min)
188 {
188 {
189 // Remove rounding errors
189 // Remove rounding errors
190 qreal roundedValue = newValue;
190 qreal roundedValue = newValue;
191 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
191 if (qFuzzyIsNull(min) && qFuzzyIsNull(newValue))
192 roundedValue = 0.0;
192 roundedValue = 0.0;
193 else if (qFuzzyCompare(newValue, max))
193 else if (qFuzzyCompare(newValue, max))
194 roundedValue = max;
194 roundedValue = max;
195 else if (qFuzzyCompare(newValue, min))
195 else if (qFuzzyCompare(newValue, min))
196 roundedValue = min;
196 roundedValue = min;
197
197
198 // Check if the position is valid after removing the rounding errors
198 // Check if the position is valid after removing the rounding errors
199 if (roundedValue < min || roundedValue > max) {
199 if (roundedValue < min || roundedValue > max) {
200 qWarning("QPieSeries: Illegal value");
200 qWarning("QPieSeries: Illegal value");
201 return false;
201 return false;
202 }
202 }
203
203
204 if (!qFuzzyIsNull(value - roundedValue)) {
204 if (!qFuzzyIsNull(value - roundedValue)) {
205 value = roundedValue;
205 value = roundedValue;
206 return true;
206 return true;
207 }
207 }
208
208
209 // The change was so small it is considered a rounding error
209 // The change was so small it is considered a rounding error
210 return false;
210 return false;
211 }
211 }
212
212
213
213
214
214
215 /*!
215 /*!
216 \class QPieSeries
216 \class QPieSeries
217 \brief Pie series API for QtCommercial Charts
217 \brief Pie series API for QtCommercial Charts
218
218
219 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
219 The pie series defines a pie chart which consists of pie slices which are QPieSlice objects.
220 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
220 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
221 The actual slice size is determined by that relative value.
221 The actual slice size is determined by that relative value.
222
222
223 By default the pie is defined as a full pie but it can be a partial pie.
223 By default the pie is defined as a full pie but it can be a partial pie.
224 This can be done by setting a starting angle and angle span to the series.
224 This can be done by setting a starting angle and angle span to the series.
225 */
225 */
226
226
227 /*!
227 /*!
228 Constructs a series object which is a child of \a parent.
228 Constructs a series object which is a child of \a parent.
229 */
229 */
230 QPieSeries::QPieSeries(QObject *parent) :
230 QPieSeries::QPieSeries(QObject *parent) :
231 QSeries(parent),
231 QSeries(parent),
232 d_ptr(new QPieSeriesPrivate(this))
232 d_ptr(new QPieSeriesPrivate(this))
233 {
233 {
234
234
235 }
235 }
236
236
237 /*!
237 /*!
238 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
238 Destroys the object. Note that adding series to QChart transfers the ownership to the chart.
239 */
239 */
240 QPieSeries::~QPieSeries()
240 QPieSeries::~QPieSeries()
241 {
241 {
242 // NOTE: d_prt destroyed by QObject
242 // NOTE: d_prt destroyed by QObject
243 }
243 }
244
244
245 /*!
245 /*!
246 Returns QChartSeries::SeriesTypePie.
246 Returns QChartSeries::SeriesTypePie.
247 */
247 */
248 QSeries::QSeriesType QPieSeries::type() const
248 QSeries::QSeriesType QPieSeries::type() const
249 {
249 {
250 return QSeries::SeriesTypePie;
250 return QSeries::SeriesTypePie;
251 }
251 }
252
252
253 /*!
253 /*!
254 Sets an array of \a slices to the series replacing the existing slices.
254 Sets an array of \a slices to the series replacing the existing slices.
255 Slice ownership is passed to the series.
255 Slice ownership is passed to the series.
256 */
256 */
257 void QPieSeries::replace(QList<QPieSlice*> slices)
257 void QPieSeries::replace(QList<QPieSlice*> slices)
258 {
258 {
259 clear();
259 clear();
260 append(slices);
260 append(slices);
261 }
261 }
262
262
263 /*!
263 /*!
264 Adds an array of \a slices to the series.
264 Adds an array of \a slices to the series.
265 Slice ownership is passed to the series.
265 Slice ownership is passed to the series.
266 */
266 */
267 void QPieSeries::append(QList<QPieSlice*> slices)
267 void QPieSeries::append(QList<QPieSlice*> slices)
268 {
268 {
269 Q_D(QPieSeries);
269 Q_D(QPieSeries);
270
270
271 foreach (QPieSlice* s, slices) {
271 foreach (QPieSlice* s, slices) {
272 s->setParent(this);
272 s->setParent(this);
273 d->m_slices << s;
273 d->m_slices << s;
274 }
274 }
275
275
276 d->updateDerivativeData();
276 d->updateDerivativeData();
277
277
278 foreach (QPieSlice* s, slices) {
278 foreach (QPieSlice* s, slices) {
279 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
279 connect(s, SIGNAL(changed()), d, SLOT(sliceChanged()));
280 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
280 connect(s, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
281 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
281 connect(s, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
282 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
282 connect(s, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
283 }
283 }
284
284
285 emit added(slices);
285 emit added(slices);
286 }
286 }
287
287
288 /*!
288 /*!
289 Adds a single \a slice to the series.
289 Adds a single \a slice to the series.
290 Slice ownership is passed to the series.
290 Slice ownership is passed to the series.
291 */
291 */
292 void QPieSeries::append(QPieSlice* slice)
292 void QPieSeries::append(QPieSlice* slice)
293 {
293 {
294 append(QList<QPieSlice*>() << slice);
294 append(QList<QPieSlice*>() << slice);
295 }
295 }
296
296
297 /*!
297 /*!
298 Adds a single \a slice to the series and returns a reference to the series.
298 Adds a single \a slice to the series and returns a reference to the series.
299 Slice ownership is passed to the series.
299 Slice ownership is passed to the series.
300 */
300 */
301 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
301 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
302 {
302 {
303 append(slice);
303 append(slice);
304 return *this;
304 return *this;
305 }
305 }
306
306
307
307
308 /*!
308 /*!
309 Appends a single slice to the series with give \a value and \a name.
309 Appends a single slice to the series with give \a value and \a name.
310 Slice ownership is passed to the series.
310 Slice ownership is passed to the series.
311 */
311 */
312 QPieSlice* QPieSeries::append(qreal value, QString name)
312 QPieSlice* QPieSeries::append(qreal value, QString name)
313 {
313 {
314 QPieSlice* slice = new QPieSlice(value, name);
314 QPieSlice* slice = new QPieSlice(value, name);
315 append(slice);
315 append(slice);
316 return slice;
316 return slice;
317 }
317 }
318
318
319 /*!
319 /*!
320 Inserts a single \a slice to the series before the slice at \a index position.
320 Inserts a single \a slice to the series before the slice at \a index position.
321 Slice ownership is passed to the series.
321 Slice ownership is passed to the series.
322 */
322 */
323 void QPieSeries::insert(int index, QPieSlice* slice)
323 void QPieSeries::insert(int index, QPieSlice* slice)
324 {
324 {
325 Q_D(QPieSeries);
325 Q_D(QPieSeries);
326 Q_ASSERT(index <= d->m_slices.count());
326 Q_ASSERT(index <= d->m_slices.count());
327 slice->setParent(this);
327 slice->setParent(this);
328 d->m_slices.insert(index, slice);
328 d->m_slices.insert(index, slice);
329
329
330 d->updateDerivativeData();
330 d->updateDerivativeData();
331
331
332 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
332 connect(slice, SIGNAL(changed()), d, SLOT(sliceChanged()));
333 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
333 connect(slice, SIGNAL(clicked(Qt::MouseButtons)), d, SLOT(sliceClicked(Qt::MouseButtons)));
334 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
334 connect(slice, SIGNAL(hoverEnter()), d, SLOT(sliceHoverEnter()));
335 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
335 connect(slice, SIGNAL(hoverLeave()), d, SLOT(sliceHoverLeave()));
336
336
337 emit added(QList<QPieSlice*>() << slice);
337 emit added(QList<QPieSlice*>() << slice);
338 }
338 }
339
339
340 /*!
340 /*!
341 Removes a single \a slice from the series and deletes the slice.
341 Removes a single \a slice from the series and deletes the slice.
342
342
343 Do not reference this pointer after this call.
343 Do not reference this pointer after this call.
344 */
344 */
345 void QPieSeries::remove(QPieSlice* slice)
345 void QPieSeries::remove(QPieSlice* slice)
346 {
346 {
347 Q_D(QPieSeries);
347 Q_D(QPieSeries);
348 if (!d->m_slices.removeOne(slice)) {
348 if (!d->m_slices.removeOne(slice)) {
349 Q_ASSERT(0); // TODO: how should this be reported?
349 Q_ASSERT(0); // TODO: how should this be reported?
350 return;
350 return;
351 }
351 }
352
352
353 d->updateDerivativeData();
353 d->updateDerivativeData();
354
354
355 emit removed(QList<QPieSlice*>() << slice);
355 emit removed(QList<QPieSlice*>() << slice);
356
356
357 delete slice;
357 delete slice;
358 slice = 0;
358 slice = 0;
359 }
359 }
360
360
361 /*!
361 /*!
362 Clears all slices from the series.
362 Clears all slices from the series.
363 */
363 */
364 void QPieSeries::clear()
364 void QPieSeries::clear()
365 {
365 {
366 Q_D(QPieSeries);
366 Q_D(QPieSeries);
367 if (d->m_slices.count() == 0)
367 if (d->m_slices.count() == 0)
368 return;
368 return;
369
369
370 QList<QPieSlice*> slices = d->m_slices;
370 QList<QPieSlice*> slices = d->m_slices;
371 foreach (QPieSlice* s, d->m_slices) {
371 foreach (QPieSlice* s, d->m_slices) {
372 d->m_slices.removeOne(s);
372 d->m_slices.removeOne(s);
373 delete s;
373 delete s;
374 }
374 }
375
375
376 d->updateDerivativeData();
376 d->updateDerivativeData();
377
377
378 emit removed(slices);
378 emit removed(slices);
379 }
379 }
380
380
381 /*!
381 /*!
382 Counts the number of the slices in this series.
382 Counts the number of the slices in this series.
383 */
383 */
384 int QPieSeries::count() const
384 int QPieSeries::count() const
385 {
385 {
386 Q_D(const QPieSeries);
386 Q_D(const QPieSeries);
387 return d->m_slices.count();
387 return d->m_slices.count();
388 }
388 }
389
389
390 /*!
390 /*!
391 Returns true is the series is empty.
391 Returns true is the series is empty.
392 */
392 */
393 bool QPieSeries::isEmpty() const
393 bool QPieSeries::isEmpty() const
394 {
394 {
395 Q_D(const QPieSeries);
395 Q_D(const QPieSeries);
396 return d->m_slices.isEmpty();
396 return d->m_slices.isEmpty();
397 }
397 }
398
398
399 /*!
399 /*!
400 Returns a list of slices that belong to this series.
400 Returns a list of slices that belong to this series.
401 */
401 */
402 QList<QPieSlice*> QPieSeries::slices() const
402 QList<QPieSlice*> QPieSeries::slices() const
403 {
403 {
404 Q_D(const QPieSeries);
404 Q_D(const QPieSeries);
405 return d->m_slices;
405 return d->m_slices;
406 }
406 }
407
407
408 /*!
408 /*!
409 Sets the horizontal center position of the pie to \relativePosition. If \relativePosition is
409 Sets the horizontal center position of the pie to \relativePosition. If \relativePosition is
410 set to 0.0 the pie is drawn on the left side of the chart and if it's set to 1.0 the pie is
410 set to 0.0 the pie is drawn on the left side of the chart and if it's set to 1.0 the pie is
411 drawn on right side of the chart. The default value 0.5 puts the pie in the middle.
411 drawn on right side of the chart. The default value 0.5 puts the pie in the middle.
412
412
413 \sa setHorizontalPosition(), setPieSize()
413 \sa setHorizontalPosition(), setPieSize()
414 */
414 */
415 void QPieSeries::setHorizontalPosition(qreal relativePosition)
415 void QPieSeries::setHorizontalPosition(qreal relativePosition)
416 {
416 {
417 Q_D(QPieSeries);
417 Q_D(QPieSeries);
418 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
418 if (d->setRealValue(d->m_pieRelativeHorPos, relativePosition, 1.0))
419 emit piePositionChanged();
419 emit piePositionChanged();
420 }
420 }
421
421
422 /*!
422 /*!
423 Sets the vertical center position of the pie to \relativePosition. If \relativePosition is
423 Sets the vertical center position of the pie to \relativePosition. If \relativePosition is
424 set to 0.0 the pie is drawn on the top of the chart and if it's set to 1.0 the pie is drawn
424 set to 0.0 the pie is drawn on the top of the chart and if it's set to 1.0 the pie is drawn
425 on bottom of the chart. The default value 0.5 puts the pie in the middle.
425 on bottom of the chart. The default value 0.5 puts the pie in the middle.
426
426
427 \sa setVerticalPosition(), setPieSize()
427 \sa setVerticalPosition(), setPieSize()
428 */
428 */
429 void QPieSeries::setVerticalPosition(qreal relativePosition)
429 void QPieSeries::setVerticalPosition(qreal relativePosition)
430 {
430 {
431 Q_D(QPieSeries);
431 Q_D(QPieSeries);
432 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
432 if (d->setRealValue(d->m_pieRelativeVerPos, relativePosition, 1.0))
433 emit piePositionChanged();
433 emit piePositionChanged();
434 }
434 }
435
435
436 /*!
436 /*!
437 Gets the horizontal position of the pie.
437 Gets the horizontal position of the pie.
438
438
439 The returned value is relative to the chart rectangle where:
439 The returned value is relative to the chart rectangle where:
440
440
441 0.0 means the absolute left.
441 0.0 means the absolute left.
442 1.0 means the absolute right.
442 1.0 means the absolute right.
443
443
444 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
444 By default it is 0.5 which puts the pie in the horizontal middle of the chart rectangle.
445
445
446 \sa verticalPosition(), setPieSize()
446 \sa verticalPosition(), setPieSize()
447 */
447 */
448 qreal QPieSeries::horizontalPosition() const
448 qreal QPieSeries::horizontalPosition() const
449 {
449 {
450 Q_D(const QPieSeries);
450 Q_D(const QPieSeries);
451 return d->m_pieRelativeHorPos;
451 return d->m_pieRelativeHorPos;
452 }
452 }
453
453
454 /*!
454 /*!
455 Gets the vertical position position of the pie.
455 Gets the vertical position position of the pie.
456
456
457 The returned value is relative to the chart rectangle where:
457 The returned value is relative to the chart rectangle where:
458
458
459 0.0 means the absolute top.
459 0.0 means the absolute top.
460 1.0 means the absolute bottom.
460 1.0 means the absolute bottom.
461
461
462 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
462 By default it is 0.5 which puts the pie in the vertical middle of the chart rectangle.
463
463
464 \sa horizontalPosition(), setPieSize()
464 \sa horizontalPosition(), setPieSize()
465 */
465 */
466 qreal QPieSeries::verticalPosition() const
466 qreal QPieSeries::verticalPosition() const
467 {
467 {
468 Q_D(const QPieSeries);
468 Q_D(const QPieSeries);
469 return d->m_pieRelativeVerPos;
469 return d->m_pieRelativeVerPos;
470 }
470 }
471
471
472 /*!
472 /*!
473 Sets the relative size of the pie.
473 Sets the relative size of the pie.
474
474
475 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
475 The \a relativeSize is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
476
476
477 Default value is 0.7.
477 Default value is 0.7.
478
478
479 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
479 \sa pieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
480 */
480 */
481 void QPieSeries::setPieSize(qreal relativeSize)
481 void QPieSeries::setPieSize(qreal relativeSize)
482 {
482 {
483 Q_D(QPieSeries);
483 Q_D(QPieSeries);
484 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
484 if (d->setRealValue(d->m_pieRelativeSize, relativeSize, 1.0))
485 emit pieSizeChanged();
485 emit pieSizeChanged();
486 }
486 }
487
487
488 /*!
488 /*!
489 Gets the relative size of the pie.
489 Gets the relative size of the pie.
490
490
491 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
491 The size is defined so that the 1.0 is the maximum that can fit the given chart rectangle.
492
492
493 Default value is 0.7.
493 Default value is 0.7.
494
494
495 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
495 \sa setPieSize(), setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
496 */
496 */
497 qreal QPieSeries::pieSize() const
497 qreal QPieSeries::pieSize() const
498 {
498 {
499 Q_D(const QPieSeries);
499 Q_D(const QPieSeries);
500 return d->m_pieRelativeSize;
500 return d->m_pieRelativeSize;
501 }
501 }
502
502
503
503
504 /*!
504 /*!
505 Sets the end angle of the pie.
505 Sets the end angle of the pie.
506
506
507 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
507 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
508
508
509 \a angle must be less than pie end angle. Default value is 0.
509 \a angle must be less than pie end angle. Default value is 0.
510
510
511 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
511 \sa pieStartAngle(), pieEndAngle(), setPieEndAngle()
512 */
512 */
513 void QPieSeries::setPieStartAngle(qreal angle)
513 void QPieSeries::setPieStartAngle(qreal angle)
514 {
514 {
515 Q_D(QPieSeries);
515 Q_D(QPieSeries);
516 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
516 if (d->setRealValue(d->m_pieStartAngle, angle, d->m_pieEndAngle))
517 d->updateDerivativeData();
517 d->updateDerivativeData();
518 }
518 }
519
519
520 /*!
520 /*!
521 Gets the start angle of the pie.
521 Gets the start angle of the pie.
522
522
523 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
523 Full pie is 360 degrees where 0 degrees is at 12 a'clock. Default value is 360.
524
524
525 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
525 \sa setPieStartAngle(), pieEndAngle(), setPieEndAngle()
526 */
526 */
527 qreal QPieSeries::pieStartAngle() const
527 qreal QPieSeries::pieStartAngle() const
528 {
528 {
529 Q_D(const QPieSeries);
529 Q_D(const QPieSeries);
530 return d->m_pieStartAngle;
530 return d->m_pieStartAngle;
531 }
531 }
532
532
533 /*!
533 /*!
534 Sets the end angle of the pie.
534 Sets the end angle of the pie.
535
535
536 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
536 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
537
537
538 \a angle must be greater than start angle.
538 \a angle must be greater than start angle.
539
539
540 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
540 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
541 */
541 */
542 void QPieSeries::setPieEndAngle(qreal angle)
542 void QPieSeries::setPieEndAngle(qreal angle)
543 {
543 {
544 Q_D(QPieSeries);
544 Q_D(QPieSeries);
545
545
546 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
546 if (d->setRealValue(d->m_pieEndAngle, angle, 360.0, d->m_pieStartAngle))
547 d->updateDerivativeData();
547 d->updateDerivativeData();
548 }
548 }
549
549
550 /*!
550 /*!
551 Returns the end angle of the pie.
551 Returns the end angle of the pie.
552
552
553 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
553 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
554
554
555 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
555 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
556 */
556 */
557 qreal QPieSeries::pieEndAngle() const
557 qreal QPieSeries::pieEndAngle() const
558 {
558 {
559 Q_D(const QPieSeries);
559 Q_D(const QPieSeries);
560 return d->m_pieEndAngle;
560 return d->m_pieEndAngle;
561 }
561 }
562
562
563 /*!
563 /*!
564 Sets the all the slice labels \a visible or invisible.
564 Sets the all the slice labels \a visible or invisible.
565
565
566 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
566 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
567 */
567 */
568 void QPieSeries::setLabelsVisible(bool visible)
568 void QPieSeries::setLabelsVisible(bool visible)
569 {
569 {
570 Q_D(QPieSeries);
570 Q_D(QPieSeries);
571 foreach (QPieSlice* s, d->m_slices)
571 foreach (QPieSlice* s, d->m_slices)
572 s->setLabelVisible(visible);
572 s->setLabelVisible(visible);
573 }
573 }
574
574
575 /*!
575 /*!
576 Returns the sum of all slice values in this series.
576 Returns the sum of all slice values in this series.
577
577
578 \sa QPieSlice::value(), QPieSlice::setValue()
578 \sa QPieSlice::value(), QPieSlice::setValue()
579 */
579 */
580 qreal QPieSeries::total() const
580 qreal QPieSeries::total() const
581 {
581 {
582 Q_D(const QPieSeries);
582 Q_D(const QPieSeries);
583 return d->m_total;
583 return d->m_total;
584 }
584 }
585
585
586 /*!
586 /*!
587 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
587 \fn void QPieSeries::clicked(QPieSlice* slice, Qt::MouseButtons buttons)
588
588
589 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
589 This signal is emitted when a \a slice has been clicked with mouse \a buttons.
590
590
591 \sa QPieSlice::clicked()
591 \sa QPieSlice::clicked()
592 */
592 */
593
593
594 /*!
594 /*!
595 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
595 \fn void QPieSeries::hoverEnter(QPieSlice* slice)
596
596
597 This signal is emitted when user has hovered over a \a slice.
597 This signal is emitted when user has hovered over a \a slice.
598
598
599 \sa QPieSlice::hoverEnter()
599 \sa QPieSlice::hoverEnter()
600 */
600 */
601
601
602 /*!
602 /*!
603 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
603 \fn void QPieSeries::hoverLeave(QPieSlice* slice)
604
604
605 This signal is emitted when user has hovered away from a \a slice.
605 This signal is emitted when user has hovered away from a \a slice.
606
606
607 \sa QPieSlice::hoverLeave()
607 \sa QPieSlice::hoverLeave()
608 */
608 */
609
609
610 /*!
610 /*!
611 \fn void QPieSeries::added(QList<QPieSlice*> slices)
611 \fn void QPieSeries::added(QList<QPieSlice*> slices)
612
612
613 This signal is emitted when \a slices has been added to the series.
613 This signal is emitted when \a slices has been added to the series.
614
614
615 \sa append(), insert()
615 \sa append(), insert()
616 */
616 */
617
617
618 /*!
618 /*!
619 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
619 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
620
620
621 This signal is emitted when \a slices has been removed from the series.
621 This signal is emitted when \a slices has been removed from the series.
622
622
623 \sa remove(), clear()
623 \sa remove(), clear()
624 */
624 */
625
625
626 /*!
626 /*!
627 \fn void QPieSeries::piePositionChanged()
627 \fn void QPieSeries::piePositionChanged()
628
628
629 This signal is emitted when pie position has changed.
629 This signal is emitted when pie position has changed.
630
630
631 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
631 \sa setPiePosition(), pieVerticalPosition(), pieHorizontalPosition()
632 */
632 */
633
633
634 /*!
634 /*!
635 \fn void QPieSeries::pieSizeChanged()
635 \fn void QPieSeries::pieSizeChanged()
636
636
637 This signal is emitted when pie size has changed.
637 This signal is emitted when pie size has changed.
638
638
639 \sa pieSize(), setPieSize()
639 \sa pieSize(), setPieSize()
640 */
640 */
641
641
642 /*!
642 /*!
643 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
643 \fn bool QPieSeries::setModel(QAbstractItemModel *model)
644 Sets the \a model to be used as a data source
644 Sets the \a model to be used as a data source
645 */
645 */
646 bool QPieSeries::setModel(QAbstractItemModel* model)
646 bool QPieSeries::setModel(QAbstractItemModel* model)
647 {
647 {
648 Q_D(QPieSeries);
648 Q_D(QPieSeries);
649 // disconnect signals from old model
649 // disconnect signals from old model
650 if(m_model)
650 if(m_model)
651 {
651 {
652 disconnect(m_model, 0, this, 0);
652 disconnect(m_model, 0, this, 0);
653 d->m_mapValues = -1;
653 d->m_mapValues = -1;
654 d->m_mapLabels = -1;
654 d->m_mapLabels = -1;
655 d->m_mapOrientation = Qt::Vertical;
655 d->m_mapOrientation = Qt::Vertical;
656 }
656 }
657
657
658 // set new model
658 // set new model
659 if(model)
659 if(model)
660 {
660 {
661 m_model = model;
661 m_model = model;
662 return true;
662 return true;
663 }
663 }
664 else
664 else
665 {
665 {
666 m_model = 0;
666 m_model = 0;
667 return false;
667 return false;
668 }
668 }
669 }
669 }
670
670
671 /*!
672 \fn bool QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
673 Sets column/row specified by \a modelValuesLine to be used as a list of pie slice values for the pie.
674 Parameter \a modelValuesLine indicates the column/row where the values for the pie slices are located in the model.
675 Parameter \a modelLabelsLine indicates the column/row where the labels for the pie slices are located in the model.
676 The \a orientation paramater specifies whether the data is in columns or in rows.
677 */
671 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
678 void QPieSeries::setModelMapping(int modelValuesLine, int modelLabelsLine, Qt::Orientation orientation)
672 {
679 {
673 Q_D(QPieSeries);
680 Q_D(QPieSeries);
674
681
675 if (m_model == 0)
682 if (m_model == 0)
676 return;
683 return;
677
684
678 d->m_mapValues = modelValuesLine;
685 d->m_mapValues = modelValuesLine;
679 d->m_mapLabels = modelLabelsLine;
686 d->m_mapLabels = modelLabelsLine;
680 d->m_mapOrientation = orientation;
687 d->m_mapOrientation = orientation;
681
688
682 // connect the signals
689 // connect the signals
683 if (d->m_mapOrientation == Qt::Vertical) {
690 if (d->m_mapOrientation == Qt::Vertical) {
684 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
691 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
685 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
692 connect(m_model, SIGNAL(rowsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
686 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
693 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
687 } else {
694 } else {
688 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
695 connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex, QModelIndex)));
689 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
696 connect(m_model, SIGNAL(columnsInserted(QModelIndex, int, int)), d, SLOT(modelDataAdded(QModelIndex,int,int)));
690 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
697 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), d, SLOT(modelDataRemoved(QModelIndex,int,int)));
691 }
698 }
692
699
693 // create the initial slices set
700 // create the initial slices set
694 if (d->m_mapOrientation == Qt::Vertical) {
701 if (d->m_mapOrientation == Qt::Vertical) {
695 for (int i = 0; i < m_model->rowCount(); i++)
702 for (int i = 0; i < m_model->rowCount(); i++)
696 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());
703 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());
697 } else {
704 } else {
698 for (int i = 0; i < m_model->columnCount(); i++)
705 for (int i = 0; i < m_model->columnCount(); i++)
699 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());
706 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());
700 }
707 }
701 }
708 }
702
709
703 #include "moc_qpieseries.cpp"
710 #include "moc_qpieseries.cpp"
704 #include "moc_qpieseriesprivate_p.cpp"
711 #include "moc_qpieseriesprivate_p.cpp"
705
712
706 QTCOMMERCIALCHART_END_NAMESPACE
713 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,179 +1,198
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 "qsplineseries.h"
21 #include "qsplineseries.h"
22
22
23 /*!
23 /*!
24 \class QSplineSeries
24 \class QSplineSeries
25 \brief Series type used to store data needed to draw a spline.
25 \brief Series type used to store data needed to draw a spline.
26
26
27 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
27 QSplineSeries stores the data points along with the segment control points needed by QPainterPath to draw spline
28 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
28 Control points are automatically calculated when data changes. The algorithm computes the points so that the normal spline can be drawn.
29 */
29 */
30
30
31 /*!
31 /*!
32 \fn QSeriesType QSplineSeries::type() const
32 \fn QSeriesType QSplineSeries::type() const
33 Returns the type of the series
33 Returns the type of the series
34 */
34 */
35
35
36 /*!
36 /*!
37 \fn QSeriesType QSplineSeries::controlPoint(int index) const
37 \fn QSeriesType QSplineSeries::controlPoint(int index) const
38 Returns the control point specified by \a index
38 Returns the control point specified by \a index
39 */
39 */
40
40
41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
41 QTCOMMERCIALCHART_BEGIN_NAMESPACE
42
42
43 /*!
43 /*!
44 Constructs empty series object which is a child of \a parent.
44 Constructs empty series object which is a child of \a parent.
45 When series object is added to QChartView or QChart instance then the ownerships is transfered.
45 When series object is added to QChartView or QChart instance then the ownerships is transfered.
46 */
46 */
47
47
48 QSplineSeries::QSplineSeries(QObject *parent) :
48 QSplineSeries::QSplineSeries(QObject *parent) :
49 QLineSeries(parent)
49 QLineSeries(parent)
50 {
50 {
51 connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
51 connect(this,SIGNAL(pointAdded(int)), this, SLOT(updateControlPoints()));
52 connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
52 connect(this,SIGNAL(pointRemoved(int)), this, SLOT(updateControlPoints()));
53 connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
53 connect(this,SIGNAL(pointReplaced(int)), this, SLOT(updateControlPoints()));
54 }
54 }
55
55
56 /*!
56 /*!
57 \internal
57 \internal
58 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
58 Calculates control points which are needed by QPainterPath.cubicTo function to draw the cubic Bezier cureve between two points.
59 */
59 */
60 void QSplineSeries::calculateControlPoints()
60 void QSplineSeries::calculateControlPoints()
61 {
61 {
62
62
63 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
63 // Based on http://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit
64 // CPOL License
64 // CPOL License
65
65
66 int n = count() - 1;
66 int n = count() - 1;
67 if (n == 1)
67 if (n == 1)
68 { // Special case: Bezier curve should be a straight line.
68 { // Special case: Bezier curve should be a straight line.
69 // firstControlPoints = new Point[1];
69 // firstControlPoints = new Point[1];
70 // 3P1 = 2P0 + P3
70 // 3P1 = 2P0 + P3
71 m_controlPoints.append(QPointF((2 * x(0) + x(1)) / 3, (2 * y(0) + y(1)) / 3));
71 m_controlPoints.append(QPointF((2 * x(0) + x(1)) / 3, (2 * y(0) + y(1)) / 3));
72
72
73 // P2 = 2P1 P0
73 // P2 = 2P1 P0
74 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - x(0), 2 * m_controlPoints[0].y() - y(0)));
74 m_controlPoints.append(QPointF(2 * m_controlPoints[0].x() - x(0), 2 * m_controlPoints[0].y() - y(0)));
75 return;
75 return;
76 }
76 }
77
77
78 // Calculate first Bezier control points
78 // Calculate first Bezier control points
79 // Right hand side vector
79 // Right hand side vector
80 // Set of equations for P0 to Pn points.
80 // Set of equations for P0 to Pn points.
81 //
81 //
82 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
82 // | 2 1 0 0 ... 0 0 0 ... 0 0 0 | | P1_1 | | P0 + 2 * P1 |
83 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
83 // | 1 4 1 0 ... 0 0 0 ... 0 0 0 | | P1_2 | | 4 * P1 + 2 * P2 |
84 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
84 // | 0 1 4 1 ... 0 0 0 ... 0 0 0 | | P1_3 | | 4 * P2 + 2 * P3 |
85 // | . . . . . . . . . . . . | | ... | | ... |
85 // | . . . . . . . . . . . . | | ... | | ... |
86 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
86 // | 0 0 0 0 ... 1 4 1 ... 0 0 0 | * | P1_i | = | 4 * P(i-1) + 2 * Pi |
87 // | . . . . . . . . . . . . | | ... | | ... |
87 // | . . . . . . . . . . . . | | ... | | ... |
88 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
88 // | 0 0 0 0 0 0 0 0 ... 1 4 1 | | P1_(n-1)| | 4 * P(n-2) + 2 * P(n-1) |
89 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
89 // | 0 0 0 0 0 0 0 0 ... 0 2 7 | | P1_n | | 8 * P(n-1) + Pn |
90 //
90 //
91 QList<qreal> rhs;
91 QList<qreal> rhs;
92 rhs.append(x(0) + 2 * x(1));
92 rhs.append(x(0) + 2 * x(1));
93
93
94 // Set right hand side X values
94 // Set right hand side X values
95 for (int i = 1; i < n - 1; ++i)
95 for (int i = 1; i < n - 1; ++i)
96 rhs.append(4 * x(i) + 2 * x(i + 1));
96 rhs.append(4 * x(i) + 2 * x(i + 1));
97
97
98 rhs.append((8 * x(n - 1) + x(n)) / 2.0);
98 rhs.append((8 * x(n - 1) + x(n)) / 2.0);
99 // Get first control points X-values
99 // Get first control points X-values
100 QList<qreal> xControl = getFirstControlPoints(rhs);
100 QList<qreal> xControl = getFirstControlPoints(rhs);
101 rhs[0] = y(0) + 2 * y(1);
101 rhs[0] = y(0) + 2 * y(1);
102
102
103 // Set right hand side Y values
103 // Set right hand side Y values
104 for (int i = 1; i < n - 1; ++i)
104 for (int i = 1; i < n - 1; ++i)
105 rhs[i] = 4 * y(i) + 2 * y(i + 1);
105 rhs[i] = 4 * y(i) + 2 * y(i + 1);
106
106
107 rhs[n - 1] = (8 * y(n - 1) + y(n)) / 2.0;
107 rhs[n - 1] = (8 * y(n - 1) + y(n)) / 2.0;
108 // Get first control points Y-values
108 // Get first control points Y-values
109 QList<qreal> yControl = getFirstControlPoints(rhs);
109 QList<qreal> yControl = getFirstControlPoints(rhs);
110
110
111 // Fill output arrays.
111 // Fill output arrays.
112 for (int i = 0; i < n; ++i) {
112 for (int i = 0; i < n; ++i) {
113 // First control point
113 // First control point
114 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
114 m_controlPoints.append(QPointF(xControl[i], yControl[i]));
115 // Second control point
115 // Second control point
116 if (i < n - 1)
116 if (i < n - 1)
117 m_controlPoints.append(QPointF(2 * x(i + 1) - xControl[i + 1], 2 * y(i + 1) - yControl[i + 1]));
117 m_controlPoints.append(QPointF(2 * x(i + 1) - xControl[i + 1], 2 * y(i + 1) - yControl[i + 1]));
118 else
118 else
119 m_controlPoints.append(QPointF((x(n) + xControl[n - 1]) / 2, (y(n) + yControl[n - 1]) / 2));
119 m_controlPoints.append(QPointF((x(n) + xControl[n - 1]) / 2, (y(n) + yControl[n - 1]) / 2));
120 }
120 }
121 }
121 }
122
122
123 /*!
123 /*!
124 \internal
124 \internal
125 */
125 */
126 QList<qreal> QSplineSeries::getFirstControlPoints(QList<qreal> rhs)
126 QList<qreal> QSplineSeries::getFirstControlPoints(QList<qreal> rhs)
127 {
127 {
128 QList<qreal> x; // Solution vector.
128 QList<qreal> x; // Solution vector.
129 QList<qreal> tmp; // Temp workspace.
129 QList<qreal> tmp; // Temp workspace.
130
130
131 qreal b = 2.0;
131 qreal b = 2.0;
132 x.append(rhs[0] / b);
132 x.append(rhs[0] / b);
133 tmp.append(0);
133 tmp.append(0);
134 for (int i = 1; i < rhs.size(); i++) {
134 for (int i = 1; i < rhs.size(); i++) {
135 // Decomposition and forward substitution.
135 // Decomposition and forward substitution.
136 tmp.append(1 / b);
136 tmp.append(1 / b);
137 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
137 b = (i < rhs.size() - 1 ? 4.0 : 3.5) - tmp[i];
138 x.append((rhs[i] - x[i - 1]) / b);
138 x.append((rhs[i] - x[i - 1]) / b);
139 }
139 }
140 for (int i = 1; i < rhs.size(); i++)
140 for (int i = 1; i < rhs.size(); i++)
141 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
141 x[rhs.size() - i - 1] -= tmp[rhs.size() - i] * x[rhs.size() - i]; // Backsubstitution.
142
142
143 return x;
143 return x;
144 }
144 }
145
145
146 /*!
146 /*!
147 \internal
147 \internal
148 Updates the control points, besed on currently avaiable knots.
148 Updates the control points, besed on currently avaiable knots.
149 */
149 */
150 void QSplineSeries::updateControlPoints()
150 void QSplineSeries::updateControlPoints()
151 {
151 {
152 if (count() > 1) {
152 if (count() > 1) {
153 m_controlPoints.clear();
153 m_controlPoints.clear();
154 calculateControlPoints();
154 calculateControlPoints();
155 }
155 }
156 }
156 }
157
157
158 bool QSplineSeries::setModel(QAbstractItemModel* model)
158 /*!
159 {
159 \fn bool QSplineSeries::setModel(QAbstractItemModel *model)
160 QXYSeries::setModel(model);
160 Sets the \a model to be used as a data source
161 // calculateControlPoints();
161 \sa setModelMapping(), setModelMappingRange()
162 return true;
162 */
163 }
163 //bool QSplineSeries::setModel(QAbstractItemModel* model)
164 //{
165 // QXYSeries::setModel(model);
166 //// calculateControlPoints();
167 // return true;
168 //}
164
169
165 void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
170 /*!
166 {
171 \fn bool QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
167 QLineSeries::setModelMapping(modelX, modelY, orientation);
172 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
168 // calculateControlPoints();
173 as a data source for y coordinate. The \a orientation paramater specifies whether the data
169 }
174 is in columns or in rows.
175 */
176 //void QSplineSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
177 //{
178 // QLineSeries::setModelMapping(modelX, modelY, orientation);
179 //// calculateControlPoints();
180 //}
170
181
182 /*!
183 \fn bool QSplineSeries::setModelMappingRange(int first, int count)
184 Allows limiting the model mapping.
185 Parameter \a first specifies which element of the model should be used as a first one of the series.
186 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
187 then all the items following \a first item in a model are used.
188 \sa setModel(), setModelMapping()
189 */
171 void QSplineSeries::setModelMappingRange(int first, int count)
190 void QSplineSeries::setModelMappingRange(int first, int count)
172 {
191 {
173 QLineSeries::setModelMappingRange(first, count);
192 QLineSeries::setModelMappingRange(first, count);
174 calculateControlPoints();
193 calculateControlPoints();
175 }
194 }
176
195
177 #include "moc_qsplineseries.cpp"
196 #include "moc_qsplineseries.cpp"
178
197
179 QTCOMMERCIALCHART_END_NAMESPACE
198 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,60 +1,60
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 QSPLINESERIES_H
21 #ifndef QSPLINESERIES_H
22 #define QSPLINESERIES_H
22 #define QSPLINESERIES_H
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <qlineseries.h>
25 #include <qlineseries.h>
26 #include <QList>
26 #include <QList>
27 #include <QPointF>
27 #include <QPointF>
28 #include <QtGlobal>
28 #include <QtGlobal>
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
32 class QTCOMMERCIALCHART_EXPORT QSplineSeries : public QLineSeries
33 {
33 {
34 Q_OBJECT
34 Q_OBJECT
35 public:
35 public:
36
36
37 QSplineSeries(QObject *parent = 0);
37 QSplineSeries(QObject *parent = 0);
38 QSeriesType type() const {return QSeries::SeriesTypeSpline;}
38 QSeriesType type() const {return QSeries::SeriesTypeSpline;}
39
39
40 QPointF controlPoint(int index) const {return m_controlPoints[index];}
40 QPointF controlPoint(int index) const {return m_controlPoints[index];}
41 bool setModel(QAbstractItemModel *model);
41 // bool setModel(QAbstractItemModel *model);
42
42
43 void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
43 // void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
44 void setModelMappingRange(int first, int count);
44 void setModelMappingRange(int first, int count);
45
45
46 private:
46 private:
47 void calculateControlPoints();
47 void calculateControlPoints();
48 QList<qreal> getFirstControlPoints(QList<qreal> rhs);
48 QList<qreal> getFirstControlPoints(QList<qreal> rhs);
49
49
50 private Q_SLOTS:
50 private Q_SLOTS:
51 void updateControlPoints();
51 void updateControlPoints();
52
52
53 private:
53 private:
54 QList<QPointF> m_controlPoints;
54 QList<QPointF> m_controlPoints;
55
55
56 };
56 };
57
57
58 QTCOMMERCIALCHART_END_NAMESPACE
58 QTCOMMERCIALCHART_END_NAMESPACE
59
59
60 #endif // QSPLINESERIES_H
60 #endif // QSPLINESERIES_H
@@ -1,535 +1,564
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 #include <QAbstractItemModel>
23
23
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
24 QTCOMMERCIALCHART_BEGIN_NAMESPACE
25
25
26 /*!
26 /*!
27 \class QXYSeries
27 \class QXYSeries
28 \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.
29 */
29 */
30
30
31 /*!
31 /*!
32 \fn QPen QXYSeries::pen() const
32 \fn QPen QXYSeries::pen() const
33 \brief Returns pen used to draw points for series.
33 \brief Returns pen used to draw points for series.
34 \sa setPen()
34 \sa setPen()
35 */
35 */
36
36
37 /*!
37 /*!
38 \fn QBrush QXYSeries::brush() const
38 \fn QBrush QXYSeries::brush() const
39 \brief Returns brush used to draw points for series.
39 \brief Returns brush used to draw points for series.
40 \sa setBrush()
40 \sa setBrush()
41 */
41 */
42
42
43 /*!
43 /*!
44 \fn void QXYSeries::clicked(const QPointF& point)
44 \fn void QXYSeries::clicked(const QPointF& point)
45 \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.
46 */
46 */
47
47
48 /*!
48 /*!
49 \fn void QXYSeries::pointReplaced(int index)
49 \fn void QXYSeries::pointReplaced(int index)
50 \brief \internal \a index
50 \brief \internal \a index
51 */
51 */
52
52
53 /*!
53 /*!
54 \fn void QXYSeries::pointAdded(int index)
54 \fn void QXYSeries::pointAdded(int index)
55 \brief \internal \a index
55 \brief \internal \a index
56 */
56 */
57
57
58 /*!
58 /*!
59 \fn void QXYSeries::pointRemoved(int index)
59 \fn void QXYSeries::pointRemoved(int index)
60 \brief \internal \a index
60 \brief \internal \a index
61 */
61 */
62
62
63 /*!
63 /*!
64 \fn void QXYSeries::updated()
64 \fn void QXYSeries::updated()
65 \brief \internal
65 \brief \internal
66 */
66 */
67
67
68 /*!
68 /*!
69 \fn int QXYSeries::mapFirst() const
70 Returns the index of the model's item that is used as a first one for the series.
71 \sa mapCount()
72 */
73
74 /*!
75 \fn int QXYSeries::mapCount() const
76 Returns the number of the items that are taken from the model.
77 If -1 it means all the items of the model following the first one are used.
78 \sa mapFirst()
79 */
80
81 /*!
69 Constructs empty series object which is a child of \a parent.
82 Constructs empty series object which is a child of \a parent.
70 When series object is added to QChartView or QChart instance ownerships is transfered.
83 When series object is added to QChartView or QChart instance ownerships is transfered.
71 */
84 */
72 QXYSeries::QXYSeries(QObject *parent):QSeries(parent)
85 QXYSeries::QXYSeries(QObject *parent):QSeries(parent)
73 {
86 {
74 m_mapX = -1;
87 m_mapX = -1;
75 m_mapY = -1;
88 m_mapY = -1;
76 m_mapFirst = 0;
89 m_mapFirst = 0;
77 m_mapCount = 0;
90 m_mapCount = 0;
78 m_mapLimited = false;
91 m_mapLimited = false;
79 m_mapOrientation = Qt::Vertical;
92 m_mapOrientation = Qt::Vertical;
80 // m_mapYOrientation = Qt::Vertical;
93 // m_mapYOrientation = Qt::Vertical;
81 }
94 }
82 /*!
95 /*!
83 Destroys the object. Series added to QChartView or QChart instances are owned by those,
96 Destroys the object. Series added to QChartView or QChart instances are owned by those,
84 and are deleted when mentioned object are destroyed.
97 and are deleted when mentioned object are destroyed.
85 */
98 */
86 QXYSeries::~QXYSeries()
99 QXYSeries::~QXYSeries()
87 {
100 {
88 }
101 }
89
102
90 /*!
103 /*!
91 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
104 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
92 */
105 */
93 void QXYSeries::append(qreal x,qreal y)
106 void QXYSeries::append(qreal x,qreal y)
94 {
107 {
95 Q_ASSERT(m_x.size() == m_y.size());
108 Q_ASSERT(m_x.size() == m_y.size());
96 m_x<<x;
109 m_x<<x;
97 m_y<<y;
110 m_y<<y;
98 emit pointAdded(m_x.size()-1);
111 emit pointAdded(m_x.size()-1);
99 }
112 }
100
113
101 /*!
114 /*!
102 This is an overloaded function.
115 This is an overloaded function.
103 Adds data \a point to the series. Points are connected with lines on the chart.
116 Adds data \a point to the series. Points are connected with lines on the chart.
104 */
117 */
105 void QXYSeries::append(const QPointF &point)
118 void QXYSeries::append(const QPointF &point)
106 {
119 {
107 append(point.x(),point.y());
120 append(point.x(),point.y());
108 }
121 }
109
122
110 /*!
123 /*!
111 This is an overloaded function.
124 This is an overloaded function.
112 Adds list of data \a points to the series. Points are connected with lines on the chart.
125 Adds list of data \a points to the series. Points are connected with lines on the chart.
113 */
126 */
114 void QXYSeries::append(const QList<QPointF> points)
127 void QXYSeries::append(const QList<QPointF> points)
115 {
128 {
116 foreach(const QPointF& point , points) {
129 foreach(const QPointF& point , points) {
117 append(point.x(),point.y());
130 append(point.x(),point.y());
118 }
131 }
119 }
132 }
120
133
121 /*!
134 /*!
122 Modifies \a y value for given \a x a value.
135 Modifies \a y value for given \a x a value.
123 */
136 */
124 void QXYSeries::replace(qreal x,qreal y)
137 void QXYSeries::replace(qreal x,qreal y)
125 {
138 {
126 int index = m_x.indexOf(x);
139 int index = m_x.indexOf(x);
127 m_x[index] = x;
140 m_x[index] = x;
128 m_y[index] = y;
141 m_y[index] = y;
129 emit pointReplaced(index);
142 emit pointReplaced(index);
130 }
143 }
131
144
132 /*!
145 /*!
133 This is an overloaded function.
146 This is an overloaded function.
134 Replaces current y value of for given \a point x value with \a point y value.
147 Replaces current y value of for given \a point x value with \a point y value.
135 */
148 */
136 void QXYSeries::replace(const QPointF &point)
149 void QXYSeries::replace(const QPointF &point)
137 {
150 {
138 replace(point.x(),point.y());
151 replace(point.x(),point.y());
139 }
152 }
140
153
141 /*!
154 /*!
142 Removes first \a x value and related y value.
155 Removes first \a x value and related y value.
143 */
156 */
144 void QXYSeries::remove(qreal x)
157 void QXYSeries::remove(qreal x)
145 {
158 {
146 int index = m_x.indexOf(x);
159 int index = m_x.indexOf(x);
147
160
148 if (index == -1) return;
161 if (index == -1) return;
149
162
150 m_x.remove(index);
163 m_x.remove(index);
151 m_y.remove(index);
164 m_y.remove(index);
152
165
153 emit pointRemoved(index);
166 emit pointRemoved(index);
154 }
167 }
155
168
156 /*!
169 /*!
157 Removes current \a x and \a y value.
170 Removes current \a x and \a y value.
158 */
171 */
159 void QXYSeries::remove(qreal x,qreal y)
172 void QXYSeries::remove(qreal x,qreal y)
160 {
173 {
161 int index =-1;
174 int index =-1;
162 do {
175 do {
163 index = m_x.indexOf(x,index+1);
176 index = m_x.indexOf(x,index+1);
164 } while (index !=-1 && m_y.at(index)!=y);
177 } while (index !=-1 && m_y.at(index)!=y);
165
178
166 if (index==-1) return;
179 if (index==-1) return;
167
180
168 m_x.remove(index);
181 m_x.remove(index);
169 m_y.remove(index);
182 m_y.remove(index);
170 emit pointRemoved(index);
183 emit pointRemoved(index);
171 }
184 }
172
185
173 /*!
186 /*!
174 Removes current \a point x value. Note \a point y value is ignored.
187 Removes current \a point x value. Note \a point y value is ignored.
175 */
188 */
176 void QXYSeries::remove(const QPointF &point)
189 void QXYSeries::remove(const QPointF &point)
177 {
190 {
178 remove(point.x(),point.y());
191 remove(point.x(),point.y());
179 }
192 }
180
193
181 /*!
194 /*!
182 Removes all data points from the series.
195 Removes all data points from the series.
183 */
196 */
184 void QXYSeries::removeAll()
197 void QXYSeries::removeAll()
185 {
198 {
186 m_x.clear();
199 m_x.clear();
187 m_y.clear();
200 m_y.clear();
188 }
201 }
189
202
190 /*!
203 /*!
191 \internal \a pos
204 \internal \a pos
192 */
205 */
193 qreal QXYSeries::x(int pos) const
206 qreal QXYSeries::x(int pos) const
194 {
207 {
195 if (m_model) {
208 if (m_model) {
196 if (m_mapOrientation == Qt::Vertical)
209 if (m_mapOrientation == Qt::Vertical)
197 // consecutive data is read from model's column
210 // consecutive data is read from model's column
198 return m_model->data(m_model->index(pos + m_mapFirst, m_mapX), Qt::DisplayRole).toDouble();
211 return m_model->data(m_model->index(pos + m_mapFirst, m_mapX), Qt::DisplayRole).toDouble();
199 else
212 else
200 // consecutive data is read from model's row
213 // consecutive data is read from model's row
201 return m_model->data(m_model->index(m_mapX, pos + m_mapFirst), Qt::DisplayRole).toDouble();
214 return m_model->data(m_model->index(m_mapX, pos + m_mapFirst), Qt::DisplayRole).toDouble();
202 } else {
215 } else {
203 // model is not specified, return the data from series' internal data store
216 // model is not specified, return the data from series' internal data store
204 return m_x.at(pos);
217 return m_x.at(pos);
205 }
218 }
206 }
219 }
207
220
208 /*!
221 /*!
209 \internal \a pos
222 \internal \a pos
210 */
223 */
211 qreal QXYSeries::y(int pos) const
224 qreal QXYSeries::y(int pos) const
212 {
225 {
213 if (m_model) {
226 if (m_model) {
214 if (m_mapOrientation == Qt::Vertical)
227 if (m_mapOrientation == Qt::Vertical)
215 // consecutive data is read from model's column
228 // consecutive data is read from model's column
216 return m_model->data(m_model->index(pos + m_mapFirst, m_mapY), Qt::DisplayRole).toDouble();
229 return m_model->data(m_model->index(pos + m_mapFirst, m_mapY), Qt::DisplayRole).toDouble();
217 else
230 else
218 // consecutive data is read from model's row
231 // consecutive data is read from model's row
219 return m_model->data(m_model->index(m_mapY, pos + m_mapFirst), Qt::DisplayRole).toDouble();
232 return m_model->data(m_model->index(m_mapY, pos + m_mapFirst), Qt::DisplayRole).toDouble();
220 } else {
233 } else {
221 // model is not specified, return the data from series' internal data store
234 // model is not specified, return the data from series' internal data store
222 return m_y.at(pos);
235 return m_y.at(pos);
223 }
236 }
224 }
237 }
225
238
226 /*!
239 /*!
227 Returns number of data points within series.
240 Returns number of data points within series.
228 */
241 */
229 int QXYSeries::count() const
242 int QXYSeries::count() const
230 {
243 {
231 Q_ASSERT(m_x.size() == m_y.size());
244 Q_ASSERT(m_x.size() == m_y.size());
232
245
233 if (m_model) {
246 if (m_model) {
234 if (m_mapOrientation == Qt::Vertical) {
247 if (m_mapOrientation == Qt::Vertical) {
235 // data is in a column. Return the number of mapped items if the model's column have enough items
248 // data is in a column. Return the number of mapped items if the model's column have enough items
236 // or the number of items that can be mapped
249 // or the number of items that can be mapped
237 if (m_mapLimited)
250 if (m_mapLimited)
238 return qMin(m_mapCount, qMax(m_model->rowCount() - m_mapFirst, 0));
251 return qMin(m_mapCount, qMax(m_model->rowCount() - m_mapFirst, 0));
239 else
252 else
240 return qMax(m_model->rowCount() - m_mapFirst, 0);
253 return qMax(m_model->rowCount() - m_mapFirst, 0);
241 } else {
254 } else {
242 // data is in a row. Return the number of mapped items if the model's row have enough items
255 // data is in a row. Return the number of mapped items if the model's row have enough items
243 // or the number of items that can be mapped
256 // or the number of items that can be mapped
244 if (m_mapLimited)
257 if (m_mapLimited)
245 return qMin(m_mapCount, qMax(m_model->columnCount() - m_mapFirst, 0));
258 return qMin(m_mapCount, qMax(m_model->columnCount() - m_mapFirst, 0));
246 else
259 else
247 return qMax(m_model->columnCount() - m_mapFirst, 0);
260 return qMax(m_model->columnCount() - m_mapFirst, 0);
248 }
261 }
249 }
262 }
250
263
251 // model is not specified, return the number of points in the series internal data store
264 // model is not specified, return the number of points in the series internal data store
252 return m_x.size();
265 return m_x.size();
253 }
266 }
254
267
255 /*!
268 /*!
256 Returns the data points of the series.
269 Returns the data points of the series.
257 */
270 */
258 QList<QPointF> QXYSeries::data()
271 QList<QPointF> QXYSeries::data()
259 {
272 {
260 QList<QPointF> data;
273 QList<QPointF> data;
261 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
274 for (int i(0); i < m_x.count() && i < m_y.count(); i++)
262 data.append(QPointF(m_x.at(i), m_y.at(i)));
275 data.append(QPointF(m_x.at(i), m_y.at(i)));
263 return data;
276 return data;
264 }
277 }
265
278
266
279
267 /*!
280 /*!
268 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
281 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
269 pen from chart theme is used.
282 pen from chart theme is used.
270 \sa QChart::setChartTheme()
283 \sa QChart::setChartTheme()
271 */
284 */
272 void QXYSeries::setPen(const QPen &pen)
285 void QXYSeries::setPen(const QPen &pen)
273 {
286 {
274 if (pen != m_pen) {
287 if (pen != m_pen) {
275 m_pen = pen;
288 m_pen = pen;
276 emit updated();
289 emit updated();
277 }
290 }
278 }
291 }
279
292
280 /*!
293 /*!
281 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
294 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
282 from chart theme setting is used.
295 from chart theme setting is used.
283 \sa QChart::setChartTheme()
296 \sa QChart::setChartTheme()
284 */
297 */
285
298
286 void QXYSeries::setBrush(const QBrush &brush)
299 void QXYSeries::setBrush(const QBrush &brush)
287 {
300 {
288 if (brush != m_brush) {
301 if (brush != m_brush) {
289 m_brush = brush;
302 m_brush = brush;
290 emit updated();
303 emit updated();
291 }
304 }
292 }
305 }
293
306
294
307
295 /*!
308 /*!
296 Stream operator for adding a data \a point to the series.
309 Stream operator for adding a data \a point to the series.
297 \sa append()
310 \sa append()
298 */
311 */
299
312
300 QXYSeries& QXYSeries::operator<< (const QPointF &point)
313 QXYSeries& QXYSeries::operator<< (const QPointF &point)
301 {
314 {
302 append(point);
315 append(point);
303 return *this;
316 return *this;
304 }
317 }
305
318
306
319
307 /*!
320 /*!
308 Stream operator for adding a list of \a points to the series.
321 Stream operator for adding a list of \a points to the series.
309 \sa append()
322 \sa append()
310 */
323 */
311
324
312 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
325 QXYSeries& QXYSeries::operator<< (const QList<QPointF> points)
313 {
326 {
314 append(points);
327 append(points);
315 return *this;
328 return *this;
316 }
329 }
317
330
318 /*!
331 /*!
319 \internal
332 \internal
320 */
333 */
321 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
334 void QXYSeries::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
322 {
335 {
323 Q_UNUSED(bottomRight)
336 Q_UNUSED(bottomRight)
324
337
325 if (m_mapOrientation == Qt::Vertical) {
338 if (m_mapOrientation == Qt::Vertical) {
326 if (topLeft.row() >= m_mapFirst && (!m_mapLimited || topLeft.row() < m_mapFirst + m_mapCount))
339 if (topLeft.row() >= m_mapFirst && (!m_mapLimited || topLeft.row() < m_mapFirst + m_mapCount))
327 emit pointReplaced(topLeft.row() - m_mapFirst);
340 emit pointReplaced(topLeft.row() - m_mapFirst);
328 } else {
341 } else {
329 if (topLeft.column() >= m_mapFirst && (!m_mapLimited || topLeft.column() < m_mapFirst + m_mapCount))
342 if (topLeft.column() >= m_mapFirst && (!m_mapLimited || topLeft.column() < m_mapFirst + m_mapCount))
330 emit pointReplaced(topLeft.column() - m_mapFirst);
343 emit pointReplaced(topLeft.column() - m_mapFirst);
331 }
344 }
332 }
345 }
333
346
334 /*!
347 /*!
335 \internal
348 \internal
336 */
349 */
337 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
350 void QXYSeries::modelDataAboutToBeAdded(QModelIndex parent, int start, int end)
338 {
351 {
339 Q_UNUSED(parent)
352 Q_UNUSED(parent)
340 // Q_UNUSED(end)
353 // Q_UNUSED(end)
341
354
342 if (m_mapLimited) {
355 if (m_mapLimited) {
343 if (start >= m_mapFirst + m_mapCount) {
356 if (start >= m_mapFirst + m_mapCount) {
344 // the added data is below mapped area
357 // the added data is below mapped area
345 // therefore it has no relevance
358 // therefore it has no relevance
346 return;
359 return;
347 } else {
360 } else {
348 // the added data is in the mapped area or before it and update is needed
361 // the added data is in the mapped area or before it and update is needed
349
362
350 // check how many mapped items there is currently (before new items are added)
363 // check how many mapped items there is currently (before new items are added)
351 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
364 // if the number of items currently is equal the m_mapCount then some needs to be removed from xychartitem
352 // internal storage before new ones can be added
365 // internal storage before new ones can be added
353
366
354 int itemsToRemove = qMin(count() - qMax(start - m_mapFirst, 0), end - start + 1);
367 int itemsToRemove = qMin(count() - qMax(start - m_mapFirst, 0), end - start + 1);
355 if (m_mapCount == count()) {
368 if (m_mapCount == count()) {
356 for (int i = 0; i < itemsToRemove; i++)
369 for (int i = 0; i < itemsToRemove; i++)
357 emit pointRemoved(qMin(end, count()) - i);
370 emit pointRemoved(qMin(end, count()) - i);
358 }
371 }
359 }
372 }
360 } else {
373 } else {
361 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
374 // map is not limited (it includes all the items starting from m_mapFirst till the end of model)
362 // nothing to do
375 // nothing to do
363 // emit pointAdded(qMax(start - m_mapFirst, 0));
376 // emit pointAdded(qMax(start - m_mapFirst, 0));
364 }
377 }
365 }
378 }
366
379
367 /*!
380 /*!
368 \internal
381 \internal
369 */
382 */
370 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
383 void QXYSeries::modelDataAdded(QModelIndex parent, int start, int end)
371 {
384 {
372 Q_UNUSED(parent)
385 Q_UNUSED(parent)
373 // Q_UNUSED(end)
386 // Q_UNUSED(end)
374
387
375 if (m_mapLimited) {
388 if (m_mapLimited) {
376 if (start >= m_mapFirst + m_mapCount) {
389 if (start >= m_mapFirst + m_mapCount) {
377 // the added data is below mapped area
390 // the added data is below mapped area
378 // therefore it has no relevance
391 // therefore it has no relevance
379 return;
392 return;
380 } else {
393 } else {
381 // the added data is in the mapped area or before it
394 // the added data is in the mapped area or before it
382 // update needed
395 // update needed
383 if (count() > 0) {
396 if (count() > 0) {
384 int toBeAdded = qMin(m_mapCount - (start - m_mapFirst), end - start + 1);
397 int toBeAdded = qMin(m_mapCount - (start - m_mapFirst), end - start + 1);
385 for (int i = 0; i < toBeAdded; i++)
398 for (int i = 0; i < toBeAdded; i++)
386 if (start + i >= m_mapFirst)
399 if (start + i >= m_mapFirst)
387 emit pointAdded(start + i);
400 emit pointAdded(start + i);
388 }
401 }
389 }
402 }
390 } else {
403 } else {
391 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
404 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
392 for (int i = 0; i < end - start + 1; i++)
405 for (int i = 0; i < end - start + 1; i++)
393 emit pointAdded(start + i);
406 emit pointAdded(start + i);
394 }
407 }
395 }
408 }
396
409
397 /*!
410 /*!
398 \internal
411 \internal
399 */
412 */
400 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
413 void QXYSeries::modelDataAboutToBeRemoved(QModelIndex parent, int start, int end)
401 {
414 {
402 Q_UNUSED(parent)
415 Q_UNUSED(parent)
403 // Q_UNUSED(end)
416 // Q_UNUSED(end)
404
417
405 if (m_mapLimited) {
418 if (m_mapLimited) {
406 if (start >= m_mapFirst + m_mapCount) {
419 if (start >= m_mapFirst + m_mapCount) {
407 // the removed data is below mapped area
420 // the removed data is below mapped area
408 // therefore it has no relevance
421 // therefore it has no relevance
409 return;
422 return;
410 } else {
423 } else {
411 // the removed data is in the mapped area or before it
424 // the removed data is in the mapped area or before it
412 // update needed
425 // update needed
413
426
414 // check how many items need to be removed from the xychartitem storage
427 // check how many items need to be removed from the xychartitem storage
415 // the number equals the number of items that are removed and that lay before
428 // the number equals the number of items that are removed and that lay before
416 // or in the mapped area. Items that lay beyond the map do not count
429 // or in the mapped area. Items that lay beyond the map do not count
417 // the max is the current number of items in storage (count())
430 // the max is the current number of items in storage (count())
418 int itemsToRemove = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
431 int itemsToRemove = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
419 for (int i = 0; i < itemsToRemove; i++)
432 for (int i = 0; i < itemsToRemove; i++)
420 emit pointRemoved(start);
433 emit pointRemoved(start);
421 }
434 }
422 } else {
435 } else {
423 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
436 // map is not limited (it included all the items starting from m_mapFirst till the end of model)
424 for (int i = 0; i < end - start + 1; i++)
437 for (int i = 0; i < end - start + 1; i++)
425 emit pointRemoved(start);
438 emit pointRemoved(start);
426 }
439 }
427 }
440 }
428
441
429 /*!
442 /*!
430 \internal
443 \internal
431 */
444 */
432 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
445 void QXYSeries::modelDataRemoved(QModelIndex parent, int start, int end)
433 {
446 {
434 Q_UNUSED(parent)
447 Q_UNUSED(parent)
435 Q_UNUSED(end)
448 Q_UNUSED(end)
436
449
437 // how many items there were before data was removed
450 // how many items there were before data was removed
438 // int oldCount = count() - 1;
451 // int oldCount = count() - 1;
439
452
440 if (m_mapLimited) {
453 if (m_mapLimited) {
441 if (start >= m_mapFirst + m_mapCount) {
454 if (start >= m_mapFirst + m_mapCount) {
442 // the removed data is below mapped area
455 // the removed data is below mapped area
443 // therefore it has no relevance
456 // therefore it has no relevance
444 return;
457 return;
445 } else {
458 } else {
446 // if the current items count in the whole model is bigger than the index of the last item
459 // if the current items count in the whole model is bigger than the index of the last item
447 // that was removed than it means there are some extra items available
460 // that was removed than it means there are some extra items available
448
461
449 int removedItemsCount = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
462 int removedItemsCount = qMin(count(), qMin(end, m_mapFirst + m_mapCount - 1) - start + 1);
450 int extraItemsAvailable = 0;
463 int extraItemsAvailable = 0;
451 if (m_mapOrientation == Qt::Vertical) {
464 if (m_mapOrientation == Qt::Vertical) {
452 extraItemsAvailable = qMax(m_model->rowCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
465 extraItemsAvailable = qMax(m_model->rowCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
453 } else {
466 } else {
454 extraItemsAvailable = qMax(m_model->columnCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
467 extraItemsAvailable = qMax(m_model->columnCount() + (end - start + 1) - qMax(end + 1, m_mapFirst + m_mapCount), 0);
455 }
468 }
456
469
457 // if there are excess items available (below the mapped area) use them to repopulate mapped area
470 // if there are excess items available (below the mapped area) use them to repopulate mapped area
458 int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
471 int toBeAdded = qMin(extraItemsAvailable, removedItemsCount);
459 for (int k = 0; k < toBeAdded; k++)
472 for (int k = 0; k < toBeAdded; k++)
460 emit pointAdded(m_mapFirst + m_mapCount - removedItemsCount + k);
473 emit pointAdded(m_mapFirst + m_mapCount - removedItemsCount + k);
461 }
474 }
462 } else {
475 } else {
463 // data was removed from XYSeries interal storage. Nothing more to do
476 // data was removed from XYSeries interal storage. Nothing more to do
464 }
477 }
465 }
478 }
466
479
467 /*!
480 /*!
468 \fn QAbstractItemModel* QXYSeries::model()
481 \fn QAbstractItemModel* QXYSeries::model()
469 Returns the model from which the series takes its data.
482 Returns the model from which the series takes its data.
470 */
483 */
471
484
472 /*!
485 /*!
473 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
486 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
474 Sets the \a model to be used as a data source
487 Sets the \a model to be used as a data source
488 \sa setModelMapping(), setModelMappingRange()
475 */
489 */
476 bool QXYSeries::setModel(QAbstractItemModel *model) {
490 bool QXYSeries::setModel(QAbstractItemModel *model) {
477
491
478 // disconnect signals from old model
492 // disconnect signals from old model
479 if (m_model) {
493 if (m_model) {
480 disconnect(m_model, 0, this, 0);
494 disconnect(m_model, 0, this, 0);
481 m_mapX = -1;
495 m_mapX = -1;
482 m_mapY = -1;
496 m_mapY = -1;
483 m_mapFirst = 0;
497 m_mapFirst = 0;
484 m_mapCount = 0;
498 m_mapCount = 0;
485 m_mapLimited = false;
499 m_mapLimited = false;
486 m_mapOrientation = Qt::Vertical;
500 m_mapOrientation = Qt::Vertical;
487 }
501 }
488
502
489 // set new model
503 // set new model
490 if (model) {
504 if (model) {
491 m_model = model;
505 m_model = model;
492 return true;
506 return true;
493 } else {
507 } else {
494 m_model = 0;
508 m_model = 0;
495 return false;
509 return false;
496 }
510 }
497 }
511 }
498
512
513 /*!
514 \fn bool QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
515 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
516 as a data source for y coordinate. The \a orientation paramater specifies whether the data
517 is in columns or in rows.
518 \sa setModel(), setModelMappingRange()
519 */
499 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
520 void QXYSeries::setModelMapping(int modelX, int modelY, Qt::Orientation orientation)
500 {
521 {
501 if (m_model == 0)
522 if (m_model == 0)
502 return;
523 return;
503 m_mapX = modelX;
524 m_mapX = modelX;
504 m_mapY = modelY;
525 m_mapY = modelY;
505 m_mapFirst = 0;
526 m_mapFirst = 0;
506 m_mapOrientation = orientation;
527 m_mapOrientation = orientation;
507 if (m_mapOrientation == Qt::Vertical) {
528 if (m_mapOrientation == Qt::Vertical) {
508 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
529 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
509 connect(m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
530 connect(m_model,SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
510 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
531 connect(m_model,SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
511 connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
532 connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
512 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
533 connect(m_model, SIGNAL(rowsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
513 } else {
534 } else {
514 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
535 connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SLOT(modelUpdated(QModelIndex, QModelIndex)));
515 connect(m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
536 connect(m_model,SIGNAL(columnsAboutToBeInserted(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeAdded(QModelIndex,int,int)));
516 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
537 connect(m_model,SIGNAL(columnsInserted(QModelIndex, int, int)), this, SLOT(modelDataAdded(QModelIndex,int,int)));
517 connect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
538 connect(m_model, SIGNAL(columnsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(modelDataAboutToBeRemoved(QModelIndex,int,int)));
518 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
539 connect(m_model, SIGNAL(columnsRemoved(QModelIndex, int, int)), this, SLOT(modelDataRemoved(QModelIndex,int,int)));
519 }
540 }
520 }
541 }
521
542
543 /*!
544 \fn bool QXYSeries::setModelMappingRange(int first, int count)
545 Allows limiting the model mapping.
546 Parameter \a first specifies which element of the model should be used as a first one of the series.
547 Parameter \a count specifies how many elements should be mapped. If count is not specified (defaults to -1)
548 then all the items following \a first item in a model are used.
549 \sa setModel(), setModelMapping()
550 */
522 void QXYSeries::setModelMappingRange(int first, int count)
551 void QXYSeries::setModelMappingRange(int first, int count)
523 {
552 {
524 m_mapFirst = first;
553 m_mapFirst = first;
525 if (count == 0) {
554 if (count == 0) {
526 m_mapLimited = false;
555 m_mapLimited = false;
527 } else {
556 } else {
528 m_mapCount = count;
557 m_mapCount = count;
529 m_mapLimited = true;
558 m_mapLimited = true;
530 }
559 }
531 }
560 }
532
561
533 #include "moc_qxyseries.cpp"
562 #include "moc_qxyseries.cpp"
534
563
535 QTCOMMERCIALCHART_END_NAMESPACE
564 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,103 +1,104
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 QXYSERIES_H_
21 #ifndef QXYSERIES_H_
22 #define QXYSERIES_H_
22 #define QXYSERIES_H_
23
23
24 #include <qchartglobal.h>
24 #include <qchartglobal.h>
25 #include <qseries.h>
25 #include <qseries.h>
26 #include <QPen>
26 #include <QPen>
27 #include <QBrush>
27 #include <QBrush>
28
28
29 class QModelIndex;
29 class QModelIndex;
30
30
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32
32
33 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
33 class QTCOMMERCIALCHART_EXPORT QXYSeries : public QSeries
34 {
34 {
35 Q_OBJECT
35 Q_OBJECT
36 protected:
36 protected:
37 QXYSeries(QObject *parent = 0);
37 QXYSeries(QObject *parent = 0);
38 virtual ~QXYSeries();
38 virtual ~QXYSeries();
39
39
40 public:
40 public:
41 void append(qreal x, qreal y);
41 void append(qreal x, qreal y);
42 void append(const QPointF &point);
42 void append(const QPointF &point);
43 void append(const QList<QPointF> points);
43 void append(const QList<QPointF> points);
44 void replace(qreal x,qreal y);
44 void replace(qreal x,qreal y);
45 void replace(const QPointF &point);
45 void replace(const QPointF &point);
46 void remove(qreal x);
46 void remove(qreal x);
47 void remove(qreal x, qreal y);
47 void remove(qreal x, qreal y);
48 void remove(const QPointF &point);
48 void remove(const QPointF &point);
49 void removeAll();
49 void removeAll();
50
50
51 int count() const;
51 int count() const;
52 qreal x(int pos) const;
52 qreal x(int pos) const;
53 qreal y(int pos) const;
53 qreal y(int pos) const;
54 QList<QPointF> data();
54 QList<QPointF> data();
55
55
56 QXYSeries& operator << (const QPointF &point);
56 QXYSeries& operator << (const QPointF &point);
57 QXYSeries& operator << (const QList<QPointF> points);
57 QXYSeries& operator << (const QList<QPointF> points);
58
58
59 void setPen(const QPen &pen);
59 void setPen(const QPen &pen);
60 QPen pen() const {return m_pen;}
60 QPen pen() const {return m_pen;}
61 void setBrush(const QBrush &brush);
61 void setBrush(const QBrush &brush);
62 QBrush brush() const {return m_brush;}
62 QBrush brush() const {return m_brush;}
63
63
64 bool setModel(QAbstractItemModel *model);
64 bool setModel(QAbstractItemModel *model);
65
65
66 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
66 virtual void setModelMapping(int modelX, int modelY, Qt::Orientation orientation = Qt::Vertical);
67 virtual void setModelMappingRange(int first, int count = 0);
67 virtual void setModelMappingRange(int first, int count = 0);
68 int mapFirst() const { return m_mapFirst; }
68 int mapFirst() const { return m_mapFirst; }
69 int mapCount() const { return m_mapCount; }
69
70
70 private Q_SLOTS:
71 private Q_SLOTS:
71 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
72 void modelUpdated(QModelIndex topLeft, QModelIndex bottomRight);
72 void modelDataAboutToBeAdded(QModelIndex parent, int start, int end);
73 void modelDataAboutToBeAdded(QModelIndex parent, int start, int end);
73 void modelDataAdded(QModelIndex parent, int start, int end);
74 void modelDataAdded(QModelIndex parent, int start, int end);
74 void modelDataAboutToBeRemoved(QModelIndex parent, int start, int end);
75 void modelDataAboutToBeRemoved(QModelIndex parent, int start, int end);
75 void modelDataRemoved(QModelIndex parent, int start, int end);
76 void modelDataRemoved(QModelIndex parent, int start, int end);
76
77
77 Q_SIGNALS:
78 Q_SIGNALS:
78 void clicked(const QPointF &point);
79 void clicked(const QPointF &point);
79 void selected();
80 void selected();
80 void updated();
81 void updated();
81 void pointReplaced(int index);
82 void pointReplaced(int index);
82 void pointRemoved(int index);
83 void pointRemoved(int index);
83 void pointAdded(int index);
84 void pointAdded(int index);
84
85
85 protected:
86 protected:
86 QVector<qreal> m_x;
87 QVector<qreal> m_x;
87 QVector<qreal> m_y;
88 QVector<qreal> m_y;
88
89
89 QPen m_pen;
90 QPen m_pen;
90 QBrush m_brush;
91 QBrush m_brush;
91
92
92 int m_mapX;
93 int m_mapX;
93 int m_mapY;
94 int m_mapY;
94 int m_mapFirst;
95 int m_mapFirst;
95 int m_mapCount;
96 int m_mapCount;
96 bool m_mapLimited;
97 bool m_mapLimited;
97 Qt::Orientation m_mapOrientation;
98 Qt::Orientation m_mapOrientation;
98 int tempItemsRemoved;
99 int tempItemsRemoved;
99 };
100 };
100
101
101 QTCOMMERCIALCHART_END_NAMESPACE
102 QTCOMMERCIALCHART_END_NAMESPACE
102
103
103 #endif
104 #endif
General Comments 0
You need to be logged in to leave comments. Login now