##// END OF EJS Templates
fix in legend series visibility handling
sauimone -
r1645:bb8b6398e656
parent child
Show More
@@ -1,533 +1,534
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 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 "qabstractbarseries.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 #include <QGraphicsLayout>
45 45 #include <QGraphicsSceneEvent>
46 46
47 47 QTCOMMERCIALCHART_BEGIN_NAMESPACE
48 48
49 49 /*!
50 50 \class QLegend
51 51 \brief Legend object
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 used 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 (brush) color. Note that if you change the color
107 107 of the legend, the style of the legend brush is set to Qt::SolidPattern.
108 108 */
109 109 /*!
110 110 \qmlproperty color Legend::color
111 111 The color of the legend, i.e. the background (brush) color.
112 112 */
113 113
114 114 /*!
115 115 \property QLegend::borderColor
116 116 The border color of the legend, i.e. the line color.
117 117 */
118 118 /*!
119 119 \qmlproperty color Legend::borderColor
120 120 The border color of the legend, i.e. the line color.
121 121 */
122 122
123 123 /*!
124 124 \property QLegend::font
125 125 The font of markers used by legend
126 126 */
127 127 /*!
128 128 \qmlproperty color Legend::font
129 129 The font of markers used by legend
130 130 */
131 131
132 132 /*!
133 133 \property QLegend::labelColor
134 134 The color of brush used to draw labels.
135 135 */
136 136 /*!
137 137 \qmlproperty color QLegend::labelColor
138 138 The color of brush used to draw labels.
139 139 */
140 140
141 141 /*!
142 142 \fn void QLegend::backgroundVisibleChanged(bool)
143 143 The visibility of the legend background changed to \a visible.
144 144 */
145 145
146 146 /*!
147 147 \fn void QLegend::colorChanged(QColor)
148 148 The color of the legend background changed to \a color.
149 149 */
150 150
151 151 /*!
152 152 \fn void QLegend::borderColorChanged(QColor)
153 153 The border color of the legend background changed to \a color.
154 154 */
155 155
156 156 /*!
157 157 \fn void QLegend::fontChanged(QFont)
158 158 The font of markers of the legend changed to \a font.
159 159 */
160 160
161 161 /*!
162 162 \fn void QLegend::labelColorChanged(QColor color)
163 163 This signal is emitted when the color of brush used to draw labels has changed to \a color.
164 164 */
165 165
166 166 /*!
167 167 Constructs the legend object and sets the parent to \a parent
168 168 */
169 169
170 170 QLegend::QLegend(QChart *chart):QGraphicsWidget(chart),
171 171 d_ptr(new QLegendPrivate(chart->d_ptr->m_presenter,chart,this))
172 172 {
173 173 setZValue(ChartPresenter::LegendZValue);
174 174 setFlags(QGraphicsItem::ItemClipsChildrenToShape);
175 175 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesAdded(QAbstractSeries*,Domain*)),d_ptr.data(),SLOT(handleSeriesAdded(QAbstractSeries*,Domain*)));
176 176 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesRemoved(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesRemoved(QAbstractSeries*)));
177 177 QObject::connect(chart->d_ptr->m_dataset,SIGNAL(seriesUpdated(QAbstractSeries*)),d_ptr.data(),SLOT(handleSeriesUpdated(QAbstractSeries*)));
178 178 setLayout(d_ptr->m_layout);
179 179 }
180 180
181 181 /*!
182 182 Destroys the legend object. Legend is always owned by a QChart, so an application should never call this.
183 183 */
184 184 QLegend::~QLegend()
185 185 {
186 186 }
187 187
188 188 /*!
189 189 \internal
190 190 */
191 191 void QLegend::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
192 192 {
193 193 Q_UNUSED(option)
194 194 Q_UNUSED(widget)
195 195 if(!d_ptr->m_backgroundVisible) return;
196 196
197 197 painter->setOpacity(opacity());
198 198 painter->setPen(d_ptr->m_pen);
199 199 painter->setBrush(d_ptr->m_brush);
200 200 painter->drawRoundRect(rect(),d_ptr->roundness(rect().width()),d_ptr->roundness(rect().height()));
201 201
202 202 }
203 203
204 204
205 205 /*!
206 206 Sets the \a brush of legend. Brush affects the background of legend.
207 207 */
208 208 void QLegend::setBrush(const QBrush &brush)
209 209 {
210 210 if (d_ptr->m_brush != brush) {
211 211 d_ptr->m_brush = brush;
212 212 update();
213 213 emit colorChanged(brush.color());
214 214 }
215 215 }
216 216
217 217 /*!
218 218 Returns the brush used by legend.
219 219 */
220 220 QBrush QLegend::brush() const
221 221 {
222 222 return d_ptr->m_brush;
223 223 }
224 224
225 225 void QLegend::setColor(QColor color)
226 226 {
227 227 QBrush b = d_ptr->m_brush;
228 228 if (b.style() != Qt::SolidPattern || b.color() != color) {
229 229 b.setStyle(Qt::SolidPattern);
230 230 b.setColor(color);
231 231 setBrush(b);
232 232 }
233 233 }
234 234
235 235 QColor QLegend::color()
236 236 {
237 237 return d_ptr->m_brush.color();
238 238 }
239 239
240 240 /*!
241 241 Sets the \a pen of legend. Pen affects the legend borders.
242 242 */
243 243 void QLegend::setPen(const QPen &pen)
244 244 {
245 245 if (d_ptr->m_pen != pen) {
246 246 d_ptr->m_pen = pen;
247 247 update();
248 248 emit borderColorChanged(pen.color());
249 249 }
250 250 }
251 251
252 252 /*!
253 253 Returns the pen used by legend
254 254 */
255 255
256 256 QPen QLegend::pen() const
257 257 {
258 258 return d_ptr->m_pen;
259 259 }
260 260
261 261 void QLegend::setFont(const QFont &font)
262 262 {
263 263 if (d_ptr->m_font != font) {
264 264 d_ptr->m_font = font;
265 265
266 266 foreach (LegendMarker *marker, d_ptr->markers()) {
267 267 marker->setFont(d_ptr->m_font);
268 268 }
269 269 layout()->invalidate();
270 270 emit fontChanged(font);
271 271 }
272 272 }
273 273
274 274 QFont QLegend::font() const
275 275 {
276 276 return d_ptr->m_font;
277 277 }
278 278
279 279 void QLegend::setBorderColor(QColor color)
280 280 {
281 281 QPen p = d_ptr->m_pen;
282 282 if (p.color() != color) {
283 283 p.setColor(color);
284 284 setPen(p);
285 285 }
286 286 }
287 287
288 288 QColor QLegend::borderColor()
289 289 {
290 290 return d_ptr->m_pen.color();
291 291 }
292 292
293 293 /*!
294 294 Set brush used to draw labels to \a brush.
295 295 */
296 296 void QLegend::setLabelBrush(const QBrush &brush)
297 297 {
298 298 if (d_ptr->m_labelBrush != brush) {
299 299 d_ptr->m_labelBrush = brush;
300 300 foreach (LegendMarker *marker, d_ptr->markers()) {
301 301 marker->setLabelBrush(d_ptr->m_labelBrush);
302 302 }
303 303 emit labelColorChanged(brush.color());
304 304 }
305 305 }
306 306
307 307 /*!
308 308 Brush used to draw labels.
309 309 */
310 310 QBrush QLegend::labelBrush() const
311 311 {
312 312 return d_ptr->m_labelBrush;
313 313 }
314 314
315 315 void QLegend::setLabelColor(QColor color)
316 316 {
317 317 QBrush b = d_ptr->m_labelBrush;
318 318 if (b.style() != Qt::SolidPattern || b.color() != color) {
319 319 b.setStyle(Qt::SolidPattern);
320 320 b.setColor(color);
321 321 setLabelBrush(b);
322 322 }
323 323 }
324 324
325 325 QColor QLegend::labelColor() const
326 326 {
327 327 return d_ptr->m_labelBrush.color();
328 328 }
329 329
330 330
331 331 void QLegend::setAlignment(Qt::Alignment alignment)
332 332 {
333 333 if(d_ptr->m_alignment!=alignment) {
334 334 d_ptr->m_alignment = alignment;
335 335 updateGeometry();
336 336 if(isAttachedToChart()){
337 337 d_ptr->m_presenter->layout()->invalidate();
338 338 }else{
339 339 layout()->invalidate();
340 340 }
341 341 }
342 342 }
343 343
344 344 Qt::Alignment QLegend::alignment() const
345 345 {
346 346 return d_ptr->m_alignment;
347 347 }
348 348
349 349 /*!
350 350 Detaches the legend from chart. Chart won't change layout of the legend.
351 351 */
352 352 void QLegend::detachFromChart()
353 353 {
354 354 d_ptr->m_attachedToChart = false;
355 355 d_ptr->m_layout->invalidate();
356 356 setParent(0);
357 357
358 358 }
359 359
360 360 /*!
361 361 Attaches the legend to chart. Chart may change layout of the legend.
362 362 */
363 363 void QLegend::attachToChart()
364 364 {
365 365 d_ptr->m_attachedToChart = true;
366 366 d_ptr->m_layout->invalidate();
367 367 setParent(d_ptr->m_chart);
368 368 }
369 369
370 370 /*!
371 371 Returns true, if legend is attached to chart.
372 372 */
373 373 bool QLegend::isAttachedToChart()
374 374 {
375 375 return d_ptr->m_attachedToChart;
376 376 }
377 377
378 378 /*!
379 379 Sets the visibility of legend background to \a visible
380 380 */
381 381 void QLegend::setBackgroundVisible(bool visible)
382 382 {
383 383 if(d_ptr->m_backgroundVisible != visible) {
384 384 d_ptr->m_backgroundVisible = visible;
385 385 update();
386 386 emit backgroundVisibleChanged(visible);
387 387 }
388 388 }
389 389
390 390 /*!
391 391 Returns the visibility of legend background
392 392 */
393 393 bool QLegend::isBackgroundVisible() const
394 394 {
395 395 return d_ptr->m_backgroundVisible;
396 396 }
397 397
398 398 /*!
399 399 \internal \a event see QGraphicsWidget for details
400 400 */
401 401 void QLegend::hideEvent(QHideEvent *event)
402 402 {
403 403 QGraphicsWidget::hideEvent(event);
404 404 d_ptr->m_presenter->layout()->invalidate();
405 405 }
406 406
407 407 /*!
408 408 \internal \a event see QGraphicsWidget for details
409 409 */
410 410 void QLegend::showEvent(QShowEvent *event)
411 411 {
412 412 QGraphicsWidget::showEvent(event);
413 413 d_ptr->m_presenter->layout()->invalidate();
414 414 }
415 415
416 416 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
417 417
418 418 QLegendPrivate::QLegendPrivate(ChartPresenter* presenter, QChart *chart, QLegend *q):
419 419 q_ptr(q),
420 420 m_presenter(presenter),
421 421 m_layout(new LegendLayout(q)),
422 422 m_chart(chart),
423 423 m_items(new QGraphicsItemGroup(q)),
424 424 m_alignment(Qt::AlignTop),
425 425 m_brush(QBrush()),
426 426 m_pen(QPen()),
427 427 m_labelBrush(QBrush()),
428 428 m_diameter(5),
429 429 m_attachedToChart(true),
430 430 m_backgroundVisible(false)
431 431 {
432 432
433 433 }
434 434
435 435 QLegendPrivate::~QLegendPrivate()
436 436 {
437 437
438 438 }
439 439
440 440 void QLegendPrivate::setOffset(qreal x, qreal y)
441 441 {
442 442 m_layout->setOffset(x,y);
443 443 }
444 444
445 445 QPointF QLegendPrivate::offset() const
446 446 {
447 447 return m_layout->offset();
448 448 }
449 449
450 450 int QLegendPrivate::roundness(qreal size)
451 451 {
452 452 return 100*m_diameter/int(size);
453 453 }
454 454
455 455 void QLegendPrivate::handleSeriesAdded(QAbstractSeries *series, Domain *domain)
456 456 {
457 457 Q_UNUSED(domain)
458 458
459 459 QList<LegendMarker*> markers = series->d_ptr->createLegendMarker(q_ptr);
460 460
461 461 foreach(LegendMarker* marker, markers) {
462 462 marker->setFont(m_font);
463 463 marker->setLabelBrush(m_labelBrush);
464 marker->setVisible(series->isVisible());
464 465 m_items->addToGroup(marker);
465 466 m_markers<<marker;
466 467 }
467 468
468 469 QObject::connect(series, SIGNAL(visibleChanged()), this, SLOT(handleSeriesVisibleChanged()));
469 470
470 471 if(series->type() == QAbstractSeries::SeriesTypePie) {
471 472 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
472 473 QObject::connect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
473 474 QObject::connect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
474 475 }
475 476
476 477 q_ptr->layout()->invalidate();
477 478 q_ptr->layout()->activate();
478 479 }
479 480
480 481 void QLegendPrivate::handleSeriesRemoved(QAbstractSeries *series)
481 482 {
482 483 foreach (LegendMarker *marker, m_markers) {
483 484 if (marker->series() == series) {
484 485 delete marker;
485 486 m_markers.removeAll(marker);
486 487 }
487 488 }
488 489
489 490 if(series->type() == QAbstractSeries::SeriesTypePie)
490 491 {
491 492 QPieSeries *pieSeries = static_cast<QPieSeries *>(series);
492 493 QObject::disconnect(pieSeries, SIGNAL(added(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
493 494 QObject::disconnect(pieSeries, SIGNAL(removed(QList<QPieSlice*>)), this, SLOT(handleUpdatePieSeries()));
494 495 }
495 496
496 497 q_ptr->layout()->invalidate();
497 498 }
498 499
499 500 void QLegendPrivate::handleSeriesUpdated(QAbstractSeries *series)
500 501 {
501 502 // TODO: find out which markers are are added or removed. Update them
502 503 // TODO: better implementation
503 504 handleSeriesRemoved(series);
504 505 Domain domain;
505 506 handleSeriesAdded(series, &domain);
506 507 }
507 508
508 509 void QLegendPrivate::handleUpdatePieSeries()
509 510 {
510 511 //TODO: reimplement to be optimal
511 512 QPieSeries* series = qobject_cast<QPieSeries *> (sender());
512 513 Q_ASSERT(series);
513 514 handleSeriesRemoved(series);
514 515 handleSeriesAdded(series, 0);
515 516 }
516 517
517 518 void QLegendPrivate::handleSeriesVisibleChanged()
518 519 {
519 520 QAbstractSeries* series = qobject_cast<QAbstractSeries *> (sender());
520 521
521 522 foreach (LegendMarker* marker, m_markers) {
522 523 if (marker->series() == series) {
523 marker->setVisible(!marker->isVisible());
524 marker->setVisible(series->isVisible());
524 525 }
525 526 }
526 527
527 528 q_ptr->layout()->invalidate();
528 529 }
529 530
530 531 #include "moc_qlegend.cpp"
531 532 #include "moc_qlegend_p.cpp"
532 533
533 534 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now