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