##// END OF EJS Templates
Fixes legend markers updates
Michal Klocek -
r2085:224fca6f4967
parent child
Show More
@@ -1,867 +1,859
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 "qabstractbarseries.h"
21 #include "qabstractbarseries.h"
22 #include "qabstractbarseries_p.h"
22 #include "qabstractbarseries_p.h"
23 #include "qbarset.h"
23 #include "qbarset.h"
24 #include "qbarset_p.h"
24 #include "qbarset_p.h"
25 #include "domain_p.h"
25 #include "domain_p.h"
26 #include "legendmarker_p.h"
26 #include "legendmarker_p.h"
27 #include "chartdataset_p.h"
27 #include "chartdataset_p.h"
28 #include "charttheme_p.h"
28 #include "charttheme_p.h"
29 #include "qvalueaxis.h"
29 #include "qvalueaxis.h"
30 #include "qbarcategoryaxis.h"
30 #include "qbarcategoryaxis.h"
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 /*!
34 /*!
35 \class QAbstractBarSeries
35 \class QAbstractBarSeries
36 \brief Series for creating a bar chart
36 \brief Series for creating a bar chart
37 \mainclass
37 \mainclass
38
38
39 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
39 QAbstractBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars to
40 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
40 the position defined by data. Single bar is defined by QPointF, where x value is the x-coordinate of the bar
41 and y-value is the height of the bar. The category names are ignored with this series and x-axis
41 and y-value is the height of the bar. The category names are ignored with this series and x-axis
42 shows the x-values.
42 shows the x-values.
43
43
44 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
44 See the \l {BarChart Example} {bar chart example} to learn how to create a simple bar chart.
45 \image examples_barchart.png
45 \image examples_barchart.png
46
46
47 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
47 \sa QBarSet, QStackedBarSeries, QPercentBarSeries
48 */
48 */
49 /*!
49 /*!
50 \qmlclass AbstractBarSeries QAbstractBarSeries
50 \qmlclass AbstractBarSeries QAbstractBarSeries
51 \inherits QAbstractSeries
51 \inherits QAbstractSeries
52
52
53 The following QML shows how to create a simple bar chart:
53 The following QML shows how to create a simple bar chart:
54 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
54 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
55
55
56 \beginfloatleft
56 \beginfloatleft
57 \image demos_qmlchart6.png
57 \image demos_qmlchart6.png
58 \endfloat
58 \endfloat
59 \clearfloat
59 \clearfloat
60 */
60 */
61
61
62 /*!
62 /*!
63 \property QAbstractBarSeries::barWidth
63 \property QAbstractBarSeries::barWidth
64 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
64 The width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
65 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
65 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
66 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
66 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
67 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
67 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
68 \sa QBarSeries
68 \sa QBarSeries
69 */
69 */
70 /*!
70 /*!
71 \qmlproperty real AbstractBarSeries::barWidth
71 \qmlproperty real AbstractBarSeries::barWidth
72 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
72 The width of the bars of the series. The unit of width is the unit of x-axis. The minimum width for bars
73 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
73 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
74 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
74 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
75 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
75 Note that with QBarSeries this value means the width of one group of bars instead of just one bar.
76 */
76 */
77
77
78 /*!
78 /*!
79 \property QAbstractBarSeries::count
79 \property QAbstractBarSeries::count
80 Holds the number of sets in series.
80 Holds the number of sets in series.
81 */
81 */
82 /*!
82 /*!
83 \qmlproperty int AbstractBarSeries::count
83 \qmlproperty int AbstractBarSeries::count
84 Holds the number of sets in series.
84 Holds the number of sets in series.
85 */
85 */
86
86
87 /*!
87 /*!
88 \property QAbstractBarSeries::labelsVisible
88 \property QAbstractBarSeries::labelsVisible
89 Defines the visibility of the labels in series
89 Defines the visibility of the labels in series
90 */
90 */
91 /*!
91 /*!
92 \qmlproperty bool AbstractBarSeries::labelsVisible
92 \qmlproperty bool AbstractBarSeries::labelsVisible
93 Defines the visibility of the labels in series
93 Defines the visibility of the labels in series
94 */
94 */
95
95
96 /*!
96 /*!
97 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
97 \fn void QAbstractBarSeries::clicked(int index, QBarSet *barset)
98 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
98 The signal is emitted if the user clicks with a mouse on top of QBarSet \a barset.
99 Clicked bar inside set is indexed by \a index
99 Clicked bar inside set is indexed by \a index
100 */
100 */
101 /*!
101 /*!
102 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
102 \qmlsignal AbstractBarSeries::onClicked(int index, BarSet barset)
103 The signal is emitted if the user clicks with a mouse on top of BarSet.
103 The signal is emitted if the user clicks with a mouse on top of BarSet.
104 Clicked bar inside set is indexed by \a index
104 Clicked bar inside set is indexed by \a index
105 */
105 */
106
106
107 /*!
107 /*!
108 \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
108 \fn void QAbstractBarSeries::hovered(bool status, QBarSet* barset)
109
109
110 The signal is emitted if mouse is hovered on top of series.
110 The signal is emitted if mouse is hovered on top of series.
111 Parameter \a barset is the pointer of barset, where hover happened.
111 Parameter \a barset is the pointer of barset, where hover happened.
112 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
112 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
113 */
113 */
114 /*!
114 /*!
115 \qmlsignal AbstractBarSeries::onHovered(bool status, BarSet barset)
115 \qmlsignal AbstractBarSeries::onHovered(bool status, BarSet barset)
116
116
117 The signal is emitted if mouse is hovered on top of series.
117 The signal is emitted if mouse is hovered on top of series.
118 Parameter \a barset is the pointer of barset, where hover happened.
118 Parameter \a barset is the pointer of barset, where hover happened.
119 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
119 Parameter \a status is true, if mouse entered on top of series, false if mouse left from top of series.
120 */
120 */
121
121
122 /*!
122 /*!
123 \fn void QAbstractBarSeries::countChanged()
123 \fn void QAbstractBarSeries::countChanged()
124 This signal is emitted when barset count has been changed, for example by append or remove.
124 This signal is emitted when barset count has been changed, for example by append or remove.
125 */
125 */
126 /*!
126 /*!
127 \qmlsignal AbstractBarSeries::onCountChanged()
127 \qmlsignal AbstractBarSeries::onCountChanged()
128 This signal is emitted when barset count has been changed, for example by append or remove.
128 This signal is emitted when barset count has been changed, for example by append or remove.
129 */
129 */
130
130
131 /*!
131 /*!
132 \fn void QAbstractBarSeries::labelsVisibleChanged()
132 \fn void QAbstractBarSeries::labelsVisibleChanged()
133 This signal is emitted when labels visibility have changed.
133 This signal is emitted when labels visibility have changed.
134 \sa isLabelsVisible(), setLabelsVisible()
134 \sa isLabelsVisible(), setLabelsVisible()
135 */
135 */
136
136
137 /*!
137 /*!
138 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
138 \fn void QAbstractBarSeries::barsetsAdded(QList<QBarSet*> sets)
139 This signal is emitted when \a sets have been added to the series.
139 This signal is emitted when \a sets have been added to the series.
140 \sa append(), insert()
140 \sa append(), insert()
141 */
141 */
142 /*!
142 /*!
143 \qmlsignal AbstractBarSeries::onAdded(BarSet barset)
143 \qmlsignal AbstractBarSeries::onAdded(BarSet barset)
144 Emitted when \a barset has been added to the series.
144 Emitted when \a barset has been added to the series.
145 */
145 */
146
146
147 /*!
147 /*!
148 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
148 \fn void QAbstractBarSeries::barsetsRemoved(QList<QBarSet*> sets)
149 This signal is emitted when \a sets have been removed from the series.
149 This signal is emitted when \a sets have been removed from the series.
150 \sa remove()
150 \sa remove()
151 */
151 */
152 /*!
152 /*!
153 \qmlsignal AbstractBarSeries::onRemoved(BarSet barset)
153 \qmlsignal AbstractBarSeries::onRemoved(BarSet barset)
154 Emitted when \a barset has been removed from the series.
154 Emitted when \a barset has been removed from the series.
155 */
155 */
156
156
157 /*!
157 /*!
158 \qmlmethod BarSet AbstractBarSeries::at(int index)
158 \qmlmethod BarSet AbstractBarSeries::at(int index)
159 Returns bar set at \a index. Returns null if the index is not valid.
159 Returns bar set at \a index. Returns null if the index is not valid.
160 */
160 */
161
161
162 /*!
162 /*!
163 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
163 \qmlmethod BarSet AbstractBarSeries::append(string label, VariantList values)
164 Adds a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
164 Adds a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
165 For example:
165 For example:
166 \code
166 \code
167 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
167 myBarSeries.append("set 1", [0, 0.2, 0.2, 0.5, 0.4, 1.5, 0.9]);
168 myBarSeries.append("set 2", [Qt.point(0, 1), Qt.point(2, 2.5), Qt.point(3.5, 2.2)]);
168 myBarSeries.append("set 2", [Qt.point(0, 1), Qt.point(2, 2.5), Qt.point(3.5, 2.2)]);
169 \endcode
169 \endcode
170 */
170 */
171
171
172 /*!
172 /*!
173 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
173 \qmlmethod BarSet AbstractBarSeries::insert(int index, string label, VariantList values)
174 Inserts a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
174 Inserts a new bar set with \a label and \a values to \a index. Values can be a list of reals or a list of XYPoints.
175 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
175 If index is zero or smaller, the new barset is prepended. If the index is count or bigger, the new barset is
176 appended.
176 appended.
177 \sa AbstractBarSeries::append()
177 \sa AbstractBarSeries::append()
178 */
178 */
179
179
180 /*!
180 /*!
181 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
181 \qmlmethod bool AbstractBarSeries::remove(BarSet barset)
182 Removes the barset from the series. Returns true if successful, false otherwise.
182 Removes the barset from the series. Returns true if successful, false otherwise.
183 */
183 */
184
184
185 /*!
185 /*!
186 \qmlmethod AbstractBarSeries::clear()
186 \qmlmethod AbstractBarSeries::clear()
187 Removes all barsets from the series.
187 Removes all barsets from the series.
188 */
188 */
189
189
190 /*!
190 /*!
191 Destructs abstractbarseries and owned barsets.
191 Destructs abstractbarseries and owned barsets.
192 */
192 */
193 QAbstractBarSeries::~QAbstractBarSeries()
193 QAbstractBarSeries::~QAbstractBarSeries()
194 {
194 {
195
195
196 }
196 }
197
197
198 /*!
198 /*!
199 \internal
199 \internal
200 */
200 */
201 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &d, QObject *parent) :
201 QAbstractBarSeries::QAbstractBarSeries(QAbstractBarSeriesPrivate &o, QObject *parent) :
202 QAbstractSeries(d,parent)
202 QAbstractSeries(o,parent)
203 {
203 {
204 Q_D(QAbstractSeries);
205 QObject::connect(this,SIGNAL(countChanged()),d,SIGNAL(countChanged()));
204 }
206 }
205
207
206 /*!
208 /*!
207 Sets the width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
209 Sets the width of the bars of the series. The unit of \a width is the unit of x-axis. The minimum width for bars
208 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
210 is zero and negative values are treated as zero. Setting the width to zero means that width of the bar on screen
209 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
211 is one pixel no matter what the scale of x-axis is. Bars wider than zero are scaled with x-axis.
210 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
212 Note that with \link QBarSeries \endlink this value means the width of one group of bars instead of just one bar.
211 */
213 */
212 void QAbstractBarSeries::setBarWidth(qreal width)
214 void QAbstractBarSeries::setBarWidth(qreal width)
213 {
215 {
214 Q_D(QAbstractBarSeries);
216 Q_D(QAbstractBarSeries);
215 d->setBarWidth(width);
217 d->setBarWidth(width);
216 }
218 }
217
219
218 /*!
220 /*!
219 Returns the width of the bars of the series.
221 Returns the width of the bars of the series.
220 \sa setBarWidth()
222 \sa setBarWidth()
221 */
223 */
222 qreal QAbstractBarSeries::barWidth() const
224 qreal QAbstractBarSeries::barWidth() const
223 {
225 {
224 Q_D(const QAbstractBarSeries);
226 Q_D(const QAbstractBarSeries);
225 return d->barWidth();
227 return d->barWidth();
226 }
228 }
227
229
228 /*!
230 /*!
229 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
231 Adds a set of bars to series. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
230 Returns true, if appending succeeded.
232 Returns true, if appending succeeded.
231 */
233 */
232 bool QAbstractBarSeries::append(QBarSet *set)
234 bool QAbstractBarSeries::append(QBarSet *set)
233 {
235 {
234 Q_D(QAbstractBarSeries);
236 Q_D(QAbstractBarSeries);
235 bool success = d->append(set);
237 bool success = d->append(set);
236 if (success) {
238 if (success) {
237 QList<QBarSet*> sets;
239 QList<QBarSet*> sets;
238 sets.append(set);
240 sets.append(set);
239 set->setParent(this);
241 set->setParent(this);
240 emit barsetsAdded(sets);
242 emit barsetsAdded(sets);
241 emit countChanged();
243 emit countChanged();
242 }
244 }
243 return success;
245 return success;
244 }
246 }
245
247
246 /*!
248 /*!
247 Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
249 Removes barset from series. Releases ownership of \a set. Deletes the set, if remove
248 was successful.
250 was successful.
249 Returns true, if set was removed.
251 Returns true, if set was removed.
250 */
252 */
251 bool QAbstractBarSeries::remove(QBarSet *set)
253 bool QAbstractBarSeries::remove(QBarSet *set)
252 {
254 {
253 Q_D(QAbstractBarSeries);
255 Q_D(QAbstractBarSeries);
254 bool success = d->remove(set);
256 bool success = d->remove(set);
255 if (success) {
257 if (success) {
256 QList<QBarSet*> sets;
258 QList<QBarSet*> sets;
257 sets.append(set);
259 sets.append(set);
258 set->setParent(0);
260 set->setParent(0);
259 emit barsetsRemoved(sets);
261 emit barsetsRemoved(sets);
260 emit countChanged();
262 emit countChanged();
261 delete set;
263 delete set;
262 set = 0;
264 set = 0;
263 }
265 }
264 return success;
266 return success;
265 }
267 }
266
268
267 /*!
269 /*!
268 Takes a single \a set from the series. Does not delete the barset object.
270 Takes a single \a set from the series. Does not delete the barset object.
269
271
270 NOTE: The series remains as the barset's parent object. You must set the
272 NOTE: The series remains as the barset's parent object. You must set the
271 parent object to take full ownership.
273 parent object to take full ownership.
272
274
273 Returns true if take was successful.
275 Returns true if take was successful.
274 */
276 */
275 bool QAbstractBarSeries::take(QBarSet *set)
277 bool QAbstractBarSeries::take(QBarSet *set)
276 {
278 {
277 Q_D(QAbstractBarSeries);
279 Q_D(QAbstractBarSeries);
278 bool success = d->remove(set);
280 bool success = d->remove(set);
279 if (success) {
281 if (success) {
280 QList<QBarSet*> sets;
282 QList<QBarSet*> sets;
281 sets.append(set);
283 sets.append(set);
282 emit barsetsRemoved(sets);
284 emit barsetsRemoved(sets);
283 emit countChanged();
285 emit countChanged();
284 }
286 }
285 return success;
287 return success;
286 }
288 }
287
289
288 /*!
290 /*!
289 Adds a list of barsets to series. Takes ownership of \a sets.
291 Adds a list of barsets to series. Takes ownership of \a sets.
290 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
292 Returns true, if all sets were appended successfully. If any of the sets is null or is already appended to series,
291 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
293 nothing is appended and function returns false. If any of the sets is in list more than once, nothing is appended
292 and function returns false.
294 and function returns false.
293 */
295 */
294 bool QAbstractBarSeries::append(QList<QBarSet* > sets)
296 bool QAbstractBarSeries::append(QList<QBarSet* > sets)
295 {
297 {
296 Q_D(QAbstractBarSeries);
298 Q_D(QAbstractBarSeries);
297 bool success = d->append(sets);
299 bool success = d->append(sets);
298 if (success) {
300 if (success) {
299 emit barsetsAdded(sets);
301 emit barsetsAdded(sets);
300 emit countChanged();
302 emit countChanged();
301 }
303 }
302 return success;
304 return success;
303 }
305 }
304
306
305 /*!
307 /*!
306 Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
308 Insert a set of bars to series at \a index postion. Takes ownership of \a set. If the set is null or is already in series, it won't be appended.
307 Returns true, if inserting succeeded.
309 Returns true, if inserting succeeded.
308
310
309 */
311 */
310 bool QAbstractBarSeries::insert(int index, QBarSet *set)
312 bool QAbstractBarSeries::insert(int index, QBarSet *set)
311 {
313 {
312 Q_D(QAbstractBarSeries);
314 Q_D(QAbstractBarSeries);
313 bool success = d->insert(index, set);
315 bool success = d->insert(index, set);
314 if (success) {
316 if (success) {
315 QList<QBarSet*> sets;
317 QList<QBarSet*> sets;
316 sets.append(set);
318 sets.append(set);
317 emit barsetsAdded(sets);
319 emit barsetsAdded(sets);
318 emit countChanged();
320 emit countChanged();
319 }
321 }
320 return success;
322 return success;
321 }
323 }
322
324
323 /*!
325 /*!
324 Removes all barsets from the series. Deletes removed sets.
326 Removes all barsets from the series. Deletes removed sets.
325 */
327 */
326 void QAbstractBarSeries::clear()
328 void QAbstractBarSeries::clear()
327 {
329 {
328 Q_D(QAbstractBarSeries);
330 Q_D(QAbstractBarSeries);
329 QList<QBarSet *> sets = barSets();
331 QList<QBarSet *> sets = barSets();
330 bool success = d->remove(sets);
332 bool success = d->remove(sets);
331 if (success) {
333 if (success) {
332 emit barsetsRemoved(sets);
334 emit barsetsRemoved(sets);
333 emit countChanged();
335 emit countChanged();
334 foreach (QBarSet* set, sets) {
336 foreach (QBarSet* set, sets) {
335 delete set;
337 delete set;
336 }
338 }
337 }
339 }
338 }
340 }
339
341
340 /*!
342 /*!
341 Returns number of sets in series.
343 Returns number of sets in series.
342 */
344 */
343 int QAbstractBarSeries::count() const
345 int QAbstractBarSeries::count() const
344 {
346 {
345 Q_D(const QAbstractBarSeries);
347 Q_D(const QAbstractBarSeries);
346 return d->m_barSets.count();
348 return d->m_barSets.count();
347 }
349 }
348
350
349 /*!
351 /*!
350 Returns a list of sets in series. Keeps ownership of sets.
352 Returns a list of sets in series. Keeps ownership of sets.
351 */
353 */
352 QList<QBarSet*> QAbstractBarSeries::barSets() const
354 QList<QBarSet*> QAbstractBarSeries::barSets() const
353 {
355 {
354 Q_D(const QAbstractBarSeries);
356 Q_D(const QAbstractBarSeries);
355 return d->m_barSets;
357 return d->m_barSets;
356 }
358 }
357
359
358 /*!
360 /*!
359 Sets the visibility of labels in series to \a visible
361 Sets the visibility of labels in series to \a visible
360 */
362 */
361 void QAbstractBarSeries::setLabelsVisible(bool visible)
363 void QAbstractBarSeries::setLabelsVisible(bool visible)
362 {
364 {
363 Q_D(QAbstractBarSeries);
365 Q_D(QAbstractBarSeries);
364 if (d->m_labelsVisible != visible) {
366 if (d->m_labelsVisible != visible) {
365 d->setLabelsVisible(visible);
367 d->setLabelsVisible(visible);
366 emit labelsVisibleChanged();
368 emit labelsVisibleChanged();
367 }
369 }
368 }
370 }
369
371
370 /*!
372 /*!
371 Returns the visibility of labels
373 Returns the visibility of labels
372 */
374 */
373 bool QAbstractBarSeries::isLabelsVisible() const
375 bool QAbstractBarSeries::isLabelsVisible() const
374 {
376 {
375 Q_D(const QAbstractBarSeries);
377 Q_D(const QAbstractBarSeries);
376 return d->m_labelsVisible;
378 return d->m_labelsVisible;
377 }
379 }
378
380
379 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
381 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
380
382
381 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
383 QAbstractBarSeriesPrivate::QAbstractBarSeriesPrivate(QAbstractBarSeries *q) :
382 QAbstractSeriesPrivate(q),
384 QAbstractSeriesPrivate(q),
383 m_barWidth(0.5), // Default value is 50% of category width
385 m_barWidth(0.5), // Default value is 50% of category width
384 m_labelsVisible(false),
386 m_labelsVisible(false),
385 m_visible(true)
387 m_visible(true)
386 {
388 {
387 }
389 }
388
390
389 int QAbstractBarSeriesPrivate::categoryCount() const
391 int QAbstractBarSeriesPrivate::categoryCount() const
390 {
392 {
391 // No categories defined. return count of longest set.
393 // No categories defined. return count of longest set.
392 int count = 0;
394 int count = 0;
393 for (int i=0; i<m_barSets.count(); i++) {
395 for (int i=0; i<m_barSets.count(); i++) {
394 if (m_barSets.at(i)->count() > count) {
396 if (m_barSets.at(i)->count() > count) {
395 count = m_barSets.at(i)->count();
397 count = m_barSets.at(i)->count();
396 }
398 }
397 }
399 }
398
400
399 return count;
401 return count;
400 }
402 }
401
403
402 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
404 void QAbstractBarSeriesPrivate::setBarWidth(qreal width)
403 {
405 {
404 if (width < 0.0) {
406 if (width < 0.0) {
405 width = 0.0;
407 width = 0.0;
406 }
408 }
407 m_barWidth = width;
409 m_barWidth = width;
408 emit updatedLayout();
410 emit updatedLayout();
409 }
411 }
410
412
411 qreal QAbstractBarSeriesPrivate::barWidth() const
413 qreal QAbstractBarSeriesPrivate::barWidth() const
412 {
414 {
413 return m_barWidth;
415 return m_barWidth;
414 }
416 }
415
417
416 QBarSet* QAbstractBarSeriesPrivate::barsetAt(int index)
418 QBarSet* QAbstractBarSeriesPrivate::barsetAt(int index)
417 {
419 {
418 return m_barSets.at(index);
420 return m_barSets.at(index);
419 }
421 }
420
422
421 void QAbstractBarSeriesPrivate::setVisible(bool visible)
423 void QAbstractBarSeriesPrivate::setVisible(bool visible)
422 {
424 {
423 m_visible = visible;
425 m_visible = visible;
424 emit visibleChanged();
426 emit visibleChanged();
425 }
427 }
426
428
427 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
429 void QAbstractBarSeriesPrivate::setLabelsVisible(bool visible)
428 {
430 {
429 m_labelsVisible = visible;
431 m_labelsVisible = visible;
430 emit labelsVisibleChanged(visible);
432 emit labelsVisibleChanged(visible);
431 }
433 }
432
434
433 qreal QAbstractBarSeriesPrivate::min()
435 qreal QAbstractBarSeriesPrivate::min()
434 {
436 {
435 if (m_barSets.count() <= 0) {
437 if (m_barSets.count() <= 0) {
436 return 0;
438 return 0;
437 }
439 }
438 qreal min = INT_MAX;
440 qreal min = INT_MAX;
439
441
440 for (int i = 0; i < m_barSets.count(); i++) {
442 for (int i = 0; i < m_barSets.count(); i++) {
441 int categoryCount = m_barSets.at(i)->count();
443 int categoryCount = m_barSets.at(i)->count();
442 for (int j = 0; j < categoryCount; j++) {
444 for (int j = 0; j < categoryCount; j++) {
443 qreal temp = m_barSets.at(i)->at(j);
445 qreal temp = m_barSets.at(i)->at(j);
444 if (temp < min)
446 if (temp < min)
445 min = temp;
447 min = temp;
446 }
448 }
447 }
449 }
448 return min;
450 return min;
449 }
451 }
450
452
451 qreal QAbstractBarSeriesPrivate::max()
453 qreal QAbstractBarSeriesPrivate::max()
452 {
454 {
453 if (m_barSets.count() <= 0) {
455 if (m_barSets.count() <= 0) {
454 return 0;
456 return 0;
455 }
457 }
456 qreal max = INT_MIN;
458 qreal max = INT_MIN;
457
459
458 for (int i = 0; i < m_barSets.count(); i++) {
460 for (int i = 0; i < m_barSets.count(); i++) {
459 int categoryCount = m_barSets.at(i)->count();
461 int categoryCount = m_barSets.at(i)->count();
460 for (int j = 0; j < categoryCount; j++) {
462 for (int j = 0; j < categoryCount; j++) {
461 qreal temp = m_barSets.at(i)->at(j);
463 qreal temp = m_barSets.at(i)->at(j);
462 if (temp > max)
464 if (temp > max)
463 max = temp;
465 max = temp;
464 }
466 }
465 }
467 }
466
468
467 return max;
469 return max;
468 }
470 }
469
471
470 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
472 qreal QAbstractBarSeriesPrivate::valueAt(int set, int category)
471 {
473 {
472 if ((set < 0) || (set >= m_barSets.count())) {
474 if ((set < 0) || (set >= m_barSets.count())) {
473 // No set, no value.
475 // No set, no value.
474 return 0;
476 return 0;
475 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
477 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
476 // No category, no value.
478 // No category, no value.
477 return 0;
479 return 0;
478 }
480 }
479
481
480 return m_barSets.at(set)->at(category);
482 return m_barSets.at(set)->at(category);
481 }
483 }
482
484
483 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
485 qreal QAbstractBarSeriesPrivate::percentageAt(int set, int category)
484 {
486 {
485 if ((set < 0) || (set >= m_barSets.count())) {
487 if ((set < 0) || (set >= m_barSets.count())) {
486 // No set, no value.
488 // No set, no value.
487 return 0;
489 return 0;
488 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
490 } else if ((category < 0) || (category >= m_barSets.at(set)->count())) {
489 // No category, no value.
491 // No category, no value.
490 return 0;
492 return 0;
491 }
493 }
492
494
493 qreal value = m_barSets.at(set)->at(category);
495 qreal value = m_barSets.at(set)->at(category);
494 qreal sum = categorySum(category);
496 qreal sum = categorySum(category);
495 if ( qFuzzyIsNull(sum) ) {
497 if ( qFuzzyIsNull(sum) ) {
496 return 0;
498 return 0;
497 }
499 }
498
500
499 return value / sum;
501 return value / sum;
500 }
502 }
501
503
502 qreal QAbstractBarSeriesPrivate::categorySum(int category)
504 qreal QAbstractBarSeriesPrivate::categorySum(int category)
503 {
505 {
504 qreal sum(0);
506 qreal sum(0);
505 int count = m_barSets.count(); // Count sets
507 int count = m_barSets.count(); // Count sets
506 for (int set = 0; set < count; set++) {
508 for (int set = 0; set < count; set++) {
507 if (category < m_barSets.at(set)->count())
509 if (category < m_barSets.at(set)->count())
508 sum += m_barSets.at(set)->at(category);
510 sum += m_barSets.at(set)->at(category);
509 }
511 }
510 return sum;
512 return sum;
511 }
513 }
512
514
513 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
515 qreal QAbstractBarSeriesPrivate::absoluteCategorySum(int category)
514 {
516 {
515 qreal sum(0);
517 qreal sum(0);
516 int count = m_barSets.count(); // Count sets
518 int count = m_barSets.count(); // Count sets
517 for (int set = 0; set < count; set++) {
519 for (int set = 0; set < count; set++) {
518 if (category < m_barSets.at(set)->count())
520 if (category < m_barSets.at(set)->count())
519 sum += qAbs(m_barSets.at(set)->at(category));
521 sum += qAbs(m_barSets.at(set)->at(category));
520 }
522 }
521 return sum;
523 return sum;
522 }
524 }
523
525
524 qreal QAbstractBarSeriesPrivate::maxCategorySum()
526 qreal QAbstractBarSeriesPrivate::maxCategorySum()
525 {
527 {
526 qreal max = INT_MIN;
528 qreal max = INT_MIN;
527 int count = categoryCount();
529 int count = categoryCount();
528 for (int i = 0; i < count; i++) {
530 for (int i = 0; i < count; i++) {
529 qreal sum = categorySum(i);
531 qreal sum = categorySum(i);
530 if (sum > max)
532 if (sum > max)
531 max = sum;
533 max = sum;
532 }
534 }
533 return max;
535 return max;
534 }
536 }
535
537
536 qreal QAbstractBarSeriesPrivate::minX()
538 qreal QAbstractBarSeriesPrivate::minX()
537 {
539 {
538 if (m_barSets.count() <= 0) {
540 if (m_barSets.count() <= 0) {
539 return 0;
541 return 0;
540 }
542 }
541 qreal min = INT_MAX;
543 qreal min = INT_MAX;
542
544
543 for (int i = 0; i < m_barSets.count(); i++) {
545 for (int i = 0; i < m_barSets.count(); i++) {
544 int categoryCount = m_barSets.at(i)->count();
546 int categoryCount = m_barSets.at(i)->count();
545 for (int j = 0; j < categoryCount; j++) {
547 for (int j = 0; j < categoryCount; j++) {
546 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
548 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
547 if (temp < min)
549 if (temp < min)
548 min = temp;
550 min = temp;
549 }
551 }
550 }
552 }
551 return min;
553 return min;
552 }
554 }
553
555
554 qreal QAbstractBarSeriesPrivate::maxX()
556 qreal QAbstractBarSeriesPrivate::maxX()
555 {
557 {
556 if (m_barSets.count() <= 0) {
558 if (m_barSets.count() <= 0) {
557 return 0;
559 return 0;
558 }
560 }
559 qreal max = INT_MIN;
561 qreal max = INT_MIN;
560
562
561 for (int i = 0; i < m_barSets.count(); i++) {
563 for (int i = 0; i < m_barSets.count(); i++) {
562 int categoryCount = m_barSets.at(i)->count();
564 int categoryCount = m_barSets.at(i)->count();
563 for (int j = 0; j < categoryCount; j++) {
565 for (int j = 0; j < categoryCount; j++) {
564 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
566 qreal temp = m_barSets.at(i)->d_ptr.data()->m_values.at(j).x();
565 if (temp > max)
567 if (temp > max)
566 max = temp;
568 max = temp;
567 }
569 }
568 }
570 }
569
571
570 return max;
572 return max;
571 }
573 }
572
574
573 qreal QAbstractBarSeriesPrivate::categoryTop(int category)
575 qreal QAbstractBarSeriesPrivate::categoryTop(int category)
574 {
576 {
575 // Returns top (sum of all positive values) of category.
577 // Returns top (sum of all positive values) of category.
576 // Returns 0, if all values are negative
578 // Returns 0, if all values are negative
577 qreal top(0);
579 qreal top(0);
578 int count = m_barSets.count();
580 int count = m_barSets.count();
579 for (int set = 0; set < count; set++) {
581 for (int set = 0; set < count; set++) {
580 if (category < m_barSets.at(set)->count()) {
582 if (category < m_barSets.at(set)->count()) {
581 qreal temp = m_barSets.at(set)->at(category);
583 qreal temp = m_barSets.at(set)->at(category);
582 if (temp > 0) {
584 if (temp > 0) {
583 top += temp;
585 top += temp;
584 }
586 }
585 }
587 }
586 }
588 }
587 return top;
589 return top;
588 }
590 }
589
591
590 qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
592 qreal QAbstractBarSeriesPrivate::categoryBottom(int category)
591 {
593 {
592 // Returns bottom (sum of all negative values) of category
594 // Returns bottom (sum of all negative values) of category
593 // Returns 0, if all values are positive
595 // Returns 0, if all values are positive
594 qreal bottom(0);
596 qreal bottom(0);
595 int count = m_barSets.count();
597 int count = m_barSets.count();
596 for (int set = 0; set < count; set++) {
598 for (int set = 0; set < count; set++) {
597 if (category < m_barSets.at(set)->count()) {
599 if (category < m_barSets.at(set)->count()) {
598 qreal temp = m_barSets.at(set)->at(category);
600 qreal temp = m_barSets.at(set)->at(category);
599 if (temp < 0) {
601 if (temp < 0) {
600 bottom += temp;
602 bottom += temp;
601 }
603 }
602 }
604 }
603 }
605 }
604 return bottom;
606 return bottom;
605 }
607 }
606
608
607 qreal QAbstractBarSeriesPrivate::top()
609 qreal QAbstractBarSeriesPrivate::top()
608 {
610 {
609 // Returns top of all categories
611 // Returns top of all categories
610 qreal top(0);
612 qreal top(0);
611 int count = categoryCount();
613 int count = categoryCount();
612 for (int i=0; i<count; i++) {
614 for (int i=0; i<count; i++) {
613 qreal temp = categoryTop(i);
615 qreal temp = categoryTop(i);
614 if (temp > top) {
616 if (temp > top) {
615 top = temp;
617 top = temp;
616 }
618 }
617 }
619 }
618 return top;
620 return top;
619 }
621 }
620
622
621 qreal QAbstractBarSeriesPrivate::bottom()
623 qreal QAbstractBarSeriesPrivate::bottom()
622 {
624 {
623 // Returns bottom of all categories
625 // Returns bottom of all categories
624 qreal bottom(0);
626 qreal bottom(0);
625 int count = categoryCount();
627 int count = categoryCount();
626 for (int i=0; i<count; i++) {
628 for (int i=0; i<count; i++) {
627 qreal temp = categoryBottom(i);
629 qreal temp = categoryBottom(i);
628 if (temp < bottom) {
630 if (temp < bottom) {
629 bottom = temp;
631 bottom = temp;
630 }
632 }
631 }
633 }
632 return bottom;
634 return bottom;
633 }
635 }
634
636
635
637
636 void QAbstractBarSeriesPrivate::scaleDomain(Domain& domain)
638 void QAbstractBarSeriesPrivate::scaleDomain(Domain& domain)
637 {
639 {
638 qreal minX(domain.minX());
640 qreal minX(domain.minX());
639 qreal minY(domain.minY());
641 qreal minY(domain.minY());
640 qreal maxX(domain.maxX());
642 qreal maxX(domain.maxX());
641 qreal maxY(domain.maxY());
643 qreal maxY(domain.maxY());
642
644
643 qreal seriesMinX = this->minX();
645 qreal seriesMinX = this->minX();
644 qreal seriesMaxX = this->maxX();
646 qreal seriesMaxX = this->maxX();
645 qreal y = max();
647 qreal y = max();
646 minX = qMin(minX, seriesMinX - (qreal)0.5);
648 minX = qMin(minX, seriesMinX - (qreal)0.5);
647 minY = qMin(minY, y);
649 minY = qMin(minY, y);
648 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
650 maxX = qMax(maxX, seriesMaxX + (qreal)0.5);
649 maxY = qMax(maxY, y);
651 maxY = qMax(maxY, y);
650
652
651 domain.setRange(minX,maxX,minY,maxY);
653 domain.setRange(minX,maxX,minY,maxY);
652 }
654 }
653
655
654 ChartElement* QAbstractBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
656 ChartElement* QAbstractBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
655 {
657 {
656 Q_UNUSED(presenter);
658 Q_UNUSED(presenter);
657 qWarning() << "QAbstractBarSeriesPrivate::createGraphics called";
659 qWarning() << "QAbstractBarSeriesPrivate::createGraphics called";
658 return 0;
660 return 0;
659 }
661 }
660
662
661 QList<LegendMarker*> QAbstractBarSeriesPrivate::createLegendMarker(QLegend* legend)
663 QList<LegendMarker*> QAbstractBarSeriesPrivate::createLegendMarker(QLegend* legend)
662 {
664 {
663 Q_Q(QAbstractBarSeries);
665 Q_Q(QAbstractBarSeries);
664 QList<LegendMarker*> markers;
666 QList<LegendMarker*> markers;
665 foreach(QBarSet* set, q->barSets()) {
667 foreach(QBarSet* set, q->barSets()) {
666 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
668 BarLegendMarker* marker = new BarLegendMarker(q,set,legend);
667 markers << marker;
669 markers << marker;
668 }
670 }
669
671
670 return markers;
672 return markers;
671 }
673 }
672
674
673 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
675 bool QAbstractBarSeriesPrivate::append(QBarSet *set)
674 {
676 {
675 Q_Q(QAbstractBarSeries);
676 if ((m_barSets.contains(set)) || (set == 0)) {
677 if ((m_barSets.contains(set)) || (set == 0)) {
677 // Fail if set is already in list or set is null.
678 // Fail if set is already in list or set is null.
678 return false;
679 return false;
679 }
680 }
680
681
681 m_barSets.append(set);
682 m_barSets.append(set);
682 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
683 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
683 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
684 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
684 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
685 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
685
686
686 emit restructuredBars(); // this notifies barchartitem
687 emit restructuredBars(); // this notifies barchartitem
687 emit legendPropertiesUpdated(q); // this notifies legend
688 return true;
688 return true;
689 }
689 }
690
690
691 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
691 bool QAbstractBarSeriesPrivate::remove(QBarSet *set)
692 {
692 {
693 Q_Q(QAbstractBarSeries);
694 if (!m_barSets.contains(set)) {
693 if (!m_barSets.contains(set)) {
695 // Fail if set is not in list
694 // Fail if set is not in list
696 return false;
695 return false;
697 }
696 }
698
697
699 m_barSets.removeOne(set);
698 m_barSets.removeOne(set);
700 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
699 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
701 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
700 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
702 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
701 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
703
702
704 emit restructuredBars(); // this notifies barchartitem
703 emit restructuredBars(); // this notifies barchartitem
705 emit legendPropertiesUpdated(q);
706 return true;
704 return true;
707 }
705 }
708
706
709 bool QAbstractBarSeriesPrivate::append(QList<QBarSet* > sets)
707 bool QAbstractBarSeriesPrivate::append(QList<QBarSet* > sets)
710 {
708 {
711 Q_Q(QAbstractBarSeries);
712 foreach (QBarSet* set, sets) {
709 foreach (QBarSet* set, sets) {
713 if ((set == 0) || (m_barSets.contains(set))) {
710 if ((set == 0) || (m_barSets.contains(set))) {
714 // Fail if any of the sets is null or is already appended.
711 // Fail if any of the sets is null or is already appended.
715 return false;
712 return false;
716 }
713 }
717 if (sets.count(set) != 1) {
714 if (sets.count(set) != 1) {
718 // Also fail if same set is more than once in given list.
715 // Also fail if same set is more than once in given list.
719 return false;
716 return false;
720 }
717 }
721 }
718 }
722
719
723 foreach (QBarSet* set, sets) {
720 foreach (QBarSet* set, sets) {
724 m_barSets.append(set);
721 m_barSets.append(set);
725 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
722 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
726 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
723 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
727 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
724 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
728 }
725 }
729
726
730 emit restructuredBars(); // this notifies barchartitem
727 emit restructuredBars(); // this notifies barchartitem
731 emit legendPropertiesUpdated(q); // this notifies legend
732 return true;
728 return true;
733 }
729 }
734
730
735 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet* > sets)
731 bool QAbstractBarSeriesPrivate::remove(QList<QBarSet* > sets)
736 {
732 {
737 Q_Q(QAbstractBarSeries);
738 if (sets.count() == 0) {
733 if (sets.count() == 0) {
739 return false;
734 return false;
740 }
735 }
741 foreach (QBarSet* set, sets) {
736 foreach (QBarSet* set, sets) {
742 if ((set == 0) || (!m_barSets.contains(set))) {
737 if ((set == 0) || (!m_barSets.contains(set))) {
743 // Fail if any of the sets is null or is not in series
738 // Fail if any of the sets is null or is not in series
744 return false;
739 return false;
745 }
740 }
746 if (sets.count(set) != 1) {
741 if (sets.count(set) != 1) {
747 // Also fail if same set is more than once in given list.
742 // Also fail if same set is more than once in given list.
748 return false;
743 return false;
749 }
744 }
750 }
745 }
751
746
752 foreach (QBarSet* set, sets) {
747 foreach (QBarSet* set, sets) {
753 m_barSets.removeOne(set);
748 m_barSets.removeOne(set);
754 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
749 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
755 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
750 QObject::disconnect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
756 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
751 QObject::disconnect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
757 }
752 }
758
753
759 emit restructuredBars(); // this notifies barchartitem
754 emit restructuredBars(); // this notifies barchartitem
760 emit legendPropertiesUpdated(q);
761 return true;
755 return true;
762 }
756 }
763
757
764 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
758 bool QAbstractBarSeriesPrivate::insert(int index, QBarSet *set)
765 {
759 {
766 Q_Q(QAbstractBarSeries);
767 if ((m_barSets.contains(set)) || (set == 0)) {
760 if ((m_barSets.contains(set)) || (set == 0)) {
768 // Fail if set is already in list or set is null.
761 // Fail if set is already in list or set is null.
769 return false;
762 return false;
770 }
763 }
771
764
772 m_barSets.insert(index, set);
765 m_barSets.insert(index, set);
773 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
766 QObject::connect(set->d_ptr.data(), SIGNAL(updatedLayout()), this, SIGNAL(updatedLayout()));
774 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
767 QObject::connect(set->d_ptr.data(), SIGNAL(updatedBars()), this, SIGNAL(updatedBars()));
775 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
768 QObject::connect(set->d_ptr.data(), SIGNAL(restructuredBars()), this, SIGNAL(restructuredBars()));
776
769
777 emit restructuredBars(); // this notifies barchartitem
770 emit restructuredBars(); // this notifies barchartitem
778 emit legendPropertiesUpdated(q);
779 return true;
771 return true;
780 }
772 }
781
773
782 void QAbstractBarSeriesPrivate::initializeAxis(QAbstractAxis* axis)
774 void QAbstractBarSeriesPrivate::initializeAxis(QAbstractAxis* axis)
783 {
775 {
784 Q_Q(QAbstractBarSeries);
776 Q_Q(QAbstractBarSeries);
785
777
786 if(axis->type()==QAbstractAxis::AxisTypeBarCategory) {
778 if(axis->type()==QAbstractAxis::AxisTypeBarCategory) {
787
779
788 switch(q->type()) {
780 switch(q->type()) {
789
781
790 case QAbstractSeries::SeriesTypeHorizontalBar:
782 case QAbstractSeries::SeriesTypeHorizontalBar:
791 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
783 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
792 case QAbstractSeries::SeriesTypeHorizontalStackedBar: {
784 case QAbstractSeries::SeriesTypeHorizontalStackedBar: {
793
785
794 if(axis->orientation()==Qt::Vertical)
786 if(axis->orientation()==Qt::Vertical)
795 {
787 {
796 populateCategories(qobject_cast<QBarCategoryAxis*>(axis));
788 populateCategories(qobject_cast<QBarCategoryAxis*>(axis));
797 }
789 }
798 break;
790 break;
799 }
791 }
800 case QAbstractSeries::SeriesTypeBar:
792 case QAbstractSeries::SeriesTypeBar:
801 case QAbstractSeries::SeriesTypePercentBar:
793 case QAbstractSeries::SeriesTypePercentBar:
802 case QAbstractSeries::SeriesTypeStackedBar: {
794 case QAbstractSeries::SeriesTypeStackedBar: {
803
795
804 if(axis->orientation()==Qt::Horizontal)
796 if(axis->orientation()==Qt::Horizontal)
805 {
797 {
806 populateCategories(qobject_cast<QBarCategoryAxis*>(axis));
798 populateCategories(qobject_cast<QBarCategoryAxis*>(axis));
807 }
799 }
808 break;
800 break;
809 }
801 }
810 default:
802 default:
811 qWarning()<<"Unexpected series type";
803 qWarning()<<"Unexpected series type";
812 break;
804 break;
813
805
814 }
806 }
815 }
807 }
816 }
808 }
817
809
818 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
810 QAbstractAxis::AxisType QAbstractBarSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
819 {
811 {
820 Q_Q(const QAbstractBarSeries);
812 Q_Q(const QAbstractBarSeries);
821
813
822 switch(q->type()) {
814 switch(q->type()) {
823
815
824 case QAbstractSeries::SeriesTypeHorizontalBar:
816 case QAbstractSeries::SeriesTypeHorizontalBar:
825 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
817 case QAbstractSeries::SeriesTypeHorizontalPercentBar:
826 case QAbstractSeries::SeriesTypeHorizontalStackedBar: {
818 case QAbstractSeries::SeriesTypeHorizontalStackedBar: {
827
819
828 if(orientation==Qt::Vertical)
820 if(orientation==Qt::Vertical)
829 {
821 {
830 return QAbstractAxis::AxisTypeBarCategory;
822 return QAbstractAxis::AxisTypeBarCategory;
831 }
823 }
832 break;
824 break;
833 }
825 }
834 case QAbstractSeries::SeriesTypeBar:
826 case QAbstractSeries::SeriesTypeBar:
835 case QAbstractSeries::SeriesTypePercentBar:
827 case QAbstractSeries::SeriesTypePercentBar:
836 case QAbstractSeries::SeriesTypeStackedBar: {
828 case QAbstractSeries::SeriesTypeStackedBar: {
837
829
838 if(orientation==Qt::Horizontal)
830 if(orientation==Qt::Horizontal)
839 {
831 {
840 return QAbstractAxis::AxisTypeBarCategory;
832 return QAbstractAxis::AxisTypeBarCategory;
841 }
833 }
842 break;
834 break;
843 }
835 }
844 default:
836 default:
845 qWarning()<<"Unexpected series type";
837 qWarning()<<"Unexpected series type";
846 break;
838 break;
847
839
848 }
840 }
849 return QAbstractAxis::AxisTypeValue;
841 return QAbstractAxis::AxisTypeValue;
850
842
851 }
843 }
852
844
853 void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis* axis)
845 void QAbstractBarSeriesPrivate::populateCategories(QBarCategoryAxis* axis)
854 {
846 {
855 QStringList categories;
847 QStringList categories;
856 if(axis->categories().isEmpty()) {
848 if(axis->categories().isEmpty()) {
857 for (int i(1); i < categoryCount()+1; i++)
849 for (int i(1); i < categoryCount()+1; i++)
858 categories << QString::number(i);
850 categories << QString::number(i);
859 axis->append(categories);
851 axis->append(categories);
860 }
852 }
861 }
853 }
862
854
863 #include "moc_qabstractbarseries.cpp"
855 #include "moc_qabstractbarseries.cpp"
864 #include "moc_qabstractbarseries_p.cpp"
856 #include "moc_qabstractbarseries_p.cpp"
865
857
866
858
867 QTCOMMERCIALCHART_END_NAMESPACE
859 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,124 +1,125
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qbarseries.h"
21 #include "qbarseries.h"
22 #include "qbarseries_p.h"
22 #include "qbarseries_p.h"
23 #include "barchartitem_p.h"
23 #include "barchartitem_p.h"
24 #include "chartdataset_p.h"
24 #include "chartdataset_p.h"
25 #include "charttheme_p.h"
25 #include "charttheme_p.h"
26 #include "baranimation_p.h"
26 #include "baranimation_p.h"
27 #include "qvalueaxis.h"
27 #include "qvalueaxis.h"
28 #include "qbarcategoryaxis.h"
28 #include "qbarcategoryaxis.h"
29
29
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
30 QTCOMMERCIALCHART_BEGIN_NAMESPACE
31
31
32 /*!
32 /*!
33 \class QBarSeries
33 \class QBarSeries
34 \brief Series for creating bar chart
34 \brief Series for creating bar chart
35 \mainclass
35 \mainclass
36
36
37 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
37 QBarSeries represents a series of data shown as bars. The purpose of this class is to draw bars
38 as groups, where bars in same category are grouped next to each other. QBarSeries groups the data
38 as groups, where bars in same category are grouped next to each other. QBarSeries groups the data
39 from sets to categories, which are defined by a QStringList.
39 from sets to categories, which are defined by a QStringList.
40
40
41 See the \l {BarChart Example} {bar chart example} to learn how to create a grouped bar chart.
41 See the \l {BarChart Example} {bar chart example} to learn how to create a grouped bar chart.
42 \image examples_barchart.png
42 \image examples_barchart.png
43
43
44 \sa QBarSet, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries
44 \sa QBarSet, QPercentBarSeries, QAbstractBarSeries, QStackedBarSeries
45 */
45 */
46 /*!
46 /*!
47 \qmlclass BarSeries QBarSeries
47 \qmlclass BarSeries QBarSeries
48 \inherits AbstractBarSeries
48 \inherits AbstractBarSeries
49
49
50 The following QML shows how to create a simple grouped bar chart:
50 The following QML shows how to create a simple grouped bar chart:
51 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
51 \snippet ../demos/qmlchart/qml/qmlchart/View6.qml 1
52 \beginfloatleft
52 \beginfloatleft
53 \image demos_qmlchart6.png
53 \image demos_qmlchart6.png
54 \endfloat
54 \endfloat
55 \clearfloat
55 \clearfloat
56 */
56 */
57
57
58 /*!
58 /*!
59 Constructs empty QBarSeries.
59 Constructs empty QBarSeries.
60 QBarSeries is QObject which is a child of a \a parent.
60 QBarSeries is QObject which is a child of a \a parent.
61 */
61 */
62 QBarSeries::QBarSeries(QObject *parent)
62 QBarSeries::QBarSeries(QObject *parent)
63 : QAbstractBarSeries(*new QBarSeriesPrivate(this), parent)
63 : QAbstractBarSeries(*new QBarSeriesPrivate(this), parent)
64 {
64 {
65
65 }
66 }
66
67
67 /*!
68 /*!
68 Returns QChartSeries::SeriesTypeBar.
69 Returns QChartSeries::SeriesTypeBar.
69 */
70 */
70 QAbstractSeries::SeriesType QBarSeries::type() const
71 QAbstractSeries::SeriesType QBarSeries::type() const
71 {
72 {
72 return QAbstractSeries::SeriesTypeBar;
73 return QAbstractSeries::SeriesTypeBar;
73 }
74 }
74
75
75 /*!
76 /*!
76 Destructor. Removes series from chart.
77 Destructor. Removes series from chart.
77 */
78 */
78 QBarSeries::~QBarSeries()
79 QBarSeries::~QBarSeries()
79 {
80 {
80 Q_D(QBarSeries);
81 Q_D(QBarSeries);
81 if(d->m_dataset) {
82 if(d->m_dataset) {
82 d->m_dataset->removeSeries(this);
83 d->m_dataset->removeSeries(this);
83 }
84 }
84 }
85 }
85 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
86
87
87 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) : QAbstractBarSeriesPrivate(q)
88 QBarSeriesPrivate::QBarSeriesPrivate(QBarSeries *q) : QAbstractBarSeriesPrivate(q)
88 {
89 {
89
90
90 }
91 }
91
92
92 void QBarSeriesPrivate::scaleDomain(Domain& domain)
93 void QBarSeriesPrivate::scaleDomain(Domain& domain)
93 {
94 {
94 qreal minX(domain.minX());
95 qreal minX(domain.minX());
95 qreal minY(domain.minY());
96 qreal minY(domain.minY());
96 qreal maxX(domain.maxX());
97 qreal maxX(domain.maxX());
97 qreal maxY(domain.maxY());
98 qreal maxY(domain.maxY());
98
99
99 qreal x = categoryCount();
100 qreal x = categoryCount();
100 minX = qMin(minX, - (qreal)0.5);
101 minX = qMin(minX, - (qreal)0.5);
101 minY = qMin(minY, min());
102 minY = qMin(minY, min());
102 maxX = qMax(maxX, x - (qreal)0.5);
103 maxX = qMax(maxX, x - (qreal)0.5);
103 maxY = qMax(maxY, max());
104 maxY = qMax(maxY, max());
104
105
105 domain.setRange(minX,maxX,minY,maxY);
106 domain.setRange(minX,maxX,minY,maxY);
106 }
107 }
107
108
108
109
109 ChartElement* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
110 ChartElement* QBarSeriesPrivate::createGraphics(ChartPresenter* presenter)
110 {
111 {
111 Q_Q(QBarSeries);
112 Q_Q(QBarSeries);
112
113
113 BarChartItem* bar = new BarChartItem(q,presenter);
114 BarChartItem* bar = new BarChartItem(q,presenter);
114 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
115 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
115 bar->setAnimation(new BarAnimation(bar));
116 bar->setAnimation(new BarAnimation(bar));
116 }
117 }
117 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
118 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
118 return bar;
119 return bar;
119 }
120 }
120
121
121 #include "moc_qbarseries.cpp"
122 #include "moc_qbarseries.cpp"
122
123
123 QTCOMMERCIALCHART_END_NAMESPACE
124 QTCOMMERCIALCHART_END_NAMESPACE
124
125
@@ -1,388 +1,387
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 "legendlayout_p.h"
21 #include "legendlayout_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "legendmarker_p.h"
23 #include "legendmarker_p.h"
24 #include "qlegend_p.h"
24 #include "qlegend_p.h"
25 #include <QDebug>
25 #include <QDebug>
26
26
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27 QTCOMMERCIALCHART_BEGIN_NAMESPACE
28
28
29 LegendLayout::LegendLayout(QLegend* legend):
29 LegendLayout::LegendLayout(QLegend* legend):
30 m_legend(legend)
30 m_legend(legend)
31 {
31 {
32
32
33 }
33 }
34
34
35 LegendLayout::~LegendLayout()
35 LegendLayout::~LegendLayout()
36 {
36 {
37
37
38 }
38 }
39
39
40 void LegendLayout::setOffset(qreal x, qreal y)
40 void LegendLayout::setOffset(qreal x, qreal y)
41 {
41 {
42 bool scrollHorizontal = true;
42 bool scrollHorizontal = true;
43 switch(m_legend->alignment()) {
43 switch(m_legend->alignment()) {
44 case Qt::AlignTop:
44 case Qt::AlignTop:
45 case Qt::AlignBottom: {
45 case Qt::AlignBottom: {
46 scrollHorizontal = true;
46 scrollHorizontal = true;
47 break;
47 break;
48 }
48 }
49 case Qt::AlignLeft:
49 case Qt::AlignLeft:
50 case Qt::AlignRight: {
50 case Qt::AlignRight: {
51 scrollHorizontal = false;
51 scrollHorizontal = false;
52 break;
52 break;
53 }
53 }
54 }
54 }
55
55
56 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
56 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
57 if (!m_legend->isAttachedToChart()) {
57 if (!m_legend->isAttachedToChart()) {
58 scrollHorizontal = !scrollHorizontal;
58 scrollHorizontal = !scrollHorizontal;
59 }
59 }
60
60
61 QRectF boundingRect = geometry();
61 QRectF boundingRect = geometry();
62 qreal left, top, right, bottom;
62 qreal left, top, right, bottom;
63 getContentsMargins(&left, &top, &right, &bottom);
63 getContentsMargins(&left, &top, &right, &bottom);
64 boundingRect.adjust(left,top,-right,-bottom);
64 boundingRect.adjust(left,top,-right,-bottom);
65
65
66 // Limit offset between m_minOffset and m_maxOffset
66 // Limit offset between m_minOffset and m_maxOffset
67 if (scrollHorizontal) {
67 if (scrollHorizontal) {
68 if(m_width<=boundingRect.width()) return;
68 if(m_width<=boundingRect.width()) return;
69
69
70 if (x != m_offsetX) {
70 if (x != m_offsetX) {
71 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
71 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
72 m_legend->d_ptr->items()->setPos(-m_offsetX,boundingRect.top());
72 m_legend->d_ptr->items()->setPos(-m_offsetX,boundingRect.top());
73 }
73 }
74 }
74 }
75 else {
75 else {
76 if(m_height<=boundingRect.height()) return;
76 if(m_height<=boundingRect.height()) return;
77
77
78 if (y != m_offsetY) {
78 if (y != m_offsetY) {
79 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
79 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
80 m_legend->d_ptr->items()->setPos(boundingRect.left(),-m_offsetY);
80 m_legend->d_ptr->items()->setPos(boundingRect.left(),-m_offsetY);
81 }
81 }
82 }
82 }
83 }
83 }
84
84
85 QPointF LegendLayout::offset() const
85 QPointF LegendLayout::offset() const
86 {
86 {
87 return QPointF(m_offsetX,m_offsetY);
87 return QPointF(m_offsetX,m_offsetY);
88 }
88 }
89
89
90 void LegendLayout::setGeometry(const QRectF& rect)
90 void LegendLayout::setGeometry(const QRectF& rect)
91 {
91 {
92 m_legend->d_ptr->items()->setVisible(m_legend->isVisible());
92 m_legend->d_ptr->items()->setVisible(m_legend->isVisible());
93
93
94 QGraphicsLayout::setGeometry(rect);
94 QGraphicsLayout::setGeometry(rect);
95
95
96 if(m_legend->isAttachedToChart()) {
96 if(m_legend->isAttachedToChart()) {
97 setAttachedGeometry(rect);
97 setAttachedGeometry(rect);
98 } else {
98 } else {
99 setDettachedGeometry(rect);
99 setDettachedGeometry(rect);
100 }
100 }
101
101
102 }
102 }
103
103
104 void LegendLayout::setAttachedGeometry(const QRectF& rect)
104 void LegendLayout::setAttachedGeometry(const QRectF& rect)
105 {
105 {
106 if (!rect.isValid()) return;
106 if (!rect.isValid()) return;
107
108 m_offsetX=0;
107 m_offsetX=0;
109 m_offsetY=0;
108 m_offsetY=0;
110
109
111 QSizeF size(0,0);
110 QSizeF size(0,0);
112
111
113 if( m_legend->d_ptr->markers().isEmpty()) return;
112 if( m_legend->d_ptr->markers().isEmpty()) return;
114
113
115 m_width=0;
114 m_width=0;
116 m_height=0;
115 m_height=0;
117
116
118 qreal left, top, right, bottom;
117 qreal left, top, right, bottom;
119 getContentsMargins(&left, &top, &right, &bottom);
118 getContentsMargins(&left, &top, &right, &bottom);
120
119
121 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
120 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
122
121
123 switch(m_legend->alignment()) {
122 switch(m_legend->alignment()) {
124
123
125 case Qt::AlignTop:
124 case Qt::AlignTop:
126 case Qt::AlignBottom: {
125 case Qt::AlignBottom: {
127 QPointF point(0,0);
126 QPointF point(0,0);
128 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
127 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
129 if (marker->isVisible()) {
128 if (marker->isVisible()) {
130 marker->setGeometry(geometry);
129 marker->setGeometry(geometry);
131 marker->setPos(point.x(),geometry.height()/2 - marker->boundingRect().height()/2);
130 marker->setPos(point.x(),geometry.height()/2 - marker->boundingRect().height()/2);
132 const QRectF& rect = marker->boundingRect();
131 const QRectF& rect = marker->boundingRect();
133 size = size.expandedTo(rect.size());
132 size = size.expandedTo(rect.size());
134 qreal w = rect.width();
133 qreal w = rect.width();
135 m_width+=w;
134 m_width+=w;
136 point.setX(point.x() + w);
135 point.setX(point.x() + w);
137 }
136 }
138 }
137 }
139 if(m_width<geometry.width()) {
138 if(m_width<geometry.width()) {
140 m_legend->d_ptr->items()->setPos(geometry.width()/2-m_width/2,geometry.top());
139 m_legend->d_ptr->items()->setPos(geometry.width()/2-m_width/2,geometry.top());
141
140
142 }
141 }
143 else {
142 else {
144 m_legend->d_ptr->items()->setPos(geometry.topLeft());
143 m_legend->d_ptr->items()->setPos(geometry.topLeft());
145 }
144 }
146 m_height=size.height();
145 m_height=size.height();
147 }
146 }
148 break;
147 break;
149 case Qt::AlignLeft:
148 case Qt::AlignLeft:
150 case Qt::AlignRight: {
149 case Qt::AlignRight: {
151 QPointF point(0,0);
150 QPointF point(0,0);
152 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
151 foreach (LegendMarker* marker, m_legend->d_ptr->markers()) {
153 if (marker->isVisible()) {
152 if (marker->isVisible()) {
154 marker->setGeometry(geometry);
153 marker->setGeometry(geometry);
155 marker->setPos(point);
154 marker->setPos(point);
156 const QRectF& rect = marker->boundingRect();
155 const QRectF& rect = marker->boundingRect();
157 qreal h = rect.height();
156 qreal h = rect.height();
158 size = size.expandedTo(rect.size());
157 size = size.expandedTo(rect.size());
159 m_height+=h;
158 m_height+=h;
160 point.setY(point.y() + h);
159 point.setY(point.y() + h);
161 }
160 }
162 }
161 }
163 if(m_height<geometry.height()) {
162 if(m_height<geometry.height()) {
164 m_legend->d_ptr->items()->setPos(geometry.left(),geometry.height()/2-m_height/2);
163 m_legend->d_ptr->items()->setPos(geometry.left(),geometry.height()/2-m_height/2);
165 }
164 }
166 else {
165 else {
167 m_legend->d_ptr->items()->setPos(geometry.topLeft());
166 m_legend->d_ptr->items()->setPos(geometry.topLeft());
168 }
167 }
169 m_width=size.width();
168 m_width=size.width();
170 }
169 }
171 break;
170 break;
172 }
171 }
173
172
174
173
175 m_minOffsetX = -left;
174 m_minOffsetX = -left;
176 m_minOffsetY = - top;
175 m_minOffsetY = - top;
177 m_maxOffsetX = m_width - geometry.width() - right;
176 m_maxOffsetX = m_width - geometry.width() - right;
178 m_maxOffsetY = m_height - geometry.height() - bottom;
177 m_maxOffsetY = m_height - geometry.height() - bottom;
179 }
178 }
180
179
181 void LegendLayout::setDettachedGeometry(const QRectF& rect)
180 void LegendLayout::setDettachedGeometry(const QRectF& rect)
182 {
181 {
183 if (!rect.isValid()) return;
182 if (!rect.isValid()) return;
184
183
185 // Detached layout is different.
184 // Detached layout is different.
186 // In detached mode legend may have multiple rows and columns, so layout calculations
185 // In detached mode legend may have multiple rows and columns, so layout calculations
187 // differ a log from attached mode.
186 // differ a log from attached mode.
188 // Also the scrolling logic is bit different.
187 // Also the scrolling logic is bit different.
189
188
190 m_offsetX=0;
189 m_offsetX=0;
191 m_offsetY=0;
190 m_offsetY=0;
192
191
193 qreal left, top, right, bottom;
192 qreal left, top, right, bottom;
194 getContentsMargins(&left, &top, &right, &bottom);
193 getContentsMargins(&left, &top, &right, &bottom);
195 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
194 QRectF geometry = rect.adjusted(left,top,-right,-bottom);
196
195
197 QSizeF size(0,0);
196 QSizeF size(0,0);
198
197
199 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
198 QList<LegendMarker *> markers = m_legend->d_ptr->markers();
200
199
201 if(markers.isEmpty()) return;
200 if(markers.isEmpty()) return;
202
201
203 switch (m_legend->alignment()) {
202 switch (m_legend->alignment()) {
204 case Qt::AlignTop: {
203 case Qt::AlignTop: {
205 QPointF point(0,0);
204 QPointF point(0,0);
206 m_width = 0;
205 m_width = 0;
207 m_height = 0;
206 m_height = 0;
208 for (int i=0; i<markers.count(); i++) {
207 for (int i=0; i<markers.count(); i++) {
209 LegendMarker *marker = markers.at(i);
208 LegendMarker *marker = markers.at(i);
210 if (marker->isVisible()) {
209 if (marker->isVisible()) {
211 marker->setGeometry(geometry);
210 marker->setGeometry(geometry);
212 marker->setPos(point.x(),point.y());
211 marker->setPos(point.x(),point.y());
213 const QRectF& boundingRect = marker->boundingRect();
212 const QRectF& boundingRect = marker->boundingRect();
214 qreal w = boundingRect.width();
213 qreal w = boundingRect.width();
215 qreal h = boundingRect.height();
214 qreal h = boundingRect.height();
216 m_width = qMax(m_width,w);
215 m_width = qMax(m_width,w);
217 m_height = qMax(m_height,h);
216 m_height = qMax(m_height,h);
218 point.setX(point.x() + w);
217 point.setX(point.x() + w);
219 if (point.x() + w > geometry.left() + geometry.width() - right) {
218 if (point.x() + w > geometry.left() + geometry.width() - right) {
220 // Next item would go off rect.
219 // Next item would go off rect.
221 point.setX(0);
220 point.setX(0);
222 point.setY(point.y() + h);
221 point.setY(point.y() + h);
223 if (i+1 < markers.count()) {
222 if (i+1 < markers.count()) {
224 m_height += h;
223 m_height += h;
225 }
224 }
226 }
225 }
227 }
226 }
228 }
227 }
229 m_legend->d_ptr->items()->setPos(geometry.topLeft());
228 m_legend->d_ptr->items()->setPos(geometry.topLeft());
230
229
231 m_minOffsetX = -left;
230 m_minOffsetX = -left;
232 m_minOffsetY = -top;
231 m_minOffsetY = -top;
233 m_maxOffsetX = m_width - geometry.width() - right;
232 m_maxOffsetX = m_width - geometry.width() - right;
234 m_maxOffsetY = m_height - geometry.height() - bottom;
233 m_maxOffsetY = m_height - geometry.height() - bottom;
235 }
234 }
236 break;
235 break;
237 case Qt::AlignBottom: {
236 case Qt::AlignBottom: {
238 QPointF point(0,geometry.height());
237 QPointF point(0,geometry.height());
239 m_width = 0;
238 m_width = 0;
240 m_height = 0;
239 m_height = 0;
241 for (int i=0; i<markers.count(); i++) {
240 for (int i=0; i<markers.count(); i++) {
242 LegendMarker *marker = markers.at(i);
241 LegendMarker *marker = markers.at(i);
243 if (marker->isVisible()) {
242 if (marker->isVisible()) {
244 marker->setGeometry(geometry);
243 marker->setGeometry(geometry);
245 const QRectF& boundingRect = marker->boundingRect();
244 const QRectF& boundingRect = marker->boundingRect();
246 qreal w = boundingRect.width();
245 qreal w = boundingRect.width();
247 qreal h = boundingRect.height();
246 qreal h = boundingRect.height();
248 m_width = qMax(m_width,w);
247 m_width = qMax(m_width,w);
249 m_height = qMax(m_height,h);
248 m_height = qMax(m_height,h);
250 marker->setPos(point.x(),point.y() - h);
249 marker->setPos(point.x(),point.y() - h);
251 point.setX(point.x() + w);
250 point.setX(point.x() + w);
252 if (point.x() + w > geometry.left() + geometry.width() - right) {
251 if (point.x() + w > geometry.left() + geometry.width() - right) {
253 // Next item would go off rect.
252 // Next item would go off rect.
254 point.setX(0);
253 point.setX(0);
255 point.setY(point.y() - h);
254 point.setY(point.y() - h);
256 if (i+1 < markers.count()) {
255 if (i+1 < markers.count()) {
257 m_height += h;
256 m_height += h;
258 }
257 }
259 }
258 }
260 }
259 }
261 }
260 }
262 m_legend->d_ptr->items()->setPos(geometry.topLeft());
261 m_legend->d_ptr->items()->setPos(geometry.topLeft());
263
262
264 m_minOffsetX = -left;
263 m_minOffsetX = -left;
265 m_minOffsetY = -m_height + geometry.height() - top;
264 m_minOffsetY = -m_height + geometry.height() - top;
266 m_maxOffsetX = m_width - geometry.width() - right;
265 m_maxOffsetX = m_width - geometry.width() - right;
267 m_maxOffsetY = -bottom;
266 m_maxOffsetY = -bottom;
268 }
267 }
269 break;
268 break;
270 case Qt::AlignLeft: {
269 case Qt::AlignLeft: {
271 QPointF point(0,0);
270 QPointF point(0,0);
272 m_width = 0;
271 m_width = 0;
273 m_height = 0;
272 m_height = 0;
274 qreal maxWidth = 0;
273 qreal maxWidth = 0;
275 for (int i=0; i<markers.count(); i++) {
274 for (int i=0; i<markers.count(); i++) {
276 LegendMarker *marker = markers.at(i);
275 LegendMarker *marker = markers.at(i);
277 if (marker->isVisible()) {
276 if (marker->isVisible()) {
278 marker->setGeometry(geometry);
277 marker->setGeometry(geometry);
279 const QRectF& boundingRect = marker->boundingRect();
278 const QRectF& boundingRect = marker->boundingRect();
280 qreal w = boundingRect.width();
279 qreal w = boundingRect.width();
281 qreal h = boundingRect.height();
280 qreal h = boundingRect.height();
282 m_height = qMax(m_height,h);
281 m_height = qMax(m_height,h);
283 maxWidth = qMax(maxWidth,w);
282 maxWidth = qMax(maxWidth,w);
284 marker->setPos(point.x(),point.y());
283 marker->setPos(point.x(),point.y());
285 point.setY(point.y() + h);
284 point.setY(point.y() + h);
286 if (point.y() + h > geometry.bottom() - bottom) {
285 if (point.y() + h > geometry.bottom() - bottom) {
287 // Next item would go off rect.
286 // Next item would go off rect.
288 point.setX(point.x() + maxWidth);
287 point.setX(point.x() + maxWidth);
289 point.setY(0);
288 point.setY(0);
290 if (i+1 < markers.count()) {
289 if (i+1 < markers.count()) {
291 m_width += maxWidth;
290 m_width += maxWidth;
292 maxWidth = 0;
291 maxWidth = 0;
293 }
292 }
294 }
293 }
295 }
294 }
296 }
295 }
297 m_width += maxWidth;
296 m_width += maxWidth;
298 m_legend->d_ptr->items()->setPos(geometry.topLeft());
297 m_legend->d_ptr->items()->setPos(geometry.topLeft());
299
298
300 m_minOffsetX = -left;
299 m_minOffsetX = -left;
301 m_minOffsetY = -top;
300 m_minOffsetY = -top;
302 m_maxOffsetX = m_width - geometry.width() - right;
301 m_maxOffsetX = m_width - geometry.width() - right;
303 m_maxOffsetY = m_height - geometry.height() - bottom;
302 m_maxOffsetY = m_height - geometry.height() - bottom;
304 }
303 }
305 break;
304 break;
306 case Qt::AlignRight: {
305 case Qt::AlignRight: {
307 QPointF point(geometry.width(),0);
306 QPointF point(geometry.width(),0);
308 m_width = 0;
307 m_width = 0;
309 m_height = 0;
308 m_height = 0;
310 qreal maxWidth = 0;
309 qreal maxWidth = 0;
311 for (int i=0; i<markers.count(); i++) {
310 for (int i=0; i<markers.count(); i++) {
312 LegendMarker *marker = markers.at(i);
311 LegendMarker *marker = markers.at(i);
313 if (marker->isVisible()) {
312 if (marker->isVisible()) {
314 marker->setGeometry(geometry);
313 marker->setGeometry(geometry);
315 const QRectF& boundingRect = marker->boundingRect();
314 const QRectF& boundingRect = marker->boundingRect();
316 qreal w = boundingRect.width();
315 qreal w = boundingRect.width();
317 qreal h = boundingRect.height();
316 qreal h = boundingRect.height();
318 m_height = qMax(m_height,h);
317 m_height = qMax(m_height,h);
319 maxWidth = qMax(maxWidth,w);
318 maxWidth = qMax(maxWidth,w);
320 marker->setPos(point.x() - w,point.y());
319 marker->setPos(point.x() - w,point.y());
321 point.setY(point.y() + h);
320 point.setY(point.y() + h);
322 if (point.y() + h > geometry.bottom()-bottom) {
321 if (point.y() + h > geometry.bottom()-bottom) {
323 // Next item would go off rect.
322 // Next item would go off rect.
324 point.setX(point.x() - maxWidth);
323 point.setX(point.x() - maxWidth);
325 point.setY(0);
324 point.setY(0);
326 if (i+1 < markers.count()) {
325 if (i+1 < markers.count()) {
327 m_width += maxWidth;
326 m_width += maxWidth;
328 maxWidth = 0;
327 maxWidth = 0;
329 }
328 }
330 }
329 }
331 }
330 }
332 }
331 }
333 m_width += maxWidth;
332 m_width += maxWidth;
334 m_legend->d_ptr->items()->setPos(geometry.topLeft());
333 m_legend->d_ptr->items()->setPos(geometry.topLeft());
335
334
336 m_minOffsetX = - m_width + geometry.width() - left;
335 m_minOffsetX = - m_width + geometry.width() - left;
337 m_minOffsetY = -top;
336 m_minOffsetY = -top;
338 m_maxOffsetX = - right;
337 m_maxOffsetX = - right;
339 m_maxOffsetY = m_height - geometry.height() - bottom;
338 m_maxOffsetY = m_height - geometry.height() - bottom;
340 }
339 }
341 break;
340 break;
342 default:
341 default:
343 break;
342 break;
344 }
343 }
345
344
346 }
345 }
347
346
348 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
347 QSizeF LegendLayout::sizeHint ( Qt::SizeHint which, const QSizeF & constraint) const
349 {
348 {
350 QSizeF size(0, 0);
349 QSizeF size(0, 0);
351 qreal left, top, right, bottom;
350 qreal left, top, right, bottom;
352 getContentsMargins(&left, &top, &right, &bottom);
351 getContentsMargins(&left, &top, &right, &bottom);
353
352
354 if(constraint.isValid()) {
353 if(constraint.isValid()) {
355 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
354 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
356 size = size.expandedTo(marker->effectiveSizeHint(which));
355 size = size.expandedTo(marker->effectiveSizeHint(which));
357 }
356 }
358 size = size.boundedTo(constraint);
357 size = size.boundedTo(constraint);
359 }
358 }
360 else if (constraint.width() >= 0) {
359 else if (constraint.width() >= 0) {
361 qreal width = 0;
360 qreal width = 0;
362 qreal height = 0;
361 qreal height = 0;
363 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
362 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
364 width+=marker->effectiveSizeHint(which).width();
363 width+=marker->effectiveSizeHint(which).width();
365 height=qMax(height,marker->effectiveSizeHint(which).height());
364 height=qMax(height,marker->effectiveSizeHint(which).height());
366 }
365 }
367
366
368 size = QSizeF(qMin(constraint.width(),width), height);
367 size = QSizeF(qMin(constraint.width(),width), height);
369 }
368 }
370 else if (constraint.height() >= 0) {
369 else if (constraint.height() >= 0) {
371 qreal width = 0;
370 qreal width = 0;
372 qreal height = 0;
371 qreal height = 0;
373 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
372 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
374 width=qMax(width,marker->effectiveSizeHint(which).width());
373 width=qMax(width,marker->effectiveSizeHint(which).width());
375 height+=height,marker->effectiveSizeHint(which).height();
374 height+=height,marker->effectiveSizeHint(which).height();
376 }
375 }
377 size = QSizeF(width,qMin(constraint.height(),height));
376 size = QSizeF(width,qMin(constraint.height(),height));
378 }
377 }
379 else {
378 else {
380 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
379 foreach(LegendMarker* marker, m_legend->d_ptr->markers()) {
381 size = size.expandedTo(marker->effectiveSizeHint(which));
380 size = size.expandedTo(marker->effectiveSizeHint(which));
382 }
381 }
383 }
382 }
384 size += QSize(left + right, top + bottom);
383 size += QSize(left + right, top + bottom);
385 return size;
384 return size;
386 }
385 }
387
386
388 QTCOMMERCIALCHART_END_NAMESPACE
387 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,253 +1,254
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 "legendmarker_p.h"
21 #include "legendmarker_p.h"
22 #include "qxyseries.h"
22 #include "qxyseries.h"
23 #include "qxyseries_p.h"
23 #include "qxyseries_p.h"
24 #include "qlegend.h"
24 #include "qlegend.h"
25 #include "qabstractbarseries.h"
25 #include "qabstractbarseries.h"
26 #include "qpieseries.h"
26 #include "qpieseries.h"
27 #include "qpieslice.h"
27 #include "qpieslice.h"
28 #include "qbarset.h"
28 #include "qbarset.h"
29 #include "qbarset_p.h"
29 #include "qbarset_p.h"
30 #include "qareaseries.h"
30 #include "qareaseries.h"
31 #include "qareaseries_p.h"
31 #include "qareaseries_p.h"
32 #include <QPainter>
32 #include <QPainter>
33 #include <QGraphicsSceneEvent>
33 #include <QGraphicsSceneEvent>
34 #include <QGraphicsSimpleTextItem>
34 #include <QGraphicsSimpleTextItem>
35 #include <QDebug>
35 #include <QGraphicsLayout>
36
36
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 QTCOMMERCIALCHART_BEGIN_NAMESPACE
38
38
39 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
39 LegendMarker::LegendMarker(QAbstractSeries *series, QLegend *legend) :
40 QGraphicsObject(legend),
40 QGraphicsObject(legend),
41 m_series(series),
41 m_series(series),
42 m_markerRect(0,0,10.0,10.0),
42 m_markerRect(0,0,10.0,10.0),
43 m_boundingRect(0,0,0,0),
43 m_boundingRect(0,0,0,0),
44 m_legend(legend),
44 m_legend(legend),
45 m_textItem(new QGraphicsSimpleTextItem(this)),
45 m_textItem(new QGraphicsSimpleTextItem(this)),
46 m_rectItem(new QGraphicsRectItem(this)),
46 m_rectItem(new QGraphicsRectItem(this)),
47 m_margin(4),
47 m_margin(4),
48 m_space(4)
48 m_space(4)
49 {
49 {
50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
50 //setAcceptedMouseButtons(Qt::LeftButton|Qt::RightButton);
51 m_rectItem->setRect(m_markerRect);
51 m_rectItem->setRect(m_markerRect);
52 }
52 }
53
53
54 void LegendMarker::setPen(const QPen &pen)
54 void LegendMarker::setPen(const QPen &pen)
55 {
55 {
56 m_rectItem->setPen(pen);
56 m_rectItem->setPen(pen);
57 }
57 }
58
58
59 QPen LegendMarker::pen() const
59 QPen LegendMarker::pen() const
60 {
60 {
61 return m_rectItem->pen();
61 return m_rectItem->pen();
62 }
62 }
63
63
64 void LegendMarker::setBrush(const QBrush &brush)
64 void LegendMarker::setBrush(const QBrush &brush)
65 {
65 {
66 m_rectItem->setBrush(brush);
66 m_rectItem->setBrush(brush);
67 }
67 }
68
68
69 QBrush LegendMarker::brush() const
69 QBrush LegendMarker::brush() const
70 {
70 {
71 return m_rectItem->brush();
71 return m_rectItem->brush();
72 }
72 }
73
73
74 void LegendMarker::setFont(const QFont &font)
74 void LegendMarker::setFont(const QFont &font)
75 {
75 {
76 m_textItem->setFont(font);
76 m_textItem->setFont(font);
77 QFontMetrics fn(font);
77 QFontMetrics fn(font);
78 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
78 m_markerRect = QRectF(0,0,fn.height()/2,fn.height()/2);
79 updateGeometry();
79 updateGeometry();
80 }
80 }
81
81
82 QFont LegendMarker::font() const
82 QFont LegendMarker::font() const
83 {
83 {
84 return m_textItem->font();
84 return m_textItem->font();
85 }
85 }
86
86
87 void LegendMarker::setLabel(const QString label)
87 void LegendMarker::setLabel(const QString label)
88 {
88 {
89 m_text = label;
89 m_text = label;
90 updateGeometry();
90 updateGeometry();
91 m_legend->layout()->invalidate();
91 }
92 }
92
93
93 QString LegendMarker::label() const
94 QString LegendMarker::label() const
94 {
95 {
95 return m_text;
96 return m_text;
96 }
97 }
97
98
98 QRectF LegendMarker::boundingRect() const
99 QRectF LegendMarker::boundingRect() const
99 {
100 {
100 return m_boundingRect;
101 return m_boundingRect;
101 }
102 }
102
103
103 void LegendMarker::setLabelBrush(const QBrush &brush)
104 void LegendMarker::setLabelBrush(const QBrush &brush)
104 {
105 {
105 m_textItem->setBrush(brush);
106 m_textItem->setBrush(brush);
106 }
107 }
107
108
108 QBrush LegendMarker::labelBrush() const
109 QBrush LegendMarker::labelBrush() const
109 {
110 {
110 return m_textItem->brush();
111 return m_textItem->brush();
111 }
112 }
112
113
113
114
114 void LegendMarker::setGeometry(const QRectF& rect)
115 void LegendMarker::setGeometry(const QRectF& rect)
115 {
116 {
116 QFontMetrics fn (font());
117 QFontMetrics fn (font());
117
118
118 int width = rect.width();
119 int width = rect.width();
119 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
120 qreal x = m_margin + m_markerRect.width() + m_space + m_margin;
120 qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
121 qreal y = qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin);
121
122
122 if (fn.boundingRect(m_text).width() + x > width)
123 if (fn.boundingRect(m_text).width() + x > width)
123 {
124 {
124 QString string = m_text + "...";
125 QString string = m_text + "...";
125 while(fn.boundingRect(string).width() + x > width && string.length() > 3)
126 while(fn.boundingRect(string).width() + x > width && string.length() > 3)
126 string.remove(string.length() - 4, 1);
127 string.remove(string.length() - 4, 1);
127 m_textItem->setText(string);
128 m_textItem->setText(string);
128 }
129 }
129 else
130 else
130 m_textItem->setText(m_text);
131 m_textItem->setText(m_text);
131
132
132 const QRectF& textRect = m_textItem->boundingRect();
133 const QRectF& textRect = m_textItem->boundingRect();
133
134
134
135
135 m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
136 m_textItem->setPos(x-m_margin,y/2 - textRect.height()/2);
136 m_rectItem->setRect(m_markerRect);
137 m_rectItem->setRect(m_markerRect);
137 m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
138 m_rectItem->setPos(m_margin,y/2 - m_markerRect.height()/2);
138
139
139 prepareGeometryChange();
140 prepareGeometryChange();
140 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
141 m_boundingRect = QRectF(0,0,x+textRect.width()+m_margin,y);
141 }
142 }
142
143
143 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
144 void LegendMarker::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
144 {
145 {
145 Q_UNUSED(option)
146 Q_UNUSED(option)
146 Q_UNUSED(widget)
147 Q_UNUSED(widget)
147 Q_UNUSED(painter)
148 Q_UNUSED(painter)
148 }
149 }
149
150
150 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
151 QSizeF LegendMarker::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
151 {
152 {
152 Q_UNUSED(constraint)
153 Q_UNUSED(constraint)
153
154
154 QFontMetrics fn(m_textItem->font());
155 QFontMetrics fn(m_textItem->font());
155 QSizeF sh;
156 QSizeF sh;
156
157
157 switch (which) {
158 switch (which) {
158 case Qt::MinimumSize:
159 case Qt::MinimumSize:
159 sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
160 sh = QSizeF(fn.boundingRect("...").width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
160 break;
161 break;
161 case Qt::PreferredSize:
162 case Qt::PreferredSize:
162 sh = QSizeF(fn.boundingRect(m_text).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
163 sh = QSizeF(fn.boundingRect(m_text).width() + 2*m_margin + m_space +m_markerRect.width(),qMax(m_markerRect.height()+2*m_margin,fn.height()+2*m_margin));
163 break;
164 break;
164 default:
165 default:
165 break;
166 break;
166 }
167 }
167
168
168 return sh;
169 return sh;
169 }
170 }
170
171
171 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
172 void LegendMarker::mousePressEvent(QGraphicsSceneMouseEvent *event)
172 {
173 {
173 QGraphicsObject::mousePressEvent(event);
174 QGraphicsObject::mousePressEvent(event);
174 //TODO: selected signal removed for now
175 //TODO: selected signal removed for now
175 }
176 }
176
177
177 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
178 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
178
179
179 AreaLegendMarker::AreaLegendMarker(QAreaSeries *series,QLegend *legend) : LegendMarker(series,legend),
180 AreaLegendMarker::AreaLegendMarker(QAreaSeries *series,QLegend *legend) : LegendMarker(series,legend),
180 m_series(series)
181 m_series(series)
181 {
182 {
182 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
183 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
183 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
184 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
184 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
185 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
185 updated();
186 updated();
186 }
187 }
187
188
188 void AreaLegendMarker::updated()
189 void AreaLegendMarker::updated()
189 {
190 {
190 setBrush(m_series->brush());
191 setBrush(m_series->brush());
191 setLabel(m_series->name());
192 setLabel(m_series->name());
192 }
193 }
193
194
194 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
195 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
195
196
196 BarLegendMarker::BarLegendMarker(QAbstractBarSeries *barseries,QBarSet *barset, QLegend *legend) : LegendMarker(barseries,legend),
197 BarLegendMarker::BarLegendMarker(QAbstractBarSeries *barseries,QBarSet *barset, QLegend *legend) : LegendMarker(barseries,legend),
197 m_barset(barset)
198 m_barset(barset)
198 {
199 {
199 //QObject::connect(this, SIGNAL(selected()),barset->d_ptr.data(), SIGNAL(selected()));
200 //QObject::connect(this, SIGNAL(selected()),barset->d_ptr.data(), SIGNAL(selected()));
200 QObject::connect(barset->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(updated()));
201 QObject::connect(barset->d_ptr.data(), SIGNAL(updatedBars()), this, SLOT(updated()));
201 updated();
202 updated();
202 }
203 }
203
204
204 void BarLegendMarker::updated()
205 void BarLegendMarker::updated()
205 {
206 {
206 setBrush(m_barset->brush());
207 setBrush(m_barset->brush());
207 setLabel(m_barset->label());
208 setLabel(m_barset->label());
208 }
209 }
209
210
210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
211 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
211
212
212 PieLegendMarker::PieLegendMarker(QPieSeries* series,QPieSlice *pieslice, QLegend *legend) : LegendMarker(series,legend),
213 PieLegendMarker::PieLegendMarker(QPieSeries* series,QPieSlice *pieslice, QLegend *legend) : LegendMarker(series,legend),
213 m_pieslice(pieslice)
214 m_pieslice(pieslice)
214 {
215 {
215 QObject::connect(pieslice, SIGNAL(labelChanged()), this, SLOT(updated()));
216 QObject::connect(pieslice, SIGNAL(labelChanged()), this, SLOT(updated()));
216 QObject::connect(pieslice, SIGNAL(brushChanged()), this, SLOT(updated()));
217 QObject::connect(pieslice, SIGNAL(brushChanged()), this, SLOT(updated()));
217 updated();
218 updated();
218 }
219 }
219
220
220 void PieLegendMarker::updated()
221 void PieLegendMarker::updated()
221 {
222 {
222 setBrush(m_pieslice->brush());
223 setBrush(m_pieslice->brush());
223 setLabel(m_pieslice->label());
224 setLabel(m_pieslice->label());
224 }
225 }
225
226
226 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
227
228
228 XYLegendMarker::XYLegendMarker(QXYSeries *series, QLegend *legend) : LegendMarker(series,legend),
229 XYLegendMarker::XYLegendMarker(QXYSeries *series, QLegend *legend) : LegendMarker(series,legend),
229 m_series(series)
230 m_series(series)
230 {
231 {
231 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
232 //QObject::connect(this, SIGNAL(selected()), series, SIGNAL(selected()));
232 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
233 QObject::connect(series->d_func(),SIGNAL(updated()), this, SLOT(updated()));
233 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
234 QObject::connect(series, SIGNAL(nameChanged()), this, SLOT(updated()));
234 updated();
235 updated();
235 }
236 }
236
237
237 void XYLegendMarker::updated()
238 void XYLegendMarker::updated()
238 {
239 {
239 setLabel(m_series->name());
240 setLabel(m_series->name());
240
241
241 if(m_series->type()== QAbstractSeries::SeriesTypeScatter)
242 if(m_series->type()== QAbstractSeries::SeriesTypeScatter)
242 {
243 {
243 setBrush(m_series->brush());
244 setBrush(m_series->brush());
244
245
245 }
246 }
246 else {
247 else {
247 setBrush(QBrush(m_series->pen().color()));
248 setBrush(QBrush(m_series->pen().color()));
248 }
249 }
249 }
250 }
250
251
251 #include "moc_legendmarker_p.cpp"
252 #include "moc_legendmarker_p.cpp"
252
253
253 QTCOMMERCIALCHART_END_NAMESPACE
254 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,524 +1,525
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 "qlegend.h"
21 #include "qlegend.h"
22 #include "qlegend_p.h"
22 #include "qlegend_p.h"
23 #include "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26 #include "legendlayout_p.h"
26 #include "legendlayout_p.h"
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "qxyseries.h"
28 #include "qxyseries.h"
29 #include "qlineseries.h"
29 #include "qlineseries.h"
30 #include "qareaseries.h"
30 #include "qareaseries.h"
31 #include "qscatterseries.h"
31 #include "qscatterseries.h"
32 #include "qsplineseries.h"
32 #include "qsplineseries.h"
33 #include "qabstractbarseries.h"
33 #include "qabstractbarseries.h"
34 #include "qstackedbarseries.h"
34 #include "qstackedbarseries.h"
35 #include "qpercentbarseries.h"
35 #include "qpercentbarseries.h"
36 #include "qbarset.h"
36 #include "qbarset.h"
37 #include "qpieseries.h"
37 #include "qpieseries.h"
38 #include "qpieseries_p.h"
38 #include "qpieseries_p.h"
39 #include "qpieslice.h"
39 #include "qpieslice.h"
40 #include "chartpresenter_p.h"
40 #include "chartpresenter_p.h"
41 #include <QPainter>
41 #include <QPainter>
42 #include <QPen>
42 #include <QPen>
43 #include <QTimer>
43 #include <QTimer>
44 #include <QGraphicsLayout>
44 #include <QGraphicsLayout>
45 #include <QGraphicsSceneEvent>
45 #include <QGraphicsSceneEvent>
46
46
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48
48
49 /*!
49 /*!
50 \class QLegend
50 \class QLegend
51 \brief Legend object
51 \brief Legend object
52 \mainclass
52 \mainclass
53
53
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
56 handle the drawing manually.
56 handle the drawing manually.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
58
58
59 \image examples_percentbarchart_legend.png
59 \image examples_percentbarchart_legend.png
60
60
61 \sa QChart
61 \sa QChart
62 */
62 */
63 /*!
63 /*!
64 \qmlclass Legend QLegend
64 \qmlclass Legend QLegend
65 \brief Legend is part of QtCommercial Chart QML API.
65 \brief Legend is part of QtCommercial Chart QML API.
66
66
67 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
67 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
68 series have been changed. Legend is used via ChartView class. For example:
68 series have been changed. Legend is used via ChartView class. For example:
69 \code
69 \code
70 ChartView {
70 ChartView {
71 legend.visible: true
71 legend.visible: true
72 legend.alignment: Qt.AlignBottom
72 legend.alignment: Qt.AlignBottom
73 // Add a few series...
73 // Add a few series...
74 }
74 }
75 \endcode
75 \endcode
76
76
77 \image examples_percentbarchart_legend.png
77 \image examples_percentbarchart_legend.png
78 */
78 */
79
79
80 /*!
80 /*!
81 \property QLegend::alignment
81 \property QLegend::alignment
82 \brief The alignment of the legend.
82 \brief The alignment of the legend.
83
83
84 Legend paints on the defined position in the chart. The following alignments are supported:
84 Legend paints on the defined position in the chart. The following alignments are supported:
85 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
85 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
86 */
86 */
87 /*!
87 /*!
88 \qmlproperty Qt.Alignment Legend::alignment
88 \qmlproperty Qt.Alignment Legend::alignment
89 \brief The alignment of the legend.
89 \brief The alignment of the legend.
90
90
91 Legend paints on the defined position in the chart. The following alignments are supported:
91 Legend paints on the defined position in the chart. The following alignments are supported:
92 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
92 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
93 */
93 */
94
94
95 /*!
95 /*!
96 \property QLegend::backgroundVisible
96 \property QLegend::backgroundVisible
97 Whether the legend background is visible or not.
97 Whether the legend background is visible or not.
98 */
98 */
99 /*!
99 /*!
100 \qmlproperty bool Legend::backgroundVisible
100 \qmlproperty bool Legend::backgroundVisible
101 Whether the legend background is visible or not.
101 Whether the legend background is visible or not.
102 */
102 */
103
103
104 /*!
104 /*!
105 \property QLegend::color
105 \property QLegend::color
106 The color of the legend, i.e. the background (brush) color. Note that if you change the color
106 The color of the legend, i.e. the background (brush) color. Note that if you change the color
107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
108 */
108 */
109 /*!
109 /*!
110 \qmlproperty color Legend::color
110 \qmlproperty color Legend::color
111 The color of the legend, i.e. the background (brush) color.
111 The color of the legend, i.e. the background (brush) color.
112 */
112 */
113
113
114 /*!
114 /*!
115 \property QLegend::borderColor
115 \property QLegend::borderColor
116 The border color of the legend, i.e. the line color.
116 The border color of the legend, i.e. the line color.
117 */
117 */
118 /*!
118 /*!
119 \qmlproperty color Legend::borderColor
119 \qmlproperty color Legend::borderColor
120 The border color of the legend, i.e. the line color.
120 The border color of the legend, i.e. the line color.
121 */
121 */
122
122
123 /*!
123 /*!
124 \property QLegend::font
124 \property QLegend::font
125 The font of markers used by legend
125 The font of markers used by legend
126 */
126 */
127 /*!
127 /*!
128 \qmlproperty color Legend::font
128 \qmlproperty color Legend::font
129 The font of markers used by legend
129 The font of markers used by legend
130 */
130 */
131
131
132 /*!
132 /*!
133 \property QLegend::labelColor
133 \property QLegend::labelColor
134 The color of brush used to draw labels.
134 The color of brush used to draw labels.
135 */
135 */
136 /*!
136 /*!
137 \qmlproperty color QLegend::labelColor
137 \qmlproperty color QLegend::labelColor
138 The color of brush used to draw labels.
138 The color of brush used to draw labels.
139 */
139 */
140
140
141 /*!
141 /*!
142 \fn void QLegend::backgroundVisibleChanged(bool)
142 \fn void QLegend::backgroundVisibleChanged(bool)
143 The visibility of the legend background changed to \a visible.
143 The visibility of the legend background changed to \a visible.
144 */
144 */
145
145
146 /*!
146 /*!
147 \fn void QLegend::colorChanged(QColor)
147 \fn void QLegend::colorChanged(QColor)
148 The color of the legend background changed to \a color.
148 The color of the legend background changed to \a color.
149 */
149 */
150
150
151 /*!
151 /*!
152 \fn void QLegend::borderColorChanged(QColor)
152 \fn void QLegend::borderColorChanged(QColor)
153 The border color of the legend background changed to \a color.
153 The border color of the legend background changed to \a color.
154 */
154 */
155
155
156 /*!
156 /*!
157 \fn void QLegend::fontChanged(QFont)
157 \fn void QLegend::fontChanged(QFont)
158 The font of markers of the legend changed to \a font.
158 The font of markers of the legend changed to \a font.
159 */
159 */
160
160
161 /*!
161 /*!
162 \fn void QLegend::labelColorChanged(QColor color)
162 \fn void QLegend::labelColorChanged(QColor color)
163 This signal is emitted when the color of brush used to draw labels has changed to \a color.
163 This signal is emitted when the color of brush used to draw labels has changed to \a color.
164 */
164 */
165
165
166 /*!
166 /*!
167 Constructs the legend object and sets the parent to \a parent
167 Constructs the legend object and sets the parent to \a parent
168 */
168 */
169
169
170 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
170 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
171 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
171 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
172 {
172 {
173 setZValue(ChartPresenter::LegendZValue);
173 setZValue(ChartPresenter::LegendZValue);
174 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
174 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
175 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
175 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
176 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
176 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
177 // QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
177 // QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
178 setLayout(d_ptr->m_layout);
178 setLayout(d_ptr->m_layout);
179 }
179 }
180
180
181 /*!
181 /*!
182 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
182 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
183 */
183 */
184 QLegend::~QLegend()
184 QLegend::~QLegend()
185 {
185 {
186 }
186 }
187
187
188 /*!
188 /*!
189 \internal
189 \internal
190 */
190 */
191 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
191 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
192 {
192 {
193 Q_UNUSED(option)
193 Q_UNUSED(option)
194 Q_UNUSED(widget)
194 Q_UNUSED(widget)
195
195
196 if(!d_ptr->m_backgroundVisible) return;
196 if(!d_ptr->m_backgroundVisible) return;
197
197
198 painter->setOpacity(opacity());
198 painter->setOpacity(opacity());
199 painter->setPen(d_ptr->m_pen);
199 painter->setPen(d_ptr->m_pen);
200 painter->setBrush(d_ptr->m_brush);
200 painter->setBrush(d_ptr->m_brush);
201 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
201 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
202
202
203 }
203 }
204
204
205
205
206 /*!
206 /*!
207 Sets the \a brush of legend. Brush affects the background of legend.
207 Sets the \a brush of legend. Brush affects the background of legend.
208 */
208 */
209 void QLegend::setBrush(const QBrush &brush)
209 void QLegend::setBrush(const QBrush &brush)
210 {
210 {
211 if (d_ptr->m_brush != brush) {
211 if (d_ptr->m_brush != brush) {
212 d_ptr->m_brush = brush;
212 d_ptr->m_brush = brush;
213 update();
213 update();
214 emit colorChanged(brush.color());
214 emit colorChanged(brush.color());
215 }
215 }
216 }
216 }
217
217
218 /*!
218 /*!
219 Returns the brush used by legend.
219 Returns the brush used by legend.
220 */
220 */
221 QBrush QLegend::brush() const
221 QBrush QLegend::brush() const
222 {
222 {
223 return d_ptr->m_brush;
223 return d_ptr->m_brush;
224 }
224 }
225
225
226 void QLegend::setColor(QColor color)
226 void QLegend::setColor(QColor color)
227 {
227 {
228 QBrush b = d_ptr->m_brush;
228 QBrush b = d_ptr->m_brush;
229 if (b.style() != Qt::SolidPattern || b.color() != color) {
229 if (b.style() != Qt::SolidPattern || b.color() != color) {
230 b.setStyle(Qt::SolidPattern);
230 b.setStyle(Qt::SolidPattern);
231 b.setColor(color);
231 b.setColor(color);
232 setBrush(b);
232 setBrush(b);
233 }
233 }
234 }
234 }
235
235
236 QColor QLegend::color()
236 QColor QLegend::color()
237 {
237 {
238 return d_ptr->m_brush.color();
238 return d_ptr->m_brush.color();
239 }
239 }
240
240
241 /*!
241 /*!
242 Sets the \a pen of legend. Pen affects the legend borders.
242 Sets the \a pen of legend. Pen affects the legend borders.
243 */
243 */
244 void QLegend::setPen(const QPen &pen)
244 void QLegend::setPen(const QPen &pen)
245 {
245 {
246 if (d_ptr->m_pen != pen) {
246 if (d_ptr->m_pen != pen) {
247 d_ptr->m_pen = pen;
247 d_ptr->m_pen = pen;
248 update();
248 update();
249 emit borderColorChanged(pen.color());
249 emit borderColorChanged(pen.color());
250 }
250 }
251 }
251 }
252
252
253 /*!
253 /*!
254 Returns the pen used by legend
254 Returns the pen used by legend
255 */
255 */
256
256
257 QPen QLegend::pen() const
257 QPen QLegend::pen() const
258 {
258 {
259 return d_ptr->m_pen;
259 return d_ptr->m_pen;
260 }
260 }
261
261
262 void QLegend::setFont(const QFont &font)
262 void QLegend::setFont(const QFont &font)
263 {
263 {
264 if (d_ptr->m_font != font) {
264 if (d_ptr->m_font != font) {
265 d_ptr->m_font = font;
265 d_ptr->m_font = font;
266
266
267 foreach (LegendMarker *marker, d_ptr->markers()) {
267 foreach (LegendMarker *marker, d_ptr->markers()) {
268 marker->setFont(d_ptr->m_font);
268 marker->setFont(d_ptr->m_font);
269 }
269 }
270 layout()->invalidate();
270 layout()->invalidate();
271 emit fontChanged(font);
271 emit fontChanged(font);
272 }
272 }
273 }
273 }
274
274
275 QFont QLegend::font() const
275 QFont QLegend::font() const
276 {
276 {
277 return d_ptr->m_font;
277 return d_ptr->m_font;
278 }
278 }
279
279
280 void QLegend::setBorderColor(QColor color)
280 void QLegend::setBorderColor(QColor color)
281 {
281 {
282 QPen p = d_ptr->m_pen;
282 QPen p = d_ptr->m_pen;
283 if (p.color() != color) {
283 if (p.color() != color) {
284 p.setColor(color);
284 p.setColor(color);
285 setPen(p);
285 setPen(p);
286 }
286 }
287 }
287 }
288
288
289 QColor QLegend::borderColor()
289 QColor QLegend::borderColor()
290 {
290 {
291 return d_ptr->m_pen.color();
291 return d_ptr->m_pen.color();
292 }
292 }
293
293
294 /*!
294 /*!
295 Set brush used to draw labels to \a brush.
295 Set brush used to draw labels to \a brush.
296 */
296 */
297 void QLegend::setLabelBrush(const QBrush &brush)
297 void QLegend::setLabelBrush(const QBrush &brush)
298 {
298 {
299 if (d_ptr->m_labelBrush != brush) {
299 if (d_ptr->m_labelBrush != brush) {
300 d_ptr->m_labelBrush = brush;
300 d_ptr->m_labelBrush = brush;
301 foreach (LegendMarker *marker, d_ptr->markers()) {
301 foreach (LegendMarker *marker, d_ptr->markers()) {
302 marker->setLabelBrush(d_ptr->m_labelBrush);
302 marker->setLabelBrush(d_ptr->m_labelBrush);
303 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
303 // Note: The pen of the marker rectangle could be exposed in the public QLegend API
304 // instead of mapping it from label brush color
304 // instead of mapping it from label brush color
305 marker->setPen(brush.color());
305 marker->setPen(brush.color());
306 }
306 }
307 emit labelColorChanged(brush.color());
307 emit labelColorChanged(brush.color());
308 }
308 }
309 }
309 }
310
310
311 /*!
311 /*!
312 Brush used to draw labels.
312 Brush used to draw labels.
313 */
313 */
314 QBrush QLegend::labelBrush() const
314 QBrush QLegend::labelBrush() const
315 {
315 {
316 return d_ptr->m_labelBrush;
316 return d_ptr->m_labelBrush;
317 }
317 }
318
318
319 void QLegend::setLabelColor(QColor color)
319 void QLegend::setLabelColor(QColor color)
320 {
320 {
321 QBrush b = d_ptr->m_labelBrush;
321 QBrush b = d_ptr->m_labelBrush;
322 if (b.style() != Qt::SolidPattern || b.color() != color) {
322 if (b.style() != Qt::SolidPattern || b.color() != color) {
323 b.setStyle(Qt::SolidPattern);
323 b.setStyle(Qt::SolidPattern);
324 b.setColor(color);
324 b.setColor(color);
325 setLabelBrush(b);
325 setLabelBrush(b);
326 }
326 }
327 }
327 }
328
328
329 QColor QLegend::labelColor() const
329 QColor QLegend::labelColor() const
330 {
330 {
331 return d_ptr->m_labelBrush.color();
331 return d_ptr->m_labelBrush.color();
332 }
332 }
333
333
334
334
335 void QLegend::setAlignment(Qt::Alignment alignment)
335 void QLegend::setAlignment(Qt::Alignment alignment)
336 {
336 {
337 if(d_ptr->m_alignment!=alignment) {
337 if(d_ptr->m_alignment!=alignment) {
338 d_ptr->m_alignment = alignment;
338 d_ptr->m_alignment = alignment;
339 if(isAttachedToChart()){
339 if(isAttachedToChart()){
340 d_ptr->m_presenter->layout()->invalidate();
340 d_ptr->m_presenter->layout()->invalidate();
341 }else{
341 }else{
342 layout()->invalidate();
342 layout()->invalidate();
343 }
343 }
344 }
344 }
345 }
345 }
346
346
347 Qt::Alignment QLegend::alignment() const
347 Qt::Alignment QLegend::alignment() const
348 {
348 {
349 return d_ptr->m_alignment;
349 return d_ptr->m_alignment;
350 }
350 }
351
351
352 /*!
352 /*!
353 Detaches the legend from chart. Chart won't change layout of the legend.
353 Detaches the legend from chart. Chart won't change layout of the legend.
354 */
354 */
355 void QLegend::detachFromChart()
355 void QLegend::detachFromChart()
356 {
356 {
357 d_ptr->m_attachedToChart = false;
357 d_ptr->m_attachedToChart = false;
358 d_ptr->m_layout->invalidate();
358 d_ptr->m_layout->invalidate();
359 setParent(0);
359 setParent(0);
360
360
361 }
361 }
362
362
363 /*!
363 /*!
364 Attaches the legend to chart. Chart may change layout of the legend.
364 Attaches the legend to chart. Chart may change layout of the legend.
365 */
365 */
366 void QLegend::attachToChart()
366 void QLegend::attachToChart()
367 {
367 {
368 d_ptr->m_attachedToChart = true;
368 d_ptr->m_attachedToChart = true;
369 d_ptr->m_presenter->layout()->invalidate();
369 d_ptr->m_presenter->layout()->invalidate();
370 setParent(d_ptr->m_chart);
370 setParent(d_ptr->m_chart);
371 }
371 }
372
372
373 /*!
373 /*!
374 Returns true, if legend is attached to chart.
374 Returns true, if legend is attached to chart.
375 */
375 */
376 bool QLegend::isAttachedToChart()
376 bool QLegend::isAttachedToChart()
377 {
377 {
378 return d_ptr->m_attachedToChart;
378 return d_ptr->m_attachedToChart;
379 }
379 }
380
380
381 /*!
381 /*!
382 Sets the visibility of legend background to \a visible
382 Sets the visibility of legend background to \a visible
383 */
383 */
384 void QLegend::setBackgroundVisible(bool visible)
384 void QLegend::setBackgroundVisible(bool visible)
385 {
385 {
386 if(d_ptr->m_backgroundVisible != visible) {
386 if(d_ptr->m_backgroundVisible != visible) {
387 d_ptr->m_backgroundVisible = visible;
387 d_ptr->m_backgroundVisible = visible;
388 update();
388 update();
389 emit backgroundVisibleChanged(visible);
389 emit backgroundVisibleChanged(visible);
390 }
390 }
391 }
391 }
392
392
393 /*!
393 /*!
394 Returns the visibility of legend background
394 Returns the visibility of legend background
395 */
395 */
396 bool QLegend::isBackgroundVisible() const
396 bool QLegend::isBackgroundVisible() const
397 {
397 {
398 return d_ptr->m_backgroundVisible;
398 return d_ptr->m_backgroundVisible;
399 }
399 }
400
400
401 /*!
401 /*!
402 \internal \a event see QGraphicsWidget for details
402 \internal \a event see QGraphicsWidget for details
403 */
403 */
404 void QLegend::hideEvent(QHideEvent *event)
404 void QLegend::hideEvent(QHideEvent *event)
405 {
405 {
406 if(isAttachedToChart()) d_ptr->m_presenter->layout()->invalidate();
406 if(isAttachedToChart()) d_ptr->m_presenter->layout()->invalidate();
407 QGraphicsWidget::hideEvent(event);
407 QGraphicsWidget::hideEvent(event);
408 }
408 }
409
409
410 /*!
410 /*!
411 \internal \a event see QGraphicsWidget for details
411 \internal \a event see QGraphicsWidget for details
412 */
412 */
413 void QLegend::showEvent(QShowEvent *event)
413 void QLegend::showEvent(QShowEvent *event)
414 {
414 {
415 if(isAttachedToChart()) {
415 if(isAttachedToChart()) {
416 d_ptr->m_presenter->layout()->invalidate();
416 d_ptr->m_presenter->layout()->invalidate();
417 d_ptr->items()->setVisible(false);
417 d_ptr->items()->setVisible(false);
418 layout()->invalidate();
418 layout()->invalidate();
419 }
419 }
420 QGraphicsWidget::showEvent(event);
420 QGraphicsWidget::showEvent(event);
421 //layout activation will show the items
421 //layout activation will show the items
422 }
422 }
423
423
424 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
424 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
425
425
426 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
426 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
427 q_ptr(q),
427 q_ptr(q),
428 m_presenter(presenter),
428 m_presenter(presenter),
429 m_layout(new LegendLayout(q)),
429 m_layout(new LegendLayout(q)),
430 m_chart(chart),
430 m_chart(chart),
431 m_items(new QGraphicsItemGroup(q)),
431 m_items(new QGraphicsItemGroup(q)),
432 m_alignment(Qt::AlignTop),
432 m_alignment(Qt::AlignTop),
433 m_brush(QBrush()),
433 m_brush(QBrush()),
434 m_pen(QPen()),
434 m_pen(QPen()),
435 m_labelBrush(QBrush()),
435 m_labelBrush(QBrush()),
436 m_diameter(5),
436 m_diameter(5),
437 m_attachedToChart(true),
437 m_attachedToChart(true),
438 m_backgroundVisible(false)
438 m_backgroundVisible(false)
439 {
439 {
440
440
441 }
441 }
442
442
443 QLegendPrivate::~QLegendPrivate()
443 QLegendPrivate::~QLegendPrivate()
444 {
444 {
445
445
446 }
446 }
447
447
448 void QLegendPrivate::setOffset(qreal x, qreal y)
448 void QLegendPrivate::setOffset(qreal x, qreal y)
449 {
449 {
450 m_layout->setOffset(x,y);
450 m_layout->setOffset(x,y);
451 }
451 }
452
452
453 QPointF QLegendPrivate::offset() const
453 QPointF QLegendPrivate::offset() const
454 {
454 {
455 return m_layout->offset();
455 return m_layout->offset();
456 }
456 }
457
457
458 int QLegendPrivate::roundness(qreal size)
458 int QLegendPrivate::roundness(qreal size)
459 {
459 {
460 return 100*m_diameter/int(size);
460 return 100*m_diameter/int(size);
461 }
461 }
462
462
463 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
463 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
464 {
464 {
465 Q_UNUSED(domain)
465 Q_UNUSED(domain)
466
466
467 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
467 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
468
468
469 foreach (LegendMarker* marker, markers) {
469 foreach (LegendMarker* marker, markers) {
470 marker->setFont(m_font);
470 marker->setFont(m_font);
471 marker->setLabelBrush(m_labelBrush);
471 marker->setLabelBrush(m_labelBrush);
472 marker->setVisible(series->isVisible());
472 marker->setVisible(series->isVisible());
473 m_items->addToGroup(marker);
473 m_items->addToGroup(marker);
474 m_markers<<marker;
474 m_markers<<marker;
475 }
475 }
476
476
477 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
477 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
478 QObject::connect(series->d_ptr.data(), SIGNAL(legendPropertiesUpdated(QAbstractSeries*)), this, SLOT(handleLegendPropertiesUpdated(QAbstractSeries*)));
478 QObject::connect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
479
479
480 m_items->setVisible(false);
480 q_ptr->layout()->invalidate();
481 q_ptr->layout()->invalidate();
481 q_ptr->layout()->activate();
482 m_presenter->layout()->invalidate();
482 }
483 }
483
484
484 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
485 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
485 {
486 {
486 foreach (LegendMarker *marker, m_markers) {
487 foreach (LegendMarker *marker, m_markers) {
487 if (marker->series() == series) {
488 if (marker->series() == series) {
488 delete marker;
489 delete marker;
489 m_markers.removeAll(marker);
490 m_markers.removeAll(marker);
490 }
491 }
491 }
492 }
492
493
493 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
494 QObject::disconnect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
494 QObject::disconnect(series->d_ptr.data(), SIGNAL(legendPropertiesUpdated(QAbstractSeries*)), this, SLOT(handleLegendPropertiesUpdated(QAbstractSeries*)));
495 QObject::disconnect(series->d_ptr.data(), SIGNAL(countChanged()), this, SLOT(handleCountChanged()));
495
496
496 q_ptr->layout()->invalidate();
497 q_ptr->layout()->invalidate();
497 }
498 }
498
499
499 void QLegendPrivate::handleSeriesVisibleChanged()
500 void QLegendPrivate::handleSeriesVisibleChanged()
500 {
501 {
501 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
502 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
503 Q_ASSERT(series);
502
504
503 foreach (LegendMarker* marker, m_markers) {
505 foreach (LegendMarker* marker, m_markers) {
504 if (marker->series() == series) {
506 if (marker->series() == series) {
505 marker->setVisible(series->isVisible());
507 marker->setVisible(series->isVisible());
506 }
508 }
507 }
509 }
508
510
509 q_ptr->layout()->invalidate();
511 q_ptr->layout()->invalidate();
510 }
512 }
511
513
512 void QLegendPrivate::handleLegendPropertiesUpdated(QAbstractSeries *series)
514 void QLegendPrivate::handleCountChanged()
513 {
515 {
514 // Handle new or removed markers
516 QAbstractSeriesPrivate* series = qobject_cast<QAbstractSeriesPrivate *> (sender());
515 // Handle changes of marker pen/brush/label. every property that legend is interested
517 Q_ASSERT(series);
516 handleSeriesRemoved(series);
518 handleSeriesRemoved(series->q_ptr);
517 Domain domain;
519 handleSeriesAdded(series->q_ptr, 0);
518 handleSeriesAdded(series, &domain);
519 }
520 }
520
521
521 #include "moc_qlegend.cpp"
522 #include "moc_qlegend.cpp"
522 #include "moc_qlegend_p.cpp"
523 #include "moc_qlegend_p.cpp"
523
524
524 QTCOMMERCIALCHART_END_NAMESPACE
525 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,87 +1,87
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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QLEGEND_P_H
30 #ifndef QLEGEND_P_H
31 #define QLEGEND_P_H
31 #define QLEGEND_P_H
32
32
33 #include "qlegend.h"
33 #include "qlegend.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 class QChart;
37 class QChart;
38 class ChartPresenter;
38 class ChartPresenter;
39 class QAbstractSeries;
39 class QAbstractSeries;
40 class LegendLayout;
40 class LegendLayout;
41 class LegendMarker;
41 class LegendMarker;
42 class Domain;
42 class Domain;
43
43
44 class QLegendPrivate : public QObject
44 class QLegendPrivate : public QObject
45 {
45 {
46 Q_OBJECT
46 Q_OBJECT
47 public:
47 public:
48 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
48 QLegendPrivate(ChartPresenter *presenter, QChart *chart, QLegend *q);
49 ~QLegendPrivate();
49 ~QLegendPrivate();
50
50
51 void setOffset(qreal x, qreal y);
51 void setOffset(qreal x, qreal y);
52 QPointF offset() const;
52 QPointF offset() const;
53 int roundness(qreal size);
53 int roundness(qreal size);
54
54
55 QList<LegendMarker*> markers() { return m_markers; }
55 QList<LegendMarker*> markers() { return m_markers; }
56 QGraphicsItemGroup* items() { return m_items; }
56 QGraphicsItemGroup* items() { return m_items; }
57
57
58 public Q_SLOTS:
58 public Q_SLOTS:
59 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
59 void handleSeriesAdded(QAbstractSeries *series, Domain *domain);
60 void handleSeriesRemoved(QAbstractSeries *series);
60 void handleSeriesRemoved(QAbstractSeries *series);
61 void handleSeriesVisibleChanged();
61 void handleSeriesVisibleChanged();
62 void handleLegendPropertiesUpdated(QAbstractSeries *series);
62 void handleCountChanged();
63
63
64 private:
64 private:
65 QLegend *q_ptr;
65 QLegend *q_ptr;
66 ChartPresenter *m_presenter;
66 ChartPresenter *m_presenter;
67 LegendLayout *m_layout;
67 LegendLayout *m_layout;
68 QChart* m_chart;
68 QChart* m_chart;
69 QGraphicsItemGroup* m_items;
69 QGraphicsItemGroup* m_items;
70 QList<LegendMarker*> m_markers;
70 QList<LegendMarker*> m_markers;
71 Qt::Alignment m_alignment;
71 Qt::Alignment m_alignment;
72 QBrush m_brush;
72 QBrush m_brush;
73 QPen m_pen;
73 QPen m_pen;
74 QFont m_font;
74 QFont m_font;
75 QBrush m_labelBrush;
75 QBrush m_labelBrush;
76
76
77 qreal m_diameter;
77 qreal m_diameter;
78 bool m_attachedToChart;
78 bool m_attachedToChart;
79 bool m_backgroundVisible;
79 bool m_backgroundVisible;
80
80
81 friend class QLegend;
81 friend class QLegend;
82
82
83 };
83 };
84
84
85 QTCOMMERCIALCHART_END_NAMESPACE
85 QTCOMMERCIALCHART_END_NAMESPACE
86
86
87 #endif
87 #endif
@@ -1,898 +1,879
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qpieseries.h"
21 #include "qpieseries.h"
22 #include "qpieseries_p.h"
22 #include "qpieseries_p.h"
23 #include "qpieslice.h"
23 #include "qpieslice.h"
24 #include "qpieslice_p.h"
24 #include "qpieslice_p.h"
25 #include "pieslicedata_p.h"
25 #include "pieslicedata_p.h"
26 #include "chartdataset_p.h"
26 #include "chartdataset_p.h"
27 #include "charttheme_p.h"
27 #include "charttheme_p.h"
28 #include "legendmarker_p.h"
28 #include "legendmarker_p.h"
29 #include "qabstractaxis.h"
29 #include "qabstractaxis.h"
30 #include "pieanimation_p.h"
30 #include "pieanimation_p.h"
31
31
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
32 QTCOMMERCIALCHART_BEGIN_NAMESPACE
33
33
34 /*!
34 /*!
35 \class QPieSeries
35 \class QPieSeries
36 \brief Pie series API for QtCommercial Charts
36 \brief Pie series API for QtCommercial Charts
37
37
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
38 The pie series defines a pie chart which consists of pie slices which are defined as QPieSlice objects.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
39 The slices can have any values as the QPieSeries will calculate its relative value to the sum of all slices.
40 The actual slice size is determined by that relative value.
40 The actual slice size is determined by that relative value.
41
41
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
42 Pie size and position on the chart is controlled by using relative values which range from 0.0 to 1.0
43 These relate to the actual chart rectangle.
43 These relate to the actual chart rectangle.
44
44
45 By default the pie is defined as a full pie but it can also be a partial pie.
45 By default the pie is defined as a full pie but it can also be a partial pie.
46 This can be done by setting a starting angle and angle span to the series.
46 This can be done by setting a starting angle and angle span to the series.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
47 Full pie is 360 degrees where 0 is at 12 a'clock.
48
48
49 See the \l {PieChart Example} {pie chart example} or \l {DonutChart Example} {donut chart example} to learn how to use QPieSeries.
49 See the \l {PieChart Example} {pie chart example} or \l {DonutChart Example} {donut chart example} to learn how to use QPieSeries.
50 \table 100%
50 \table 100%
51 \row
51 \row
52 \o \image examples_piechart.png
52 \o \image examples_piechart.png
53 \o \image examples_donut.png
53 \o \image examples_donut.png
54 \endtable
54 \endtable
55 */
55 */
56 /*!
56 /*!
57 \qmlclass PieSeries QPieSeries
57 \qmlclass PieSeries QPieSeries
58 \inherits AbstractSeries
58 \inherits AbstractSeries
59
59
60 The following QML shows how to create a simple pie chart.
60 The following QML shows how to create a simple pie chart.
61
61
62 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
62 \snippet ../demos/qmlchart/qml/qmlchart/View1.qml 1
63
63
64 \beginfloatleft
64 \beginfloatleft
65 \image demos_qmlchart1.png
65 \image demos_qmlchart1.png
66 \endfloat
66 \endfloat
67 \clearfloat
67 \clearfloat
68 */
68 */
69
69
70 /*!
70 /*!
71 \property QPieSeries::horizontalPosition
71 \property QPieSeries::horizontalPosition
72 \brief Defines the horizontal position of the pie.
72 \brief Defines the horizontal position of the pie.
73
73
74 The value is a relative value to the chart rectangle where:
74 The value is a relative value to the chart rectangle where:
75
75
76 \list
76 \list
77 \o 0.0 is the absolute left.
77 \o 0.0 is the absolute left.
78 \o 1.0 is the absolute right.
78 \o 1.0 is the absolute right.
79 \endlist
79 \endlist
80 Default value is 0.5 (center).
80 Default value is 0.5 (center).
81 \sa verticalPosition
81 \sa verticalPosition
82 */
82 */
83
83
84 /*!
84 /*!
85 \qmlproperty real PieSeries::horizontalPosition
85 \qmlproperty real PieSeries::horizontalPosition
86
86
87 Defines the horizontal position of the pie.
87 Defines the horizontal position of the pie.
88
88
89 The value is a relative value to the chart rectangle where:
89 The value is a relative value to the chart rectangle where:
90
90
91 \list
91 \list
92 \o 0.0 is the absolute left.
92 \o 0.0 is the absolute left.
93 \o 1.0 is the absolute right.
93 \o 1.0 is the absolute right.
94 \endlist
94 \endlist
95 Default value is 0.5 (center).
95 Default value is 0.5 (center).
96 \sa verticalPosition
96 \sa verticalPosition
97 */
97 */
98
98
99 /*!
99 /*!
100 \property QPieSeries::verticalPosition
100 \property QPieSeries::verticalPosition
101 \brief Defines the vertical position of the pie.
101 \brief Defines the vertical position of the pie.
102
102
103 The value is a relative value to the chart rectangle where:
103 The value is a relative value to the chart rectangle where:
104
104
105 \list
105 \list
106 \o 0.0 is the absolute top.
106 \o 0.0 is the absolute top.
107 \o 1.0 is the absolute bottom.
107 \o 1.0 is the absolute bottom.
108 \endlist
108 \endlist
109 Default value is 0.5 (center).
109 Default value is 0.5 (center).
110 \sa horizontalPosition
110 \sa horizontalPosition
111 */
111 */
112
112
113 /*!
113 /*!
114 \qmlproperty real PieSeries::verticalPosition
114 \qmlproperty real PieSeries::verticalPosition
115
115
116 Defines the vertical position of the pie.
116 Defines the vertical position of the pie.
117
117
118 The value is a relative value to the chart rectangle where:
118 The value is a relative value to the chart rectangle where:
119
119
120 \list
120 \list
121 \o 0.0 is the absolute top.
121 \o 0.0 is the absolute top.
122 \o 1.0 is the absolute bottom.
122 \o 1.0 is the absolute bottom.
123 \endlist
123 \endlist
124 Default value is 0.5 (center).
124 Default value is 0.5 (center).
125 \sa horizontalPosition
125 \sa horizontalPosition
126 */
126 */
127
127
128 /*!
128 /*!
129 \property QPieSeries::size
129 \property QPieSeries::size
130 \brief Defines the pie size.
130 \brief Defines the pie size.
131
131
132 The value is a relative value to the chart rectangle where:
132 The value is a relative value to the chart rectangle where:
133
133
134 \list
134 \list
135 \o 0.0 is the minimum size (pie not drawn).
135 \o 0.0 is the minimum size (pie not drawn).
136 \o 1.0 is the maximum size that can fit the chart.
136 \o 1.0 is the maximum size that can fit the chart.
137 \endlist
137 \endlist
138
138
139 When setting this property the holeSize property is adjusted if necessary, to ensure that the hole size is not greater than the outer size.
139 When setting this property the holeSize property is adjusted if necessary, to ensure that the hole size is not greater than the outer size.
140
140
141 Default value is 0.7.
141 Default value is 0.7.
142 */
142 */
143
143
144 /*!
144 /*!
145 \qmlproperty real PieSeries::size
145 \qmlproperty real PieSeries::size
146
146
147 Defines the pie size.
147 Defines the pie size.
148
148
149 The value is a relative value to the chart rectangle where:
149 The value is a relative value to the chart rectangle where:
150
150
151 \list
151 \list
152 \o 0.0 is the minimum size (pie not drawn).
152 \o 0.0 is the minimum size (pie not drawn).
153 \o 1.0 is the maximum size that can fit the chart.
153 \o 1.0 is the maximum size that can fit the chart.
154 \endlist
154 \endlist
155
155
156 Default value is 0.7.
156 Default value is 0.7.
157 */
157 */
158
158
159 /*!
159 /*!
160 \property QPieSeries::holeSize
160 \property QPieSeries::holeSize
161 \brief Defines the donut hole size.
161 \brief Defines the donut hole size.
162
162
163 The value is a relative value to the chart rectangle where:
163 The value is a relative value to the chart rectangle where:
164
164
165 \list
165 \list
166 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
166 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
167 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
167 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
168 \endlist
168 \endlist
169
169
170 The value is never greater then size property.
170 The value is never greater then size property.
171 Default value is 0.0.
171 Default value is 0.0.
172 */
172 */
173
173
174 /*!
174 /*!
175 \qmlproperty real PieSeries::holeSize
175 \qmlproperty real PieSeries::holeSize
176
176
177 Defines the donut hole size.
177 Defines the donut hole size.
178
178
179 The value is a relative value to the chart rectangle where:
179 The value is a relative value to the chart rectangle where:
180
180
181 \list
181 \list
182 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
182 \o 0.0 is the minimum size (full pie drawn, without any hole inside).
183 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
183 \o 1.0 is the maximum size that can fit the chart. (donut has no width)
184 \endlist
184 \endlist
185
185
186 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
186 When setting this property the size property is adjusted if necessary, to ensure that the inner size is not greater than the outer size.
187
187
188 Default value is 0.0.
188 Default value is 0.0.
189 */
189 */
190
190
191 /*!
191 /*!
192 \property QPieSeries::startAngle
192 \property QPieSeries::startAngle
193 \brief Defines the starting angle of the pie.
193 \brief Defines the starting angle of the pie.
194
194
195 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
195 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
196
196
197 Default is value is 0.
197 Default is value is 0.
198 */
198 */
199
199
200 /*!
200 /*!
201 \qmlproperty real PieSeries::startAngle
201 \qmlproperty real PieSeries::startAngle
202
202
203 Defines the starting angle of the pie.
203 Defines the starting angle of the pie.
204
204
205 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
205 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
206
206
207 Default is value is 0.
207 Default is value is 0.
208 */
208 */
209
209
210 /*!
210 /*!
211 \property QPieSeries::endAngle
211 \property QPieSeries::endAngle
212 \brief Defines the ending angle of the pie.
212 \brief Defines the ending angle of the pie.
213
213
214 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
214 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
215
215
216 Default is value is 360.
216 Default is value is 360.
217 */
217 */
218
218
219 /*!
219 /*!
220 \qmlproperty real PieSeries::endAngle
220 \qmlproperty real PieSeries::endAngle
221
221
222 Defines the ending angle of the pie.
222 Defines the ending angle of the pie.
223
223
224 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
224 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
225
225
226 Default is value is 360.
226 Default is value is 360.
227 */
227 */
228
228
229 /*!
229 /*!
230 \property QPieSeries::count
230 \property QPieSeries::count
231
231
232 Number of slices in the series.
232 Number of slices in the series.
233 */
233 */
234
234
235 /*!
235 /*!
236 \qmlproperty int PieSeries::count
236 \qmlproperty int PieSeries::count
237
237
238 Number of slices in the series.
238 Number of slices in the series.
239 */
239 */
240
240
241 /*!
241 /*!
242 \fn void QPieSeries::countChanged()
242 \fn void QPieSeries::countChanged()
243 Emitted when the slice count has changed.
243 Emitted when the slice count has changed.
244 \sa count
244 \sa count
245 */
245 */
246 /*!
246 /*!
247 \qmlsignal PieSeries::onCountChanged()
247 \qmlsignal PieSeries::onCountChanged()
248 Emitted when the slice count has changed.
248 Emitted when the slice count has changed.
249 */
249 */
250
250
251 /*!
251 /*!
252 \property QPieSeries::sum
252 \property QPieSeries::sum
253
253
254 Sum of all slices.
254 Sum of all slices.
255
255
256 The series keeps track of the sum of all slices it holds.
256 The series keeps track of the sum of all slices it holds.
257 */
257 */
258
258
259 /*!
259 /*!
260 \qmlproperty real PieSeries::sum
260 \qmlproperty real PieSeries::sum
261
261
262 Sum of all slices.
262 Sum of all slices.
263
263
264 The series keeps track of the sum of all slices it holds.
264 The series keeps track of the sum of all slices it holds.
265 */
265 */
266
266
267 /*!
267 /*!
268 \fn void QPieSeries::sumChanged()
268 \fn void QPieSeries::sumChanged()
269 Emitted when the sum of all slices has changed.
269 Emitted when the sum of all slices has changed.
270 \sa sum
270 \sa sum
271 */
271 */
272 /*!
272 /*!
273 \qmlsignal PieSeries::onSumChanged()
273 \qmlsignal PieSeries::onSumChanged()
274 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
274 Emitted when the sum of all slices has changed. This may happen for example if you add or remove slices, or if you
275 change value of a slice.
275 change value of a slice.
276 */
276 */
277
277
278 /*!
278 /*!
279 \fn void QPieSeries::added(QList<QPieSlice*> slices)
279 \fn void QPieSeries::added(QList<QPieSlice*> slices)
280
280
281 This signal is emitted when \a slices have been added to the series.
281 This signal is emitted when \a slices have been added to the series.
282
282
283 \sa append(), insert()
283 \sa append(), insert()
284 */
284 */
285 /*!
285 /*!
286 \qmlsignal PieSeries::onAdded(PieSlice slice)
286 \qmlsignal PieSeries::onAdded(PieSlice slice)
287 Emitted when \a slice has been added to the series.
287 Emitted when \a slice has been added to the series.
288 */
288 */
289
289
290 /*!
290 /*!
291 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
291 \fn void QPieSeries::removed(QList<QPieSlice*> slices)
292 This signal is emitted when \a slices have been removed from the series.
292 This signal is emitted when \a slices have been removed from the series.
293 \sa remove()
293 \sa remove()
294 */
294 */
295 /*!
295 /*!
296 \qmlsignal PieSeries::onRemoved(PieSlice slice)
296 \qmlsignal PieSeries::onRemoved(PieSlice slice)
297 Emitted when \a slice has been removed from the series.
297 Emitted when \a slice has been removed from the series.
298 */
298 */
299
299
300 /*!
300 /*!
301 \fn void QPieSeries::clicked(QPieSlice* slice)
301 \fn void QPieSeries::clicked(QPieSlice* slice)
302 This signal is emitted when a \a slice has been clicked.
302 This signal is emitted when a \a slice has been clicked.
303 \sa QPieSlice::clicked()
303 \sa QPieSlice::clicked()
304 */
304 */
305 /*!
305 /*!
306 \qmlsignal PieSeries::onClicked(PieSlice slice)
306 \qmlsignal PieSeries::onClicked(PieSlice slice)
307 This signal is emitted when a \a slice has been clicked.
307 This signal is emitted when a \a slice has been clicked.
308 */
308 */
309
309
310 /*!
310 /*!
311 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
311 \fn void QPieSeries::hovered(QPieSlice* slice, bool state)
312 This signal is emitted when user has hovered over or away from the \a slice.
312 This signal is emitted when user has hovered over or away from the \a slice.
313 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
313 \a state is true when user has hovered over the slice and false when hover has moved away from the slice.
314 \sa QPieSlice::hovered()
314 \sa QPieSlice::hovered()
315 */
315 */
316 /*!
316 /*!
317 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
317 \qmlsignal PieSeries::onHovered(PieSlice slice, bool state)
318 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
318 This signal is emitted when user has hovered over or away from the \a slice. \a state is true when user has hovered
319 over the slice and false when hover has moved away from the slice.
319 over the slice and false when hover has moved away from the slice.
320 */
320 */
321
321
322 /*!
322 /*!
323 \qmlmethod PieSlice PieSeries::at(int index)
323 \qmlmethod PieSlice PieSeries::at(int index)
324 Returns slice at \a index. Returns null if the index is not valid.
324 Returns slice at \a index. Returns null if the index is not valid.
325 */
325 */
326
326
327 /*!
327 /*!
328 \qmlmethod PieSlice PieSeries::find(string label)
328 \qmlmethod PieSlice PieSeries::find(string label)
329 Returns the first slice with \a label. Returns null if the index is not valid.
329 Returns the first slice with \a label. Returns null if the index is not valid.
330 */
330 */
331
331
332 /*!
332 /*!
333 \qmlmethod PieSlice PieSeries::append(string label, real value)
333 \qmlmethod PieSlice PieSeries::append(string label, real value)
334 Adds a new slice with \a label and \a value to the pie.
334 Adds a new slice with \a label and \a value to the pie.
335 */
335 */
336
336
337 /*!
337 /*!
338 \qmlmethod bool PieSeries::remove(PieSlice slice)
338 \qmlmethod bool PieSeries::remove(PieSlice slice)
339 Removes the \a slice from the pie. Returns true if the removal was successful, false otherwise.
339 Removes the \a slice from the pie. Returns true if the removal was successful, false otherwise.
340 */
340 */
341
341
342 /*!
342 /*!
343 \qmlmethod PieSeries::clear()
343 \qmlmethod PieSeries::clear()
344 Removes all slices from the pie.
344 Removes all slices from the pie.
345 */
345 */
346
346
347 /*!
347 /*!
348 Constructs a series object which is a child of \a parent.
348 Constructs a series object which is a child of \a parent.
349 */
349 */
350 QPieSeries::QPieSeries(QObject *parent) :
350 QPieSeries::QPieSeries(QObject *parent) :
351 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
351 QAbstractSeries(*new QPieSeriesPrivate(this),parent)
352 {
352 {
353
353 Q_D(QPieSeries);
354 QObject::connect(this,SIGNAL(countChanged()),d,SIGNAL(countChanged()));
354 }
355 }
355
356
356 /*!
357 /*!
357 Destroys the series and its slices.
358 Destroys the series and its slices.
358 */
359 */
359 QPieSeries::~QPieSeries()
360 QPieSeries::~QPieSeries()
360 {
361 {
361 // NOTE: d_prt destroyed by QObject
362 // NOTE: d_prt destroyed by QObject
362 }
363 }
363
364
364 /*!
365 /*!
365 Returns QChartSeries::SeriesTypePie.
366 Returns QChartSeries::SeriesTypePie.
366 */
367 */
367 QAbstractSeries::SeriesType QPieSeries::type() const
368 QAbstractSeries::SeriesType QPieSeries::type() const
368 {
369 {
369 return QAbstractSeries::SeriesTypePie;
370 return QAbstractSeries::SeriesTypePie;
370 }
371 }
371
372
372 /*!
373 /*!
373 Appends a single \a slice to the series.
374 Appends a single \a slice to the series.
374 Slice ownership is passed to the series.
375 Slice ownership is passed to the series.
375
376
376 Returns true if append was succesfull.
377 Returns true if append was succesfull.
377 */
378 */
378 bool QPieSeries::append(QPieSlice* slice)
379 bool QPieSeries::append(QPieSlice* slice)
379 {
380 {
380 return append(QList<QPieSlice*>() << slice);
381 return append(QList<QPieSlice*>() << slice);
381 }
382 }
382
383
383 /*!
384 /*!
384 Appends an array of \a slices to the series.
385 Appends an array of \a slices to the series.
385 Slice ownership is passed to the series.
386 Slice ownership is passed to the series.
386
387
387 Returns true if append was successful.
388 Returns true if append was successful.
388 */
389 */
389 bool QPieSeries::append(QList<QPieSlice*> slices)
390 bool QPieSeries::append(QList<QPieSlice*> slices)
390 {
391 {
391 Q_D(QPieSeries);
392 Q_D(QPieSeries);
392
393
393 if (slices.count() == 0)
394 if (slices.count() == 0)
394 return false;
395 return false;
395
396
396 foreach (QPieSlice* s, slices) {
397 foreach (QPieSlice* s, slices) {
397 if (!s || d->m_slices.contains(s))
398 if (!s || d->m_slices.contains(s))
398 return false;
399 return false;
399 if (s->series()) // already added to some series
400 if (s->series()) // already added to some series
400 return false;
401 return false;
401 }
402 }
402
403
403 foreach (QPieSlice* s, slices) {
404 foreach (QPieSlice* s, slices) {
404 s->setParent(this);
405 s->setParent(this);
405 QPieSlicePrivate::fromSlice(s)->m_series = this;
406 QPieSlicePrivate::fromSlice(s)->m_series = this;
406 d->m_slices << s;
407 d->m_slices << s;
407 }
408 }
408
409
409 d->updateDerivativeData();
410 d->updateDerivativeData();
410
411
411 foreach (QPieSlice* s, slices) {
412 foreach (QPieSlice* s, slices) {
412 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
413 connect(s, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
413 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
414 connect(s, SIGNAL(clicked()), d, SLOT(sliceClicked()));
414 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
415 connect(s, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
415
416 connect(s, SIGNAL(labelChanged()), d, SLOT(updateLegendProperties()));
417 connect(s, SIGNAL(penChanged()), d, SLOT(updateLegendProperties()));
418 connect(s, SIGNAL(brushChanged()), d, SLOT(updateLegendProperties()));
419 connect(s, SIGNAL(labelBrushChanged()), d, SLOT(updateLegendProperties()));
420 connect(s, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
421 connect(s, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
422 }
416 }
423
417
424 emit added(slices);
418 emit added(slices);
425 emit countChanged();
419 emit countChanged();
426
420
427 return true;
421 return true;
428 }
422 }
429
423
430 /*!
424 /*!
431 Appends a single \a slice to the series and returns a reference to the series.
425 Appends a single \a slice to the series and returns a reference to the series.
432 Slice ownership is passed to the series.
426 Slice ownership is passed to the series.
433 */
427 */
434 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
428 QPieSeries& QPieSeries::operator << (QPieSlice* slice)
435 {
429 {
436 append(slice);
430 append(slice);
437 return *this;
431 return *this;
438 }
432 }
439
433
440
434
441 /*!
435 /*!
442 Appends a single slice to the series with give \a value and \a label.
436 Appends a single slice to the series with give \a value and \a label.
443 Slice ownership is passed to the series.
437 Slice ownership is passed to the series.
444 */
438 */
445 QPieSlice* QPieSeries::append(QString label, qreal value)
439 QPieSlice* QPieSeries::append(QString label, qreal value)
446 {
440 {
447 QPieSlice* slice = new QPieSlice(label, value);
441 QPieSlice* slice = new QPieSlice(label, value);
448 append(slice);
442 append(slice);
449 return slice;
443 return slice;
450 }
444 }
451
445
452 /*!
446 /*!
453 Inserts a single \a slice to the series before the slice at \a index position.
447 Inserts a single \a slice to the series before the slice at \a index position.
454 Slice ownership is passed to the series.
448 Slice ownership is passed to the series.
455
449
456 Returns true if insert was successful.
450 Returns true if insert was successful.
457 */
451 */
458 bool QPieSeries::insert(int index, QPieSlice* slice)
452 bool QPieSeries::insert(int index, QPieSlice* slice)
459 {
453 {
460 Q_D(QPieSeries);
454 Q_D(QPieSeries);
461
455
462 if (index < 0 || index > d->m_slices.count())
456 if (index < 0 || index > d->m_slices.count())
463 return false;
457 return false;
464
458
465 if (!slice || d->m_slices.contains(slice))
459 if (!slice || d->m_slices.contains(slice))
466 return false;
460 return false;
467
461
468 if (slice->series()) // already added to some series
462 if (slice->series()) // already added to some series
469 return false;
463 return false;
470
464
471 slice->setParent(this);
465 slice->setParent(this);
472 QPieSlicePrivate::fromSlice(slice)->m_series = this;
466 QPieSlicePrivate::fromSlice(slice)->m_series = this;
473 d->m_slices.insert(index, slice);
467 d->m_slices.insert(index, slice);
474
468
475 d->updateDerivativeData();
469 d->updateDerivativeData();
476
470
477 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
471 connect(slice, SIGNAL(valueChanged()), d, SLOT(sliceValueChanged()));
478 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
472 connect(slice, SIGNAL(clicked()), d, SLOT(sliceClicked()));
479 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
473 connect(slice, SIGNAL(hovered(bool)), d, SLOT(sliceHovered(bool)));
480
474
481 connect(slice, SIGNAL(labelChanged()), d, SLOT(updateLegendProperties()));
482 connect(slice, SIGNAL(penChanged()), d, SLOT(updateLegendProperties()));
483 connect(slice, SIGNAL(brushChanged()), d, SLOT(updateLegendProperties()));
484 connect(slice, SIGNAL(labelBrushChanged()), d, SLOT(updateLegendProperties()));
485 connect(slice, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
486 connect(slice, SIGNAL(labelFontChanged()), d, SLOT(updateLegendProperties()));
487
475
488 emit added(QList<QPieSlice*>() << slice);
476 emit added(QList<QPieSlice*>() << slice);
489 emit countChanged();
477 emit countChanged();
490
478
491 return true;
479 return true;
492 }
480 }
493
481
494 /*!
482 /*!
495 Removes a single \a slice from the series and deletes the slice.
483 Removes a single \a slice from the series and deletes the slice.
496
484
497 Do not reference the pointer after this call.
485 Do not reference the pointer after this call.
498
486
499 Returns true if remove was successful.
487 Returns true if remove was successful.
500 */
488 */
501 bool QPieSeries::remove(QPieSlice* slice)
489 bool QPieSeries::remove(QPieSlice* slice)
502 {
490 {
503 Q_D(QPieSeries);
491 Q_D(QPieSeries);
504
492
505 if (!d->m_slices.removeOne(slice))
493 if (!d->m_slices.removeOne(slice))
506 return false;
494 return false;
507
495
508 d->updateDerivativeData();
496 d->updateDerivativeData();
509
497
510 emit removed(QList<QPieSlice*>() << slice);
498 emit removed(QList<QPieSlice*>() << slice);
511 emit countChanged();
499 emit countChanged();
512
500
513 delete slice;
501 delete slice;
514 slice = 0;
502 slice = 0;
515
503
516 return true;
504 return true;
517 }
505 }
518
506
519 /*!
507 /*!
520 Takes a single \a slice from the series. Does not destroy the slice object.
508 Takes a single \a slice from the series. Does not destroy the slice object.
521
509
522 NOTE: The series remains as the slice's parent object. You must set the
510 NOTE: The series remains as the slice's parent object. You must set the
523 parent object to take full ownership.
511 parent object to take full ownership.
524
512
525 Returns true if take was successful.
513 Returns true if take was successful.
526 */
514 */
527 bool QPieSeries::take(QPieSlice* slice)
515 bool QPieSeries::take(QPieSlice* slice)
528 {
516 {
529 Q_D(QPieSeries);
517 Q_D(QPieSeries);
530
518
531 if (!d->m_slices.removeOne(slice))
519 if (!d->m_slices.removeOne(slice))
532 return false;
520 return false;
533
521
534 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
522 QPieSlicePrivate::fromSlice(slice)->m_series = 0;
535 slice->disconnect(d);
523 slice->disconnect(d);
536
524
537 d->updateDerivativeData();
525 d->updateDerivativeData();
538
526
539 emit removed(QList<QPieSlice*>() << slice);
527 emit removed(QList<QPieSlice*>() << slice);
540 emit countChanged();
528 emit countChanged();
541
529
542 return true;
530 return true;
543 }
531 }
544
532
545 /*!
533 /*!
546 Clears all slices from the series.
534 Clears all slices from the series.
547 */
535 */
548 void QPieSeries::clear()
536 void QPieSeries::clear()
549 {
537 {
550 Q_D(QPieSeries);
538 Q_D(QPieSeries);
551 if (d->m_slices.count() == 0)
539 if (d->m_slices.count() == 0)
552 return;
540 return;
553
541
554 QList<QPieSlice*> slices = d->m_slices;
542 QList<QPieSlice*> slices = d->m_slices;
555 foreach (QPieSlice* s, d->m_slices)
543 foreach (QPieSlice* s, d->m_slices)
556 d->m_slices.removeOne(s);
544 d->m_slices.removeOne(s);
557
545
558 d->updateDerivativeData();
546 d->updateDerivativeData();
559
547
560 emit removed(slices);
548 emit removed(slices);
561 emit countChanged();
549 emit countChanged();
562
550
563 foreach (QPieSlice* s, slices)
551 foreach (QPieSlice* s, slices)
564 delete s;
552 delete s;
565 }
553 }
566
554
567 /*!
555 /*!
568 Returns a list of slices that belong to this series.
556 Returns a list of slices that belong to this series.
569 */
557 */
570 QList<QPieSlice*> QPieSeries::slices() const
558 QList<QPieSlice*> QPieSeries::slices() const
571 {
559 {
572 Q_D(const QPieSeries);
560 Q_D(const QPieSeries);
573 return d->m_slices;
561 return d->m_slices;
574 }
562 }
575
563
576 /*!
564 /*!
577 returns the number of the slices in this series.
565 returns the number of the slices in this series.
578 */
566 */
579 int QPieSeries::count() const
567 int QPieSeries::count() const
580 {
568 {
581 Q_D(const QPieSeries);
569 Q_D(const QPieSeries);
582 return d->m_slices.count();
570 return d->m_slices.count();
583 }
571 }
584
572
585 /*!
573 /*!
586 Returns true is the series is empty.
574 Returns true is the series is empty.
587 */
575 */
588 bool QPieSeries::isEmpty() const
576 bool QPieSeries::isEmpty() const
589 {
577 {
590 Q_D(const QPieSeries);
578 Q_D(const QPieSeries);
591 return d->m_slices.isEmpty();
579 return d->m_slices.isEmpty();
592 }
580 }
593
581
594 /*!
582 /*!
595 Returns the sum of all slice values in this series.
583 Returns the sum of all slice values in this series.
596
584
597 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
585 \sa QPieSlice::value(), QPieSlice::setValue(), QPieSlice::percentage()
598 */
586 */
599 qreal QPieSeries::sum() const
587 qreal QPieSeries::sum() const
600 {
588 {
601 Q_D(const QPieSeries);
589 Q_D(const QPieSeries);
602 return d->m_sum;
590 return d->m_sum;
603 }
591 }
604
592
605 void QPieSeries::setHoleSize(qreal holeSize)
593 void QPieSeries::setHoleSize(qreal holeSize)
606 {
594 {
607 Q_D(QPieSeries);
595 Q_D(QPieSeries);
608 holeSize = qBound((qreal)0.0, holeSize, (qreal)1.0);
596 holeSize = qBound((qreal)0.0, holeSize, (qreal)1.0);
609 d->setSizes(holeSize, qMax(d->m_pieRelativeSize, holeSize));
597 d->setSizes(holeSize, qMax(d->m_pieRelativeSize, holeSize));
610 }
598 }
611
599
612 qreal QPieSeries::holeSize() const
600 qreal QPieSeries::holeSize() const
613 {
601 {
614 Q_D(const QPieSeries);
602 Q_D(const QPieSeries);
615 return d->m_holeRelativeSize;
603 return d->m_holeRelativeSize;
616 }
604 }
617
605
618 void QPieSeries::setHorizontalPosition(qreal relativePosition)
606 void QPieSeries::setHorizontalPosition(qreal relativePosition)
619 {
607 {
620 Q_D(QPieSeries);
608 Q_D(QPieSeries);
621
609
622 if (relativePosition < 0.0)
610 if (relativePosition < 0.0)
623 relativePosition = 0.0;
611 relativePosition = 0.0;
624 if (relativePosition > 1.0)
612 if (relativePosition > 1.0)
625 relativePosition = 1.0;
613 relativePosition = 1.0;
626
614
627 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
615 if (!qFuzzyIsNull(d->m_pieRelativeHorPos - relativePosition)) {
628 d->m_pieRelativeHorPos = relativePosition;
616 d->m_pieRelativeHorPos = relativePosition;
629 emit d->horizontalPositionChanged();
617 emit d->horizontalPositionChanged();
630 }
618 }
631 }
619 }
632
620
633 qreal QPieSeries::horizontalPosition() const
621 qreal QPieSeries::horizontalPosition() const
634 {
622 {
635 Q_D(const QPieSeries);
623 Q_D(const QPieSeries);
636 return d->m_pieRelativeHorPos;
624 return d->m_pieRelativeHorPos;
637 }
625 }
638
626
639 void QPieSeries::setVerticalPosition(qreal relativePosition)
627 void QPieSeries::setVerticalPosition(qreal relativePosition)
640 {
628 {
641 Q_D(QPieSeries);
629 Q_D(QPieSeries);
642
630
643 if (relativePosition < 0.0)
631 if (relativePosition < 0.0)
644 relativePosition = 0.0;
632 relativePosition = 0.0;
645 if (relativePosition > 1.0)
633 if (relativePosition > 1.0)
646 relativePosition = 1.0;
634 relativePosition = 1.0;
647
635
648 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
636 if (!qFuzzyIsNull(d->m_pieRelativeVerPos - relativePosition)) {
649 d->m_pieRelativeVerPos = relativePosition;
637 d->m_pieRelativeVerPos = relativePosition;
650 emit d->verticalPositionChanged();
638 emit d->verticalPositionChanged();
651 }
639 }
652 }
640 }
653
641
654 qreal QPieSeries::verticalPosition() const
642 qreal QPieSeries::verticalPosition() const
655 {
643 {
656 Q_D(const QPieSeries);
644 Q_D(const QPieSeries);
657 return d->m_pieRelativeVerPos;
645 return d->m_pieRelativeVerPos;
658 }
646 }
659
647
660 void QPieSeries::setPieSize(qreal relativeSize)
648 void QPieSeries::setPieSize(qreal relativeSize)
661 {
649 {
662 Q_D(QPieSeries);
650 Q_D(QPieSeries);
663 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
651 relativeSize = qBound((qreal)0.0, relativeSize, (qreal)1.0);
664 d->setSizes(qMin(d->m_holeRelativeSize, relativeSize), relativeSize);
652 d->setSizes(qMin(d->m_holeRelativeSize, relativeSize), relativeSize);
665
653
666 }
654 }
667
655
668 qreal QPieSeries::pieSize() const
656 qreal QPieSeries::pieSize() const
669 {
657 {
670 Q_D(const QPieSeries);
658 Q_D(const QPieSeries);
671 return d->m_pieRelativeSize;
659 return d->m_pieRelativeSize;
672 }
660 }
673
661
674
662
675 void QPieSeries::setPieStartAngle(qreal angle)
663 void QPieSeries::setPieStartAngle(qreal angle)
676 {
664 {
677 Q_D(QPieSeries);
665 Q_D(QPieSeries);
678 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
666 if (qFuzzyIsNull(d->m_pieStartAngle - angle))
679 return;
667 return;
680 d->m_pieStartAngle = angle;
668 d->m_pieStartAngle = angle;
681 d->updateDerivativeData();
669 d->updateDerivativeData();
682 emit d->pieStartAngleChanged();
670 emit d->pieStartAngleChanged();
683 }
671 }
684
672
685 qreal QPieSeries::pieStartAngle() const
673 qreal QPieSeries::pieStartAngle() const
686 {
674 {
687 Q_D(const QPieSeries);
675 Q_D(const QPieSeries);
688 return d->m_pieStartAngle;
676 return d->m_pieStartAngle;
689 }
677 }
690
678
691 /*!
679 /*!
692 Sets the end angle of the pie.
680 Sets the end angle of the pie.
693
681
694 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
682 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
695
683
696 \a angle must be greater than start angle.
684 \a angle must be greater than start angle.
697
685
698 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
686 \sa pieEndAngle(), pieStartAngle(), setPieStartAngle()
699 */
687 */
700 void QPieSeries::setPieEndAngle(qreal angle)
688 void QPieSeries::setPieEndAngle(qreal angle)
701 {
689 {
702 Q_D(QPieSeries);
690 Q_D(QPieSeries);
703 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
691 if (qFuzzyIsNull(d->m_pieEndAngle - angle))
704 return;
692 return;
705 d->m_pieEndAngle = angle;
693 d->m_pieEndAngle = angle;
706 d->updateDerivativeData();
694 d->updateDerivativeData();
707 emit d->pieEndAngleChanged();
695 emit d->pieEndAngleChanged();
708 }
696 }
709
697
710 /*!
698 /*!
711 Returns the end angle of the pie.
699 Returns the end angle of the pie.
712
700
713 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
701 Full pie is 360 degrees where 0 degrees is at 12 a'clock.
714
702
715 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
703 \sa setPieEndAngle(), pieStartAngle(), setPieStartAngle()
716 */
704 */
717 qreal QPieSeries::pieEndAngle() const
705 qreal QPieSeries::pieEndAngle() const
718 {
706 {
719 Q_D(const QPieSeries);
707 Q_D(const QPieSeries);
720 return d->m_pieEndAngle;
708 return d->m_pieEndAngle;
721 }
709 }
722
710
723 /*!
711 /*!
724 Sets the all the slice labels \a visible or invisible.
712 Sets the all the slice labels \a visible or invisible.
725
713
726 Note that this affects only the current slices in the series.
714 Note that this affects only the current slices in the series.
727 If user adds a new slice the default label visibility is false.
715 If user adds a new slice the default label visibility is false.
728
716
729 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
717 \sa QPieSlice::isLabelVisible(), QPieSlice::setLabelVisible()
730 */
718 */
731 void QPieSeries::setLabelsVisible(bool visible)
719 void QPieSeries::setLabelsVisible(bool visible)
732 {
720 {
733 Q_D(QPieSeries);
721 Q_D(QPieSeries);
734 foreach (QPieSlice* s, d->m_slices)
722 foreach (QPieSlice* s, d->m_slices)
735 s->setLabelVisible(visible);
723 s->setLabelVisible(visible);
736 }
724 }
737
725
738 /*!
726 /*!
739 Sets the all the slice labels \a position
727 Sets the all the slice labels \a position
740
728
741 Note that this affects only the current slices in the series.
729 Note that this affects only the current slices in the series.
742 If user adds a new slice the default label position is LabelOutside
730 If user adds a new slice the default label position is LabelOutside
743
731
744 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
732 \sa QPieSlice::labelPosition(), QPieSlice::setLabelPosition()
745 */
733 */
746 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
734 void QPieSeries::setLabelsPosition(QPieSlice::LabelPosition position)
747 {
735 {
748 Q_D(QPieSeries);
736 Q_D(QPieSeries);
749 foreach (QPieSlice* s, d->m_slices)
737 foreach (QPieSlice* s, d->m_slices)
750 s->setLabelPosition(position);
738 s->setLabelPosition(position);
751 }
739 }
752
740
753 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
741 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
754
742
755
743
756 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
744 QPieSeriesPrivate::QPieSeriesPrivate(QPieSeries *parent) :
757 QAbstractSeriesPrivate(parent),
745 QAbstractSeriesPrivate(parent),
758 m_pieRelativeHorPos(0.5),
746 m_pieRelativeHorPos(0.5),
759 m_pieRelativeVerPos(0.5),
747 m_pieRelativeVerPos(0.5),
760 m_pieRelativeSize(0.7),
748 m_pieRelativeSize(0.7),
761 m_pieStartAngle(0),
749 m_pieStartAngle(0),
762 m_pieEndAngle(360),
750 m_pieEndAngle(360),
763 m_sum(0),
751 m_sum(0),
764 m_holeRelativeSize(0.0)
752 m_holeRelativeSize(0.0)
765 {
753 {
766 }
754 }
767
755
768 QPieSeriesPrivate::~QPieSeriesPrivate()
756 QPieSeriesPrivate::~QPieSeriesPrivate()
769 {
757 {
770 }
758 }
771
759
772 void QPieSeriesPrivate::updateDerivativeData()
760 void QPieSeriesPrivate::updateDerivativeData()
773 {
761 {
774 // calculate sum of all slices
762 // calculate sum of all slices
775 qreal sum = 0;
763 qreal sum = 0;
776 foreach (QPieSlice* s, m_slices)
764 foreach (QPieSlice* s, m_slices)
777 sum += s->value();
765 sum += s->value();
778
766
779 if (!qFuzzyIsNull(m_sum - sum)) {
767 if (!qFuzzyIsNull(m_sum - sum)) {
780 m_sum = sum;
768 m_sum = sum;
781 emit q_func()->sumChanged();
769 emit q_func()->sumChanged();
782 }
770 }
783
771
784 // nothing to show..
772 // nothing to show..
785 if (qFuzzyIsNull(m_sum))
773 if (qFuzzyIsNull(m_sum))
786 return;
774 return;
787
775
788 // update slice attributes
776 // update slice attributes
789 qreal sliceAngle = m_pieStartAngle;
777 qreal sliceAngle = m_pieStartAngle;
790 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
778 qreal pieSpan = m_pieEndAngle - m_pieStartAngle;
791 QVector<QPieSlice*> changed;
779 QVector<QPieSlice*> changed;
792 foreach (QPieSlice* s, m_slices) {
780 foreach (QPieSlice* s, m_slices) {
793 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
781 QPieSlicePrivate *d = QPieSlicePrivate::fromSlice(s);
794 d->setPercentage(s->value() / m_sum);
782 d->setPercentage(s->value() / m_sum);
795 d->setStartAngle(sliceAngle);
783 d->setStartAngle(sliceAngle);
796 d->setAngleSpan(pieSpan * s->percentage());
784 d->setAngleSpan(pieSpan * s->percentage());
797 sliceAngle += s->angleSpan();
785 sliceAngle += s->angleSpan();
798 }
786 }
799
787
800
788
801 emit calculatedDataChanged();
789 emit calculatedDataChanged();
802 }
790 }
803
791
804 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
792 void QPieSeriesPrivate::setSizes(qreal innerSize, qreal outerSize)
805 {
793 {
806 bool changed = false;
794 bool changed = false;
807
795
808 if (!qFuzzyIsNull(m_holeRelativeSize - innerSize)) {
796 if (!qFuzzyIsNull(m_holeRelativeSize - innerSize)) {
809 m_holeRelativeSize = innerSize;
797 m_holeRelativeSize = innerSize;
810 changed = true;
798 changed = true;
811 }
799 }
812
800
813 if (!qFuzzyIsNull(m_pieRelativeSize - outerSize)) {
801 if (!qFuzzyIsNull(m_pieRelativeSize - outerSize)) {
814 m_pieRelativeSize = outerSize;
802 m_pieRelativeSize = outerSize;
815 changed = true;
803 changed = true;
816 }
804 }
817
805
818 if (changed)
806 if (changed)
819 emit pieSizeChanged();
807 emit pieSizeChanged();
820 }
808 }
821
809
822 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
810 QPieSeriesPrivate* QPieSeriesPrivate::fromSeries(QPieSeries *series)
823 {
811 {
824 return series->d_func();
812 return series->d_func();
825 }
813 }
826
814
827 void QPieSeriesPrivate::sliceValueChanged()
815 void QPieSeriesPrivate::sliceValueChanged()
828 {
816 {
829 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
817 Q_ASSERT(m_slices.contains(qobject_cast<QPieSlice *>(sender())));
830 updateDerivativeData();
818 updateDerivativeData();
831 }
819 }
832
820
833 void QPieSeriesPrivate::sliceClicked()
821 void QPieSeriesPrivate::sliceClicked()
834 {
822 {
835 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
823 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
836 Q_ASSERT(m_slices.contains(slice));
824 Q_ASSERT(m_slices.contains(slice));
837 Q_Q(QPieSeries);
825 Q_Q(QPieSeries);
838 emit q->clicked(slice);
826 emit q->clicked(slice);
839 }
827 }
840
828
841 void QPieSeriesPrivate::sliceHovered(bool state)
829 void QPieSeriesPrivate::sliceHovered(bool state)
842 {
830 {
843 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
831 QPieSlice* slice = qobject_cast<QPieSlice *>(sender());
844 Q_ASSERT(m_slices.contains(slice));
832 Q_ASSERT(m_slices.contains(slice));
845 Q_Q(QPieSeries);
833 Q_Q(QPieSeries);
846 emit q->hovered(slice, state);
834 emit q->hovered(slice, state);
847 }
835 }
848
836
849 void QPieSeriesPrivate::updateLegendProperties()
850 {
851 // This slot listens to all properties of slices, which may interest legend and signals it.
852 Q_Q(QPieSeries);
853 emit legendPropertiesUpdated(q);
854 }
855
856 void QPieSeriesPrivate::scaleDomain(Domain& domain)
837 void QPieSeriesPrivate::scaleDomain(Domain& domain)
857 {
838 {
858 Q_UNUSED(domain);
839 Q_UNUSED(domain);
859 // does not apply to pie
840 // does not apply to pie
860 }
841 }
861
842
862 ChartElement* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
843 ChartElement* QPieSeriesPrivate::createGraphics(ChartPresenter* presenter)
863 {
844 {
864 Q_Q(QPieSeries);
845 Q_Q(QPieSeries);
865 PieChartItem* pie = new PieChartItem(q,presenter);
846 PieChartItem* pie = new PieChartItem(q,presenter);
866 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
847 if(presenter->animationOptions().testFlag(QChart::SeriesAnimations)) {
867 pie->setAnimation(new PieAnimation(pie));
848 pie->setAnimation(new PieAnimation(pie));
868 }
849 }
869 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
850 presenter->chartTheme()->decorate(q, presenter->dataSet()->seriesIndex(q));
870 return pie;
851 return pie;
871 }
852 }
872
853
873 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
854 QList<LegendMarker*> QPieSeriesPrivate::createLegendMarker(QLegend* legend)
874 {
855 {
875 Q_Q(QPieSeries);
856 Q_Q(QPieSeries);
876 QList<LegendMarker*> markers;
857 QList<LegendMarker*> markers;
877 foreach(QPieSlice* slice, q->slices()) {
858 foreach(QPieSlice* slice, q->slices()) {
878 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
859 PieLegendMarker* marker = new PieLegendMarker(q,slice,legend);
879 markers << marker;
860 markers << marker;
880 }
861 }
881 return markers;
862 return markers;
882 }
863 }
883
864
884 void QPieSeriesPrivate::initializeAxis(QAbstractAxis* axis)
865 void QPieSeriesPrivate::initializeAxis(QAbstractAxis* axis)
885 {
866 {
886 Q_UNUSED(axis);
867 Q_UNUSED(axis);
887 }
868 }
888
869
889 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
870 QAbstractAxis::AxisType QPieSeriesPrivate::defaultAxisType(Qt::Orientation orientation) const
890 {
871 {
891 Q_UNUSED(orientation);
872 Q_UNUSED(orientation);
892 return QAbstractAxis::AxisTypeNoAxis;
873 return QAbstractAxis::AxisTypeNoAxis;
893 }
874 }
894
875
895 #include "moc_qpieseries.cpp"
876 #include "moc_qpieseries.cpp"
896 #include "moc_qpieseries_p.cpp"
877 #include "moc_qpieseries_p.cpp"
897
878
898 QTCOMMERCIALCHART_END_NAMESPACE
879 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,89 +1,88
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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QPIESERIES_P_H
30 #ifndef QPIESERIES_P_H
31 #define QPIESERIES_P_H
31 #define QPIESERIES_P_H
32
32
33 #include "qpieseries.h"
33 #include "qpieseries.h"
34 #include "qabstractseries_p.h"
34 #include "qabstractseries_p.h"
35
35
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36 QTCOMMERCIALCHART_BEGIN_NAMESPACE
37 class QLegendPrivate;
37 class QLegendPrivate;
38
38
39 class QPieSeriesPrivate : public QAbstractSeriesPrivate
39 class QPieSeriesPrivate : public QAbstractSeriesPrivate
40 {
40 {
41 Q_OBJECT
41 Q_OBJECT
42
42
43 public:
43 public:
44 QPieSeriesPrivate(QPieSeries *parent);
44 QPieSeriesPrivate(QPieSeries *parent);
45 ~QPieSeriesPrivate();
45 ~QPieSeriesPrivate();
46
46
47 void scaleDomain(Domain& domain);
47 void scaleDomain(Domain& domain);
48 ChartElement* createGraphics(ChartPresenter *presenter);
48 ChartElement* createGraphics(ChartPresenter *presenter);
49 QList<LegendMarker*> createLegendMarker(QLegend *legend);
49 QList<LegendMarker*> createLegendMarker(QLegend *legend);
50 void initializeAxis(QAbstractAxis* axis);
50 void initializeAxis(QAbstractAxis* axis);
51 QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
51 QAbstractAxis::AxisType defaultAxisType(Qt::Orientation orientation) const;
52
52
53 void updateDerivativeData();
53 void updateDerivativeData();
54 void setSizes(qreal innerSize, qreal outerSize);
54 void setSizes(qreal innerSize, qreal outerSize);
55
55
56 static QPieSeriesPrivate* fromSeries(QPieSeries *series);
56 static QPieSeriesPrivate* fromSeries(QPieSeries *series);
57
57
58 signals:
58 signals:
59 void calculatedDataChanged();
59 void calculatedDataChanged();
60 void pieSizeChanged();
60 void pieSizeChanged();
61 void pieStartAngleChanged();
61 void pieStartAngleChanged();
62 void pieEndAngleChanged();
62 void pieEndAngleChanged();
63 void horizontalPositionChanged();
63 void horizontalPositionChanged();
64 void verticalPositionChanged();
64 void verticalPositionChanged();
65
65
66 public Q_SLOTS:
66 public Q_SLOTS:
67 void sliceValueChanged();
67 void sliceValueChanged();
68 void sliceClicked();
68 void sliceClicked();
69 void sliceHovered(bool state);
69 void sliceHovered(bool state);
70 void updateLegendProperties();
71
70
72 private:
71 private:
73 QList<QPieSlice*> m_slices;
72 QList<QPieSlice*> m_slices;
74 qreal m_pieRelativeHorPos;
73 qreal m_pieRelativeHorPos;
75 qreal m_pieRelativeVerPos;
74 qreal m_pieRelativeVerPos;
76 qreal m_pieRelativeSize;
75 qreal m_pieRelativeSize;
77 qreal m_pieStartAngle;
76 qreal m_pieStartAngle;
78 qreal m_pieEndAngle;
77 qreal m_pieEndAngle;
79 qreal m_sum;
78 qreal m_sum;
80 qreal m_holeRelativeSize;
79 qreal m_holeRelativeSize;
81
80
82 private:
81 private:
83 friend class QLegendPrivate;
82 friend class QLegendPrivate;
84 Q_DECLARE_PUBLIC(QPieSeries)
83 Q_DECLARE_PUBLIC(QPieSeries)
85 };
84 };
86
85
87 QTCOMMERCIALCHART_END_NAMESPACE
86 QTCOMMERCIALCHART_END_NAMESPACE
88
87
89 #endif // QPIESERIES_P_H
88 #endif // QPIESERIES_P_H
@@ -1,75 +1,76
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 // W A R N I N G
21 // W A R N I N G
22 // -------------
22 // -------------
23 //
23 //
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
24 // This file is not part of the QtCommercial Chart API. It exists purely as an
25 // implementation detail. This header file may change from version to
25 // implementation detail. This header file may change from version to
26 // version without notice, or even be removed.
26 // version without notice, or even be removed.
27 //
27 //
28 // We mean it.
28 // We mean it.
29
29
30 #ifndef QABSTRACTSERIES_P_H
30 #ifndef QABSTRACTSERIES_P_H
31 #define QABSTRACTSERIES_P_H
31 #define QABSTRACTSERIES_P_H
32
32
33 #include "qabstractseries.h"
33 #include "qabstractseries.h"
34
34
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
35 QTCOMMERCIALCHART_BEGIN_NAMESPACE
36
36
37 class Domain;
37 class Domain;
38 class ChartPresenter;
38 class ChartPresenter;
39 class ChartElement;
39 class ChartElement;
40 class LegendMarker;
40 class LegendMarker;
41 class QLegend;
41 class QLegend;
42 class ChartDataSet;
42 class ChartDataSet;
43 class QAbstractAxis;
43 class QAbstractAxis;
44
44
45 class QAbstractSeriesPrivate : public QObject
45 class QAbstractSeriesPrivate : public QObject
46 {
46 {
47 Q_OBJECT
47 Q_OBJECT
48 public:
48 public:
49 QAbstractSeriesPrivate(QAbstractSeries *q);
49 QAbstractSeriesPrivate(QAbstractSeries *q);
50 ~QAbstractSeriesPrivate();
50 ~QAbstractSeriesPrivate();
51
51
52 virtual void scaleDomain(Domain& domain) = 0;
52 virtual void scaleDomain(Domain& domain) = 0;
53 virtual ChartElement* createGraphics(ChartPresenter* presenter) = 0;
53 virtual ChartElement* createGraphics(ChartPresenter* presenter) = 0;
54 virtual QList<LegendMarker*> createLegendMarker(QLegend* legend) = 0;
54 virtual QList<LegendMarker*> createLegendMarker(QLegend* legend) = 0;
55 virtual void initializeAxis(QAbstractAxis* axis) = 0;
55 virtual void initializeAxis(QAbstractAxis* axis) = 0;
56 virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation) const = 0;
56 virtual QAbstractAxis::AxisType defaultAxisType(Qt::Orientation) const = 0;
57
57
58 Q_SIGNALS:
58 Q_SIGNALS:
59 void legendPropertiesUpdated(QAbstractSeries* series);
59 void countChanged();
60
60
61 protected:
61 protected:
62 QAbstractSeries *q_ptr;
62 QAbstractSeries *q_ptr;
63 QChart *m_chart;
63 QChart *m_chart;
64 ChartDataSet *m_dataset;
64 ChartDataSet *m_dataset;
65 QString m_name;
65 QString m_name;
66 bool m_visible;
66 bool m_visible;
67 qreal m_opacity;
67 qreal m_opacity;
68
68
69 friend class QAbstractSeries;
69 friend class QAbstractSeries;
70 friend class ChartDataSet;
70 friend class ChartDataSet;
71 friend class QLegendPrivate;
71 };
72 };
72
73
73 QTCOMMERCIALCHART_END_NAMESPACE
74 QTCOMMERCIALCHART_END_NAMESPACE
74
75
75 #endif
76 #endif
General Comments 0
You need to be logged in to leave comments. Login now