##// END OF EJS Templates
legend doc changes
sauimone -
r1501:ab5387953f46
parent child
Show More
@@ -1,762 +1,760
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "qlegend.h"
21 #include "qlegend.h"
22 #include "qlegend_p.h"
22 #include "qlegend_p.h"
23 #include "qabstractseries.h"
23 #include "qabstractseries.h"
24 #include "qabstractseries_p.h"
24 #include "qabstractseries_p.h"
25 #include "qchart_p.h"
25 #include "qchart_p.h"
26
26
27 #include "legendmarker_p.h"
27 #include "legendmarker_p.h"
28 #include "qxyseries.h"
28 #include "qxyseries.h"
29 #include "qlineseries.h"
29 #include "qlineseries.h"
30 #include "qareaseries.h"
30 #include "qareaseries.h"
31 #include "qscatterseries.h"
31 #include "qscatterseries.h"
32 #include "qsplineseries.h"
32 #include "qsplineseries.h"
33 #include "qbarseries.h"
33 #include "qbarseries.h"
34 #include "qstackedbarseries.h"
34 #include "qstackedbarseries.h"
35 #include "qpercentbarseries.h"
35 #include "qpercentbarseries.h"
36 #include "qbarset.h"
36 #include "qbarset.h"
37 #include "qpieseries.h"
37 #include "qpieseries.h"
38 #include "qpieseries_p.h"
38 #include "qpieseries_p.h"
39 #include "qpieslice.h"
39 #include "qpieslice.h"
40 #include "chartpresenter_p.h"
40 #include "chartpresenter_p.h"
41 #include <QPainter>
41 #include <QPainter>
42 #include <QPen>
42 #include <QPen>
43 #include <QTimer>
43 #include <QTimer>
44
44
45 #include <QGraphicsSceneEvent>
45 #include <QGraphicsSceneEvent>
46
46
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48
48
49 /*!
49 /*!
50 \class QLegend
50 \class QLegend
51 \brief part of QtCommercial chart API.
51 \brief Legend object
52 \mainclass
52 \mainclass
53
53
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
54 QLegend is a graphical object, whics displays legend of the chart. Legend state is updated by QChart, when
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
55 series have been changed. By default, legend is drawn by QChart, but user can set a new parent to legend and
56 handle the drawing manually.
56 handle the drawing manually.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
57 User isn't supposed to create or delete legend objects, but can reference it via QChart class.
58
58
59 \image examples_percentbarchart_legend.png
59 \image examples_percentbarchart_legend.png
60
60
61 \sa QChart
61 \sa QChart
62 */
62 */
63 /*!
63 /*!
64 \qmlclass Legend QLegend
64 \qmlclass Legend QLegend
65 \brief Legend is part of QtCommercial Chart QML API.
65 \brief Legend is part of QtCommercial Chart QML API.
66
66
67 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
67 Legend is a graphical object, whics displays legend of the chart. Legend state is updated by ChartView, when
68 series have been changed. Legend is used via ChartView class. For example:
68 series have been changed. Legend is used via ChartView class. For example:
69 \code
69 \code
70 ChartView {
70 ChartView {
71 legend.visible: true
71 legend.visible: true
72 legend.alignment: Qt.AlignBottom
72 legend.alignment: Qt.AlignBottom
73 // Add a few series...
73 // Add a few series...
74 }
74 }
75 \endcode
75 \endcode
76
76
77 \image examples_percentbarchart_legend.png
77 \image examples_percentbarchart_legend.png
78 */
78 */
79
79
80 /*!
80 /*!
81 \property QLegend::alignment
81 \property QLegend::alignment
82 \brief The alignment of the legend.
82 \brief The alignment of the legend.
83
83
84 Legend paints on the defined position in the chart. The following alignments are supported:
84 Legend paints on the defined position in the chart. The following alignments are supported:
85 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
85 Qt::AlignTop, Qt::AlignBottom, Qt::AlignLeft, Qt::AlignRight. If you set more than one flag the result is undefined.
86 */
86 */
87 /*!
87 /*!
88 \qmlproperty Qt.Alignment Legend::alignment
88 \qmlproperty Qt.Alignment Legend::alignment
89 \brief The alignment of the legend.
89 \brief The alignment of the legend.
90
90
91 Legend paints on the defined position in the chart. The following alignments are supported:
91 Legend paints on the defined position in the chart. The following alignments are supported:
92 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
92 Qt.AlignTop, Qt.AlignBottom, Qt.AlignLeft, Qt.AlignRight. If you set more than one flag the result is undefined.
93 */
93 */
94
94
95 /*!
95 /*!
96 \property QLegend::backgroundVisible
96 \property QLegend::backgroundVisible
97 Whether the legend background is visible or not.
97 Whether the legend background is visible or not.
98 */
98 */
99 /*!
99 /*!
100 \qmlproperty bool Legend::backgroundVisible
100 \qmlproperty bool Legend::backgroundVisible
101 Whether the legend background is visible or not.
101 Whether the legend background is visible or not.
102 */
102 */
103
103
104 /*!
104 /*!
105 \property QLegend::color
105 \property QLegend::color
106 The color of the legend, i.e. the background (brush) color. Note that if you change the color
106 The color of the legend, i.e. the background (brush) color. Note that if you change the color
107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
108 */
108 */
109 /*!
109 /*!
110 \qmlproperty color Legend::color
110 \qmlproperty color Legend::color
111 The color of the legend, i.e. the background (brush) color.
111 The color of the legend, i.e. the background (brush) color.
112 */
112 */
113
113
114 /*!
114 /*!
115 \property QLegend::borderColor
115 \property QLegend::borderColor
116 The border color of the legend, i.e. the line color.
116 The border color of the legend, i.e. the line color.
117 */
117 */
118 /*!
118 /*!
119 \qmlproperty color Legend::borderColor
119 \qmlproperty color Legend::borderColor
120 The border color of the legend, i.e. the line color.
120 The border color of the legend, i.e. the line color.
121 */
121 */
122
122
123 /*!
123 /*!
124 \fn void QLegend::backgroundVisibleChanged(bool)
124 \fn void QLegend::backgroundVisibleChanged(bool)
125 The visibility of the legend background changed to \a visible.
125 The visibility of the legend background changed to \a visible.
126 */
126 */
127
127
128 /*!
128 /*!
129 \fn void QLegend::colorChanged(QColor)
129 \fn void QLegend::colorChanged(QColor)
130 The color of the legend background changed to \a color.
130 The color of the legend background changed to \a color.
131 */
131 */
132
132
133 /*!
133 /*!
134 \fn void QLegend::borderColorChanged(QColor)
134 \fn void QLegend::borderColorChanged(QColor)
135 The border color of the legend background changed to \a color.
135 The border color of the legend background changed to \a color.
136 */
136 */
137
137
138 /*!
138 /*!
139 \fn qreal QLegend::minWidth() const
139 \fn qreal QLegend::minWidth() const
140 Returns minimum width of the legend
140 Returns minimum width of the legend
141 */
141 */
142
142
143 /*!
143 /*!
144 \fn qreal QLegend::minHeight() const
144 \fn qreal QLegend::minHeight() const
145 Returns minimum height of the legend
145 Returns minimum height of the legend
146 */
146 */
147
147
148 /*!
148 /*!
149 Constructs the legend object and sets the parent to \a parent
149 Constructs the legend object and sets the parent to \a parent
150 */
150 */
151
151
152 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
152 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
153 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
153 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
154 {
154 {
155 setZValue(ChartPresenter::LegendZValue);
155 setZValue(ChartPresenter::LegendZValue);
156 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
156 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
157 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
157 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
158 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
158 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
159 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
159 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
160 }
160 }
161
161
162 /*!
162 /*!
163 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
163 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
164 */
164 */
165 QLegend::~QLegend()
165 QLegend::~QLegend()
166 {
166 {
167 }
167 }
168
168
169 /*!
169 /*!
170 Paints the legend to given \a painter. Paremeters \a option and \a widget arent used.
170 \internal
171 */
171 */
172
173 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
172 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
174 {
173 {
175 Q_UNUSED(option)
174 Q_UNUSED(option)
176 Q_UNUSED(widget)
175 Q_UNUSED(widget)
177 if(!d_ptr->m_backgroundVisible) return;
176 if(!d_ptr->m_backgroundVisible) return;
178
177
179 painter->setOpacity(opacity());
178 painter->setOpacity(opacity());
180 painter->setPen(d_ptr->m_pen);
179 painter->setPen(d_ptr->m_pen);
181 painter->setBrush(d_ptr->m_brush);
180 painter->setBrush(d_ptr->m_brush);
182 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
181 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
183 }
182 }
184
183
185 /*!
184 /*!
186 Bounding rect of legend.
185 \internal
187 */
186 */
188
189 QRectF QLegend::boundingRect() const
187 QRectF QLegend::boundingRect() const
190 {
188 {
191 return d_ptr->m_rect;
189 return d_ptr->m_rect;
192 }
190 }
193
191
194 /*!
192 /*!
195 Sets the \a brush of legend. Brush affects the background of legend.
193 Sets the \a brush of legend. Brush affects the background of legend.
196 */
194 */
197 void QLegend::setBrush(const QBrush &brush)
195 void QLegend::setBrush(const QBrush &brush)
198 {
196 {
199 if (d_ptr->m_brush != brush) {
197 if (d_ptr->m_brush != brush) {
200 d_ptr->m_brush = brush;
198 d_ptr->m_brush = brush;
201 update();
199 update();
202 }
200 }
203 }
201 }
204
202
205 /*!
203 /*!
206 Returns the brush used by legend.
204 Returns the brush used by legend.
207 */
205 */
208 QBrush QLegend::brush() const
206 QBrush QLegend::brush() const
209 {
207 {
210 return d_ptr->m_brush;
208 return d_ptr->m_brush;
211 }
209 }
212
210
213 void QLegend::setColor(QColor color)
211 void QLegend::setColor(QColor color)
214 {
212 {
215 QBrush b = d_ptr->m_brush;
213 QBrush b = d_ptr->m_brush;
216 if (b.style() != Qt::SolidPattern || b.color() != color) {
214 if (b.style() != Qt::SolidPattern || b.color() != color) {
217 b.setStyle(Qt::SolidPattern);
215 b.setStyle(Qt::SolidPattern);
218 b.setColor(color);
216 b.setColor(color);
219 setBrush(b);
217 setBrush(b);
220 emit colorChanged(color);
218 emit colorChanged(color);
221 }
219 }
222 }
220 }
223
221
224 QColor QLegend::color()
222 QColor QLegend::color()
225 {
223 {
226 return d_ptr->m_brush.color();
224 return d_ptr->m_brush.color();
227 }
225 }
228
226
229 /*!
227 /*!
230 Sets the \a pen of legend. Pen affects the legend borders.
228 Sets the \a pen of legend. Pen affects the legend borders.
231 */
229 */
232 void QLegend::setPen(const QPen &pen)
230 void QLegend::setPen(const QPen &pen)
233 {
231 {
234 if (d_ptr->m_pen != pen) {
232 if (d_ptr->m_pen != pen) {
235 d_ptr->m_pen = pen;
233 d_ptr->m_pen = pen;
236 update();
234 update();
237 }
235 }
238 }
236 }
239
237
240 /*!
238 /*!
241 Returns the pen used by legend
239 Returns the pen used by legend
242 */
240 */
243
241
244 QPen QLegend::pen() const
242 QPen QLegend::pen() const
245 {
243 {
246 return d_ptr->m_pen;
244 return d_ptr->m_pen;
247 }
245 }
248
246
249 void QLegend::setBorderColor(QColor color)
247 void QLegend::setBorderColor(QColor color)
250 {
248 {
251 QPen p = d_ptr->m_pen;
249 QPen p = d_ptr->m_pen;
252 if (p.color() != color) {
250 if (p.color() != color) {
253 p.setColor(color);
251 p.setColor(color);
254 setPen(p);
252 setPen(p);
255 emit borderColorChanged(color);
253 emit borderColorChanged(color);
256 }
254 }
257 }
255 }
258
256
259 QColor QLegend::borderColor()
257 QColor QLegend::borderColor()
260 {
258 {
261 return d_ptr->m_pen.color();
259 return d_ptr->m_pen.color();
262 }
260 }
263
261
264 void QLegend::setAlignment(Qt::Alignment alignment)
262 void QLegend::setAlignment(Qt::Alignment alignment)
265 {
263 {
266 if(d_ptr->m_alignment!=alignment) {
264 if(d_ptr->m_alignment!=alignment) {
267 d_ptr->m_alignment = alignment;
265 d_ptr->m_alignment = alignment;
268 d_ptr->updateLayout();
266 d_ptr->updateLayout();
269 }
267 }
270 }
268 }
271
269
272 Qt::Alignment QLegend::alignment() const
270 Qt::Alignment QLegend::alignment() const
273 {
271 {
274 return d_ptr->m_alignment;
272 return d_ptr->m_alignment;
275 }
273 }
276
274
277 /*!
275 /*!
278 Detaches the legend from chart. Chart won't change layout of the legend.
276 Detaches the legend from chart. Chart won't change layout of the legend.
279 */
277 */
280 void QLegend::detachFromChart()
278 void QLegend::detachFromChart()
281 {
279 {
282 d_ptr->m_attachedToChart = false;
280 d_ptr->m_attachedToChart = false;
283 }
281 }
284
282
285 /*!
283 /*!
286 Attaches the legend to chart. Chart may change layout of the legend.
284 Attaches the legend to chart. Chart may change layout of the legend.
287 */
285 */
288 void QLegend::attachToChart()
286 void QLegend::attachToChart()
289 {
287 {
290 d_ptr->attachToChart();
288 d_ptr->attachToChart();
291 }
289 }
292
290
293 /*!
291 /*!
294 Returns true, if legend is attached to chart.
292 Returns true, if legend is attached to chart.
295 */
293 */
296 bool QLegend::isAttachedToChart()
294 bool QLegend::isAttachedToChart()
297 {
295 {
298 return d_ptr->m_attachedToChart;
296 return d_ptr->m_attachedToChart;
299 }
297 }
300
298
301 /*!
299 /*!
302 Sets the visibility of legend background to \a visible
300 Sets the visibility of legend background to \a visible
303 */
301 */
304 void QLegend::setBackgroundVisible(bool visible)
302 void QLegend::setBackgroundVisible(bool visible)
305 {
303 {
306 if(d_ptr->m_backgroundVisible != visible) {
304 if(d_ptr->m_backgroundVisible != visible) {
307 d_ptr->m_backgroundVisible = visible;
305 d_ptr->m_backgroundVisible = visible;
308 update();
306 update();
309 emit backgroundVisibleChanged(visible);
307 emit backgroundVisibleChanged(visible);
310 }
308 }
311 }
309 }
312
310
313 /*!
311 /*!
314 Returns the visibility of legend background
312 Returns the visibility of legend background
315 */
313 */
316 bool QLegend::isBackgroundVisible() const
314 bool QLegend::isBackgroundVisible() const
317 {
315 {
318 return d_ptr->m_backgroundVisible;
316 return d_ptr->m_backgroundVisible;
319 }
317 }
320
318
321 /*!
319 /*!
322 \internal \a event see QGraphicsWidget for details
320 \internal \a event see QGraphicsWidget for details
323 */
321 */
324 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
322 void QLegend::resizeEvent(QGraphicsSceneResizeEvent *event)
325 {
323 {
326 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
324 const QRectF& rect = QRectF(QPoint(0,0),event->newSize());
327 QGraphicsWidget::resizeEvent(event);
325 QGraphicsWidget::resizeEvent(event);
328 if(d_ptr->m_rect != rect) {
326 if(d_ptr->m_rect != rect) {
329 d_ptr->m_rect = rect;
327 d_ptr->m_rect = rect;
330 d_ptr->updateLayout();
328 d_ptr->updateLayout();
331 }
329 }
332 }
330 }
333
331
334 /*!
332 /*!
335 \internal \a event see QGraphicsWidget for details
333 \internal \a event see QGraphicsWidget for details
336 */
334 */
337 void QLegend::hideEvent(QHideEvent *event)
335 void QLegend::hideEvent(QHideEvent *event)
338 {
336 {
339 QGraphicsWidget::hideEvent(event);
337 QGraphicsWidget::hideEvent(event);
340 setEnabled(false);
338 setEnabled(false);
341 d_ptr->updateLayout();
339 d_ptr->updateLayout();
342 }
340 }
343
341
344 /*!
342 /*!
345 \internal \a event see QGraphicsWidget for details
343 \internal \a event see QGraphicsWidget for details
346 */
344 */
347 void QLegend::showEvent(QShowEvent *event)
345 void QLegend::showEvent(QShowEvent *event)
348 {
346 {
349 QGraphicsWidget::showEvent(event);
347 QGraphicsWidget::showEvent(event);
350 setEnabled(true);
348 setEnabled(true);
351 d_ptr->updateLayout();
349 d_ptr->updateLayout();
352 }
350 }
353
351
354 qreal QLegend::minWidth() const
352 qreal QLegend::minWidth() const
355 {
353 {
356 return d_ptr->m_minWidth;
354 return d_ptr->m_minWidth;
357 }
355 }
358
356
359 qreal QLegend::minHeight() const
357 qreal QLegend::minHeight() const
360 {
358 {
361 return d_ptr->m_minHeight;
359 return d_ptr->m_minHeight;
362 }
360 }
363
361
364 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
362 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
365
363
366 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
364 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
367 q_ptr(q),
365 q_ptr(q),
368 m_presenter(presenter),
366 m_presenter(presenter),
369 m_chart(chart),
367 m_chart(chart),
370 m_markers(new QGraphicsItemGroup(q)),
368 m_markers(new QGraphicsItemGroup(q)),
371 m_alignment(Qt::AlignTop),
369 m_alignment(Qt::AlignTop),
372 m_brush(QBrush()),
370 m_brush(QBrush()),
373 m_pen(QPen()),
371 m_pen(QPen()),
374 m_offsetX(0),
372 m_offsetX(0),
375 m_offsetY(0),
373 m_offsetY(0),
376 m_minWidth(0),
374 m_minWidth(0),
377 m_minHeight(0),
375 m_minHeight(0),
378 m_width(0),
376 m_width(0),
379 m_height(0),
377 m_height(0),
380 m_diameter(5),
378 m_diameter(5),
381 m_attachedToChart(true),
379 m_attachedToChart(true),
382 m_backgroundVisible(false)
380 m_backgroundVisible(false)
383 {
381 {
384
382
385 }
383 }
386
384
387 QLegendPrivate::~QLegendPrivate()
385 QLegendPrivate::~QLegendPrivate()
388 {
386 {
389
387
390 }
388 }
391
389
392 void QLegendPrivate::setOffset(qreal x, qreal y)
390 void QLegendPrivate::setOffset(qreal x, qreal y)
393 {
391 {
394 bool scrollHorizontal = true;
392 bool scrollHorizontal = true;
395 switch(m_alignment) {
393 switch(m_alignment) {
396 case Qt::AlignTop:
394 case Qt::AlignTop:
397 case Qt::AlignBottom: {
395 case Qt::AlignBottom: {
398 scrollHorizontal = true;
396 scrollHorizontal = true;
399 break;
397 break;
400 }
398 }
401 case Qt::AlignLeft:
399 case Qt::AlignLeft:
402 case Qt::AlignRight: {
400 case Qt::AlignRight: {
403 scrollHorizontal = false;
401 scrollHorizontal = false;
404 break;
402 break;
405 }
403 }
406 }
404 }
407
405
408 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
406 // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
409 if (!m_attachedToChart) {
407 if (!m_attachedToChart) {
410 scrollHorizontal = !scrollHorizontal;
408 scrollHorizontal = !scrollHorizontal;
411 }
409 }
412
410
413 // Limit offset between m_minOffset and m_maxOffset
411 // Limit offset between m_minOffset and m_maxOffset
414 if (scrollHorizontal) {
412 if (scrollHorizontal) {
415 if(m_width<=m_rect.width()) return;
413 if(m_width<=m_rect.width()) return;
416
414
417 if (x != m_offsetX) {
415 if (x != m_offsetX) {
418 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
416 m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
419 m_markers->setPos(-m_offsetX,m_rect.top());
417 m_markers->setPos(-m_offsetX,m_rect.top());
420 }
418 }
421 } else {
419 } else {
422 if(m_height<=m_rect.height()) return;
420 if(m_height<=m_rect.height()) return;
423
421
424 if (y != m_offsetY) {
422 if (y != m_offsetY) {
425 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
423 m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
426 m_markers->setPos(m_rect.left(),-m_offsetY);
424 m_markers->setPos(m_rect.left(),-m_offsetY);
427 }
425 }
428 }
426 }
429 }
427 }
430
428
431 QPointF QLegendPrivate::offset() const
429 QPointF QLegendPrivate::offset() const
432 {
430 {
433 return QPointF(m_offsetX,m_offsetY);
431 return QPointF(m_offsetX,m_offsetY);
434 }
432 }
435
433
436 void QLegendPrivate::updateLayout()
434 void QLegendPrivate::updateLayout()
437 {
435 {
438 if (!m_attachedToChart) {
436 if (!m_attachedToChart) {
439 updateDetachedLayout();
437 updateDetachedLayout();
440 return;
438 return;
441 }
439 }
442
440
443 m_offsetX=0;
441 m_offsetX=0;
444 QList<QGraphicsItem *> items = m_markers->childItems();
442 QList<QGraphicsItem *> items = m_markers->childItems();
445
443
446 if(items.isEmpty()) return;
444 if(items.isEmpty()) return;
447
445
448 m_minWidth=0;
446 m_minWidth=0;
449 m_minHeight=0;
447 m_minHeight=0;
450
448
451 switch(m_alignment) {
449 switch(m_alignment) {
452
450
453 case Qt::AlignTop:
451 case Qt::AlignTop:
454 case Qt::AlignBottom: {
452 case Qt::AlignBottom: {
455 QPointF point = m_rect.topLeft();
453 QPointF point = m_rect.topLeft();
456 m_width = 0;
454 m_width = 0;
457 foreach (QGraphicsItem *item, items) {
455 foreach (QGraphicsItem *item, items) {
458 if (item->isVisible()) {
456 if (item->isVisible()) {
459 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
457 item->setPos(point.x(),m_rect.height()/2 -item->boundingRect().height()/2);
460 const QRectF& rect = item->boundingRect();
458 const QRectF& rect = item->boundingRect();
461 qreal w = rect.width();
459 qreal w = rect.width();
462 m_minWidth=qMax(m_minWidth,w);
460 m_minWidth=qMax(m_minWidth,w);
463 m_minHeight=qMax(m_minHeight,rect.height());
461 m_minHeight=qMax(m_minHeight,rect.height());
464 m_width+=w;
462 m_width+=w;
465 point.setX(point.x() + w);
463 point.setX(point.x() + w);
466 }
464 }
467 }
465 }
468 if(m_width<m_rect.width()) {
466 if(m_width<m_rect.width()) {
469 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
467 m_markers->setPos(m_rect.width()/2-m_width/2,m_rect.top());
470 }
468 }
471 else {
469 else {
472 m_markers->setPos(m_rect.topLeft());
470 m_markers->setPos(m_rect.topLeft());
473 }
471 }
474 m_height=m_minHeight;
472 m_height=m_minHeight;
475 }
473 }
476 break;
474 break;
477 case Qt::AlignLeft:
475 case Qt::AlignLeft:
478 case Qt::AlignRight: {
476 case Qt::AlignRight: {
479 QPointF point = m_rect.topLeft();
477 QPointF point = m_rect.topLeft();
480 m_height = 0;
478 m_height = 0;
481 foreach (QGraphicsItem *item, items) {
479 foreach (QGraphicsItem *item, items) {
482 if (item->isVisible()) {
480 if (item->isVisible()) {
483 item->setPos(point);
481 item->setPos(point);
484 const QRectF& rect = item->boundingRect();
482 const QRectF& rect = item->boundingRect();
485 qreal h = rect.height();
483 qreal h = rect.height();
486 m_minWidth=qMax(m_minWidth,rect.width());
484 m_minWidth=qMax(m_minWidth,rect.width());
487 m_minHeight=qMax(m_minHeight,h);
485 m_minHeight=qMax(m_minHeight,h);
488 m_height+=h;
486 m_height+=h;
489 point.setY(point.y() + h);
487 point.setY(point.y() + h);
490 }
488 }
491 }
489 }
492 if(m_height<m_rect.height()) {
490 if(m_height<m_rect.height()) {
493 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
491 m_markers->setPos(m_rect.left(),m_rect.height()/2-m_height/2);
494 }
492 }
495 else {
493 else {
496 m_markers->setPos(m_rect.topLeft());
494 m_markers->setPos(m_rect.topLeft());
497 }
495 }
498 m_width=m_minWidth;
496 m_width=m_minWidth;
499 }
497 }
500 break;
498 break;
501 }
499 }
502
500
503 m_minOffsetX = 0;
501 m_minOffsetX = 0;
504 m_minOffsetY = 0;
502 m_minOffsetY = 0;
505 m_maxOffsetX = m_width - m_rect.width();
503 m_maxOffsetX = m_width - m_rect.width();
506 m_maxOffsetY = m_height - m_rect.height();
504 m_maxOffsetY = m_height - m_rect.height();
507
505
508 m_presenter->updateLayout();
506 m_presenter->updateLayout();
509 }
507 }
510
508
511 void QLegendPrivate::updateDetachedLayout()
509 void QLegendPrivate::updateDetachedLayout()
512 {
510 {
513 // Detached layout is different.
511 // Detached layout is different.
514 // In detached mode legend may have multiple rows and columns, so layout calculations
512 // In detached mode legend may have multiple rows and columns, so layout calculations
515 // differ a log from attached mode.
513 // differ a log from attached mode.
516 // Also the scrolling logic is bit different.
514 // Also the scrolling logic is bit different.
517 m_offsetX=0;
515 m_offsetX=0;
518 m_offsetY=0;
516 m_offsetY=0;
519 QList<QGraphicsItem *> items = m_markers->childItems();
517 QList<QGraphicsItem *> items = m_markers->childItems();
520
518
521 if(items.isEmpty()) return;
519 if(items.isEmpty()) return;
522
520
523 m_minWidth = 0;
521 m_minWidth = 0;
524 m_minHeight = 0;
522 m_minHeight = 0;
525
523
526 switch (m_alignment) {
524 switch (m_alignment) {
527 case Qt::AlignTop: {
525 case Qt::AlignTop: {
528 QPointF point = m_rect.topLeft();
526 QPointF point = m_rect.topLeft();
529 m_width = 0;
527 m_width = 0;
530 m_height = 0;
528 m_height = 0;
531 for (int i=0; i<items.count(); i++) {
529 for (int i=0; i<items.count(); i++) {
532 QGraphicsItem *item = items.at(i);
530 QGraphicsItem *item = items.at(i);
533 if (item->isVisible()) {
531 if (item->isVisible()) {
534 const QRectF& rect = item->boundingRect();
532 const QRectF& rect = item->boundingRect();
535 qreal w = rect.width();
533 qreal w = rect.width();
536 qreal h = rect.height();
534 qreal h = rect.height();
537 m_minWidth = qMax(m_minWidth,w);
535 m_minWidth = qMax(m_minWidth,w);
538 m_minHeight = qMax(m_minHeight,rect.height());
536 m_minHeight = qMax(m_minHeight,rect.height());
539 m_height = qMax(m_height,h);
537 m_height = qMax(m_height,h);
540 item->setPos(point.x(),point.y());
538 item->setPos(point.x(),point.y());
541 point.setX(point.x() + w);
539 point.setX(point.x() + w);
542 if (point.x() + w > m_rect.topLeft().x() + m_rect.width()) {
540 if (point.x() + w > m_rect.topLeft().x() + m_rect.width()) {
543 // Next item would go off rect.
541 // Next item would go off rect.
544 point.setX(m_rect.topLeft().x());
542 point.setX(m_rect.topLeft().x());
545 point.setY(point.y() + h);
543 point.setY(point.y() + h);
546 if (i+1 < items.count()) {
544 if (i+1 < items.count()) {
547 m_height += h;
545 m_height += h;
548 }
546 }
549 }
547 }
550 }
548 }
551 }
549 }
552 m_markers->setPos(m_rect.topLeft());
550 m_markers->setPos(m_rect.topLeft());
553 m_width = m_minWidth;
551 m_width = m_minWidth;
554
552
555 m_minOffsetX = 0;
553 m_minOffsetX = 0;
556 m_minOffsetY = 0;
554 m_minOffsetY = 0;
557 m_maxOffsetX = m_width - m_rect.width();
555 m_maxOffsetX = m_width - m_rect.width();
558 m_maxOffsetY = m_height - m_rect.height();
556 m_maxOffsetY = m_height - m_rect.height();
559 }
557 }
560 break;
558 break;
561 case Qt::AlignBottom: {
559 case Qt::AlignBottom: {
562 QPointF point = m_rect.bottomLeft();
560 QPointF point = m_rect.bottomLeft();
563 m_width = 0;
561 m_width = 0;
564 m_height = 0;
562 m_height = 0;
565 for (int i=0; i<items.count(); i++) {
563 for (int i=0; i<items.count(); i++) {
566 QGraphicsItem *item = items.at(i);
564 QGraphicsItem *item = items.at(i);
567 if (item->isVisible()) {
565 if (item->isVisible()) {
568 const QRectF& rect = item->boundingRect();
566 const QRectF& rect = item->boundingRect();
569 qreal w = rect.width();
567 qreal w = rect.width();
570 qreal h = rect.height();
568 qreal h = rect.height();
571 m_minWidth = qMax(m_minWidth,w);
569 m_minWidth = qMax(m_minWidth,w);
572 m_minHeight = qMax(m_minHeight,rect.height());
570 m_minHeight = qMax(m_minHeight,rect.height());
573 m_height = qMax(m_height,h);
571 m_height = qMax(m_height,h);
574 item->setPos(point.x(),point.y() - h);
572 item->setPos(point.x(),point.y() - h);
575 point.setX(point.x() + w);
573 point.setX(point.x() + w);
576 if (point.x() + w > m_rect.bottomLeft().x() + m_rect.width()) {
574 if (point.x() + w > m_rect.bottomLeft().x() + m_rect.width()) {
577 // Next item would go off rect.
575 // Next item would go off rect.
578 point.setX(m_rect.bottomLeft().x());
576 point.setX(m_rect.bottomLeft().x());
579 point.setY(point.y() - h);
577 point.setY(point.y() - h);
580 if (i+1 < items.count()) {
578 if (i+1 < items.count()) {
581 m_height += h;
579 m_height += h;
582 }
580 }
583 }
581 }
584 }
582 }
585 }
583 }
586 m_markers->setPos(m_rect.topLeft());
584 m_markers->setPos(m_rect.topLeft());
587 m_width = m_minWidth;
585 m_width = m_minWidth;
588
586
589 m_minOffsetX = 0;
587 m_minOffsetX = 0;
590 m_minOffsetY = qMin(m_rect.topLeft().y(), m_rect.topLeft().y() - m_height + m_rect.height());
588 m_minOffsetY = qMin(m_rect.topLeft().y(), m_rect.topLeft().y() - m_height + m_rect.height());
591 m_maxOffsetX = m_width - m_rect.width();
589 m_maxOffsetX = m_width - m_rect.width();
592 m_maxOffsetY = 0;
590 m_maxOffsetY = 0;
593 }
591 }
594 break;
592 break;
595 case Qt::AlignLeft: {
593 case Qt::AlignLeft: {
596 QPointF point = m_rect.topLeft();
594 QPointF point = m_rect.topLeft();
597 m_width = 0;
595 m_width = 0;
598 m_height = 0;
596 m_height = 0;
599 qreal maxWidth = 0;
597 qreal maxWidth = 0;
600 for (int i=0; i<items.count(); i++) {
598 for (int i=0; i<items.count(); i++) {
601 QGraphicsItem *item = items.at(i);
599 QGraphicsItem *item = items.at(i);
602 if (item->isVisible()) {
600 if (item->isVisible()) {
603 const QRectF& rect = item->boundingRect();
601 const QRectF& rect = item->boundingRect();
604 qreal w = rect.width();
602 qreal w = rect.width();
605 qreal h = rect.height();
603 qreal h = rect.height();
606 m_minWidth = qMax(m_minWidth,rect.width());
604 m_minWidth = qMax(m_minWidth,rect.width());
607 m_minHeight = qMax(m_minHeight,h);
605 m_minHeight = qMax(m_minHeight,h);
608 maxWidth = qMax(maxWidth,w);
606 maxWidth = qMax(maxWidth,w);
609 item->setPos(point.x(),point.y());
607 item->setPos(point.x(),point.y());
610 point.setY(point.y() + h);
608 point.setY(point.y() + h);
611 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
609 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
612 // Next item would go off rect.
610 // Next item would go off rect.
613 point.setX(point.x() + maxWidth);
611 point.setX(point.x() + maxWidth);
614 point.setY(m_rect.topLeft().y());
612 point.setY(m_rect.topLeft().y());
615 if (i+1 < items.count()) {
613 if (i+1 < items.count()) {
616 m_width += maxWidth;
614 m_width += maxWidth;
617 maxWidth = 0;
615 maxWidth = 0;
618 }
616 }
619 }
617 }
620 }
618 }
621 }
619 }
622 m_width += maxWidth;
620 m_width += maxWidth;
623 m_markers->setPos(m_rect.topLeft());
621 m_markers->setPos(m_rect.topLeft());
624 m_height = m_minHeight;
622 m_height = m_minHeight;
625
623
626 m_minOffsetX = 0;
624 m_minOffsetX = 0;
627 m_minOffsetY = 0;
625 m_minOffsetY = 0;
628 m_maxOffsetX = m_width - m_rect.width();
626 m_maxOffsetX = m_width - m_rect.width();
629 m_maxOffsetY = m_height - m_rect.height();
627 m_maxOffsetY = m_height - m_rect.height();
630 }
628 }
631 break;
629 break;
632 case Qt::AlignRight: {
630 case Qt::AlignRight: {
633 QPointF point = m_rect.topRight();
631 QPointF point = m_rect.topRight();
634 m_width = 0;
632 m_width = 0;
635 m_height = 0;
633 m_height = 0;
636 qreal maxWidth = 0;
634 qreal maxWidth = 0;
637 for (int i=0; i<items.count(); i++) {
635 for (int i=0; i<items.count(); i++) {
638 QGraphicsItem *item = items.at(i);
636 QGraphicsItem *item = items.at(i);
639 if (item->isVisible()) {
637 if (item->isVisible()) {
640 const QRectF& rect = item->boundingRect();
638 const QRectF& rect = item->boundingRect();
641 qreal w = rect.width();
639 qreal w = rect.width();
642 qreal h = rect.height();
640 qreal h = rect.height();
643 m_minWidth = qMax(m_minWidth,rect.width());
641 m_minWidth = qMax(m_minWidth,rect.width());
644 m_minHeight = qMax(m_minHeight,h);
642 m_minHeight = qMax(m_minHeight,h);
645 maxWidth = qMax(maxWidth,w);
643 maxWidth = qMax(maxWidth,w);
646 item->setPos(point.x() - w,point.y());
644 item->setPos(point.x() - w,point.y());
647 point.setY(point.y() + h);
645 point.setY(point.y() + h);
648 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
646 if (point.y() + h > m_rect.topLeft().y() + m_rect.height()) {
649 // Next item would go off rect.
647 // Next item would go off rect.
650 point.setX(point.x() - maxWidth);
648 point.setX(point.x() - maxWidth);
651 point.setY(m_rect.topLeft().y());
649 point.setY(m_rect.topLeft().y());
652 if (i+1 < items.count()) {
650 if (i+1 < items.count()) {
653 m_width += maxWidth;
651 m_width += maxWidth;
654 maxWidth = 0;
652 maxWidth = 0;
655 }
653 }
656 }
654 }
657 }
655 }
658 }
656 }
659 m_width += maxWidth;
657 m_width += maxWidth;
660 m_markers->setPos(m_rect.topLeft());
658 m_markers->setPos(m_rect.topLeft());
661 m_height = m_minHeight;
659 m_height = m_minHeight;
662
660
663 m_minOffsetX = qMin(m_rect.topLeft().x(), m_rect.topLeft().x() - m_width + m_rect.width());
661 m_minOffsetX = qMin(m_rect.topLeft().x(), m_rect.topLeft().x() - m_width + m_rect.width());
664 m_minOffsetY = 0;
662 m_minOffsetY = 0;
665 m_maxOffsetX = 0;
663 m_maxOffsetX = 0;
666 m_maxOffsetY = m_height - m_rect.height();
664 m_maxOffsetY = m_height - m_rect.height();
667 }
665 }
668 break;
666 break;
669 default:
667 default:
670 break;
668 break;
671 }
669 }
672 }
670 }
673
671
674 void QLegendPrivate::attachToChart()
672 void QLegendPrivate::attachToChart()
675 {
673 {
676 m_attachedToChart = true;
674 m_attachedToChart = true;
677 q_ptr->setParent(m_chart);
675 q_ptr->setParent(m_chart);
678 }
676 }
679
677
680 int QLegendPrivate::roundness(qreal size)
678 int QLegendPrivate::roundness(qreal size)
681 {
679 {
682 return 100*m_diameter/int(size);
680 return 100*m_diameter/int(size);
683 }
681 }
684
682
685 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
683 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
686 {
684 {
687 Q_UNUSED(domain)
685 Q_UNUSED(domain)
688
686
689 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
687 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
690 foreach(LegendMarker* marker, markers)
688 foreach(LegendMarker* marker, markers)
691 m_markers->addToGroup(marker);
689 m_markers->addToGroup(marker);
692
690
693 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
691 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
694
692
695 if(series->type() == QAbstractSeries::SeriesTypePie) {
693 if(series->type() == QAbstractSeries::SeriesTypePie) {
696 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
694 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
697 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
695 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
698 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
696 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
699 }
697 }
700
698
701 updateLayout();
699 updateLayout();
702 }
700 }
703
701
704 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
702 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
705 {
703 {
706 QList<QGraphicsItem *> items = m_markers->childItems();
704 QList<QGraphicsItem *> items = m_markers->childItems();
707
705
708 foreach (QGraphicsItem *markers, items) {
706 foreach (QGraphicsItem *markers, items) {
709 LegendMarker *marker = static_cast<LegendMarker*>(markers);
707 LegendMarker *marker = static_cast<LegendMarker*>(markers);
710 if (marker->series() == series) {
708 if (marker->series() == series) {
711 delete marker;
709 delete marker;
712 }
710 }
713 }
711 }
714
712
715 if(series->type() == QAbstractSeries::SeriesTypePie)
713 if(series->type() == QAbstractSeries::SeriesTypePie)
716 {
714 {
717 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
715 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
718 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
716 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
719 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
717 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
720 }
718 }
721
719
722 updateLayout();
720 updateLayout();
723 }
721 }
724
722
725 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
723 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
726 {
724 {
727 // TODO: find out which markers are are added or removed. Update them
725 // TODO: find out which markers are are added or removed. Update them
728 // TODO: better implementation
726 // TODO: better implementation
729 handleSeriesRemoved(series);
727 handleSeriesRemoved(series);
730 Domain domain;
728 Domain domain;
731 handleSeriesAdded(series, &domain);
729 handleSeriesAdded(series, &domain);
732 }
730 }
733
731
734 void QLegendPrivate::handleUpdatePieSeries()
732 void QLegendPrivate::handleUpdatePieSeries()
735 {
733 {
736 //TODO: reimplement to be optimal
734 //TODO: reimplement to be optimal
737 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
735 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
738 Q_ASSERT(series);
736 Q_ASSERT(series);
739 handleSeriesRemoved(series);
737 handleSeriesRemoved(series);
740 handleSeriesAdded(series, 0);
738 handleSeriesAdded(series, 0);
741 }
739 }
742
740
743 void QLegendPrivate::handleSeriesVisibleChanged()
741 void QLegendPrivate::handleSeriesVisibleChanged()
744 {
742 {
745 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
743 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
746 QList<QGraphicsItem *> items = m_markers->childItems();
744 QList<QGraphicsItem *> items = m_markers->childItems();
747
745
748 foreach (QGraphicsItem *markers, items) {
746 foreach (QGraphicsItem *markers, items) {
749 LegendMarker *marker = static_cast<LegendMarker*>(markers);
747 LegendMarker *marker = static_cast<LegendMarker*>(markers);
750 if (marker->series() == series) {
748 if (marker->series() == series) {
751 marker->setVisible(!marker->isVisible());
749 marker->setVisible(!marker->isVisible());
752 }
750 }
753 }
751 }
754
752
755 updateLayout();
753 updateLayout();
756 }
754 }
757
755
758
756
759 #include "moc_qlegend.cpp"
757 #include "moc_qlegend.cpp"
760 #include "moc_qlegend_p.cpp"
758 #include "moc_qlegend_p.cpp"
761
759
762 QTCOMMERCIALCHART_END_NAMESPACE
760 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now