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