KD Chart 2  [rev.2.8]
KDChartLegend.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2021 Klaralvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Chart library.
5 **
6 ** Licensees holding valid commercial KD Chart licenses may use this file in
7 ** accordance with the KD Chart Commercial License Agreement provided with
8 ** the Software.
9 **
10 **
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 and version 3 as published by the
13 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
14 **
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 **
18 ** Contact info@kdab.com if any conditions of this licensing are not
19 ** clear to you.
20 **
21 **********************************************************************/
22 
23 #include "KDChartLegend.h"
24 #include "KDChartLegend_p.h"
25 #include <KDChartTextAttributes.h>
27 #include <KDChartPalette.h>
28 #include <KDChartAbstractDiagram.h>
29 #include "KDTextDocument.h"
30 #include <KDChartDiagramObserver.h>
31 #include "KDChartLayoutItems.h"
32 
33 #include <QFont>
34 #include <QGridLayout>
35 #include <QPainter>
36 #include <QTextTableCell>
37 #include <QTextCursor>
38 #include <QTextCharFormat>
39 #include <QTextDocumentFragment>
40 #include <QTimer>
41 #include <QAbstractTextDocumentLayout>
42 #include <QtDebug>
43 #include <QLabel>
44 
45 #include <KDABLibFakes>
46 
47 using namespace KDChart;
48 
49 Legend::Private::Private() :
50  referenceArea( 0 ),
51  position( Position::East ),
52  alignment( Qt::AlignCenter ),
53  textAlignment( Qt::AlignCenter ),
54  relativePosition( RelativePosition() ),
55  orientation( Qt::Vertical ),
56  order( Qt::AscendingOrder ),
57  showLines( false ),
58  titleText( QObject::tr( "Legend" ) ),
59  spacing( 1 ),
60  useAutomaticMarkerSize( true ),
61  legendStyle( MarkersOnly )
62 {
63  // By default we specify a simple, hard point as the 'relative' position's ref. point,
64  // since we can not be sure that there will be any parent specified for the legend.
65  relativePosition.setReferencePoints( PositionPoints( QPointF( 0.0, 0.0 ) ) );
66  relativePosition.setReferencePosition( Position::NorthWest );
67  relativePosition.setAlignment( Qt::AlignTop | Qt::AlignLeft );
68  relativePosition.setHorizontalPadding( Measure( 4.0, KDChartEnums::MeasureCalculationModeAbsolute ) );
69  relativePosition.setVerticalPadding( Measure( 4.0, KDChartEnums::MeasureCalculationModeAbsolute ) );
70 }
71 
72 Legend::Private::~Private()
73 {
74  // this bloc left empty intentionally
75 }
76 
77 
78 #define d d_func()
79 
80 
81 Legend::Legend( QWidget* parent ) :
82  AbstractAreaWidget( new Private(), parent )
83 {
84  d->referenceArea = parent;
85  init();
86 }
87 
88 Legend::Legend( AbstractDiagram* diagram, QWidget* parent ) :
89  AbstractAreaWidget( new Private(), parent )
90 {
91  d->referenceArea = parent;
92  init();
94 }
95 
97 {
98  emit destroyedLegend( this );
99 }
100 
101 void Legend::init()
102 {
103  setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
104 
105  d->layout = new QGridLayout( this );
106  d->layout->setMargin( 2 );
107  d->layout->setSpacing( d->spacing );
108 
109  const Measure normalFontSizeTitle( 12, KDChartEnums::MeasureCalculationModeAbsolute );
110  const Measure normalFontSizeLabels( 10, KDChartEnums::MeasureCalculationModeAbsolute );
111  const Measure minimalFontSize( 4, KDChartEnums::MeasureCalculationModeAbsolute );
112 
113  TextAttributes textAttrs;
114  textAttrs.setPen( QPen( Qt::black ) );
115  textAttrs.setFont( QFont( QLatin1String( "helvetica" ), 10, QFont::Normal, false ) );
116  textAttrs.setFontSize( normalFontSizeLabels );
117  textAttrs.setMinimalFontSize( minimalFontSize );
118  setTextAttributes( textAttrs );
119 
120  TextAttributes titleTextAttrs;
121  titleTextAttrs.setPen( QPen( Qt::black ) );
122  titleTextAttrs.setFont( QFont( QLatin1String( "helvetica" ), 12, QFont::Bold, false ) );
123  titleTextAttrs.setFontSize( normalFontSizeTitle );
124  titleTextAttrs.setMinimalFontSize( minimalFontSize );
125  setTitleTextAttributes( titleTextAttrs );
126 
127  FrameAttributes frameAttrs;
128  frameAttrs.setVisible( true );
129  frameAttrs.setPen( QPen( Qt::black ) );
130  frameAttrs.setPadding( 1 );
131  setFrameAttributes( frameAttrs );
132 
133  d->position = Position::NorthEast;
134  d->alignment = Qt::AlignCenter;
135 }
136 
137 
139 {
140  return sizeHint();
141 }
142 
143 //#define DEBUG_LEGEND_PAINT
144 
145 QSize Legend::sizeHint() const
146 {
147 #ifdef DEBUG_LEGEND_PAINT
148  qDebug() << "Legend::sizeHint() started";
149 #endif
150  Q_FOREACH( AbstractLayoutItem* paintItem, d->paintItems ) {
151  paintItem->sizeHint();
152  }
153  return AbstractAreaWidget::sizeHint();
154 }
155 
157 {
158  buildLegend();
159 }
160 
161 void Legend::resizeLayout( const QSize& size )
162 {
163 #ifdef DEBUG_LEGEND_PAINT
164  qDebug() << "Legend::resizeLayout started";
165 #endif
166  if ( d->layout ) {
167  d->reflowHDatasetItems( this );
168  d->layout->setGeometry( QRect(QPoint( 0,0 ), size) );
169  activateTheLayout();
170  }
171 #ifdef DEBUG_LEGEND_PAINT
172  qDebug() << "Legend::resizeLayout done";
173 #endif
174 }
175 
176 void Legend::activateTheLayout()
177 {
178  if ( d->layout && d->layout->parent() ) {
179  d->layout->activate();
180  }
181 }
182 
184 {
185  if ( d->legendStyle == style ) {
186  return;
187  }
188  d->legendStyle = style;
189  setNeedRebuild();
190 }
191 
193 {
194  return d->legendStyle;
195 }
196 
201 {
202  Legend* legend = new Legend( new Private( *d ), 0 );
203  legend->setTextAttributes( textAttributes() );
205  legend->setFrameAttributes( frameAttributes() );
207  legend->setPosition( position() );
208  legend->setAlignment( alignment() );
209  legend->setTextAlignment( textAlignment() );
210  legend->setLegendStyle( legendStyle() );
211  return legend;
212 }
213 
214 
215 bool Legend::compare( const Legend* other ) const
216 {
217  if ( other == this ) {
218  return true;
219  }
220  if ( !other ) {
221  return false;
222  }
223 
224  return ( AbstractAreaBase::compare( other ) ) &&
225  (isVisible() == other->isVisible()) &&
226  (position() == other->position()) &&
227  (alignment() == other->alignment())&&
228  (textAlignment() == other->textAlignment())&&
229  (floatingPosition() == other->floatingPosition()) &&
230  (orientation() == other->orientation())&&
231  (showLines() == other->showLines())&&
232  (texts() == other->texts())&&
233  (brushes() == other->brushes())&&
234  (pens() == other->pens())&&
235  (markerAttributes() == other->markerAttributes())&&
237  (textAttributes() == other->textAttributes()) &&
238  (titleText() == other->titleText())&&
239  (titleTextAttributes() == other->titleTextAttributes()) &&
240  (spacing() == other->spacing()) &&
241  (legendStyle() == other->legendStyle());
242 }
243 
244 
245 void Legend::paint( QPainter* painter )
246 {
247 #ifdef DEBUG_LEGEND_PAINT
248  qDebug() << "entering Legend::paint( QPainter* painter )";
249 #endif
250  if ( !diagram() ) {
251  return;
252  }
253 
254  activateTheLayout();
255 
256  Q_FOREACH( AbstractLayoutItem* paintItem, d->paintItems ) {
257  paintItem->paint( painter );
258  }
259 
260 #ifdef DEBUG_LEGEND_PAINT
261  qDebug() << "leaving Legend::paint( QPainter* painter )";
262 #endif
263 }
264 
265 
267 {
268  int modelLabelsCount = 0;
269  KDAB_FOREACH ( DiagramObserver* observer, d->observers ) {
270  AbstractDiagram* diagram = observer->diagram();
271  Q_ASSERT( diagram->datasetLabels().count() == diagram->datasetBrushes().count() );
272  modelLabelsCount += diagram->datasetLabels().count();
273  }
274  return modelLabelsCount;
275 }
276 
277 
279 {
280  if ( area == d->referenceArea ) {
281  return;
282  }
283  d->referenceArea = area;
284  setNeedRebuild();
285 }
286 
288 {
289  return d->referenceArea ? d->referenceArea : qobject_cast< const QWidget* >( parent() );
290 }
291 
292 
294 {
295  if ( d->observers.isEmpty() ) {
296  return 0;
297  }
298  return d->observers.first()->diagram();
299 }
300 
302 {
303  DiagramList list;
304  for ( int i = 0; i < d->observers.size(); ++i ) {
305  list << d->observers.at(i)->diagram();
306  }
307  return list;
308 }
309 
311 {
312  ConstDiagramList list;
313  for ( int i = 0; i < d->observers.size(); ++i ) {
314  list << d->observers.at(i)->diagram();
315  }
316  return list;
317 }
318 
320 {
321  if ( newDiagram ) {
322  DiagramObserver* observer = new DiagramObserver( newDiagram, this );
323 
324  DiagramObserver* oldObs = d->findObserverForDiagram( newDiagram );
325  if ( oldObs ) {
326  delete oldObs;
327  d->observers[ d->observers.indexOf( oldObs ) ] = observer;
328  } else {
329  d->observers.append( observer );
330  }
331  connect( observer, SIGNAL( diagramAboutToBeDestroyed(AbstractDiagram*) ),
332  SLOT( resetDiagram(AbstractDiagram*) ));
333  connect( observer, SIGNAL( diagramDataChanged(AbstractDiagram*) ),
334  SLOT( setNeedRebuild() ));
335  connect( observer, SIGNAL( diagramDataHidden(AbstractDiagram*) ),
336  SLOT( setNeedRebuild() ));
337  connect( observer, SIGNAL( diagramAttributesChanged(AbstractDiagram*) ),
338  SLOT( setNeedRebuild() ));
339  setNeedRebuild();
340  }
341 }
342 
344 {
345  int datasetBrushOffset = 0;
347  for ( int i = 0; i <diagrams.count(); i++ ) {
348  if ( diagrams.at( i ) == oldDiagram ) {
349  for ( int i = 0; i < oldDiagram->datasetBrushes().count(); i++ ) {
350  d->brushes.remove(datasetBrushOffset + i);
351  d->texts.remove(datasetBrushOffset + i);
352  }
353  for ( int i = 0; i < oldDiagram->datasetPens().count(); i++ ) {
354  d->pens.remove(datasetBrushOffset + i);
355  }
356  break;
357  }
358  datasetBrushOffset += diagrams.at(i)->datasetBrushes().count();
359  }
360 
361  if ( oldDiagram ) {
362  DiagramObserver *oldObs = d->findObserverForDiagram( oldDiagram );
363  if ( oldObs ) {
364  delete oldObs;
365  d->observers.removeAt( d->observers.indexOf( oldObs ) );
366  }
367  setNeedRebuild();
368  }
369 }
370 
372 {
373  // removeDiagram() may change the d->observers list. So, build up the list of
374  // diagrams to remove first and then remove them one by one.
376  for ( int i = 0; i < d->observers.size(); ++i ) {
377  diagrams.append( d->observers.at( i )->diagram() );
378  }
379  for ( int i = 0; i < diagrams.count(); ++i ) {
380  removeDiagram( diagrams[ i ] );
381  }
382 }
383 
385  AbstractDiagram* oldDiagram )
386 {
387  AbstractDiagram* old = oldDiagram;
388  if ( !d->observers.isEmpty() && !old ) {
389  old = d->observers.first()->diagram();
390  if ( !old ) {
391  d->observers.removeFirst(); // first entry had a 0 diagram
392  }
393  }
394  if ( old ) {
395  removeDiagram( old );
396  }
397  if ( newDiagram ) {
398  addDiagram( newDiagram );
399  }
400 }
401 
403 {
404  uint offset = 0;
405 
406  for ( int i = 0; i < d->observers.count(); ++i ) {
407  if ( d->observers.at(i)->diagram() == diagram ) {
408  return offset;
409  }
410  AbstractDiagram* diagram = d->observers.at(i)->diagram();
411  if ( !diagram->model() ) {
412  continue;
413  }
414  offset = offset + diagram->model()->columnCount();
415  }
416 
417  return offset;
418 }
419 
421 {
422  replaceDiagram( newDiagram );
423 }
424 
425 void Legend::resetDiagram( AbstractDiagram* oldDiagram )
426 {
427  removeDiagram( oldDiagram );
428 }
429 
430 void Legend::setVisible( bool visible )
431 {
432  // do NOT bail out if visible == isVisible(), because the return value of isVisible() also depends
433  // on the visibility of the parent.
434  QWidget::setVisible( visible );
435  emitPositionChanged();
436 }
437 
438 void Legend::setNeedRebuild()
439 {
440  buildLegend();
441  sizeHint();
442 }
443 
445 {
446  if ( d->position == position ) {
447  return;
448  }
449  d->position = position;
450  emitPositionChanged();
451 }
452 
453 void Legend::emitPositionChanged()
454 {
455  emit positionChanged( this );
456  emit propertiesChanged();
457 }
458 
459 
461 {
462  return d->position;
463 }
464 
465 void Legend::setAlignment( Qt::Alignment alignment )
466 {
467  if ( d->alignment == alignment ) {
468  return;
469  }
470  d->alignment = alignment;
471  emitPositionChanged();
472 }
473 
474 Qt::Alignment Legend::alignment() const
475 {
476  return d->alignment;
477 }
478 
479 void Legend::setTextAlignment( Qt::Alignment alignment )
480 {
481  if ( d->textAlignment == alignment ) {
482  return;
483  }
484  d->textAlignment = alignment;
485  emitPositionChanged();
486 }
487 
488 Qt::Alignment Legend::textAlignment() const
489 {
490  return d->textAlignment;
491 }
492 
493 void Legend::setLegendSymbolAlignment( Qt::Alignment alignment )
494 {
495  if ( d->legendLineSymbolAlignment == alignment ) {
496  return;
497  }
498  d->legendLineSymbolAlignment = alignment;
499  emitPositionChanged();
500 }
501 
502 Qt::Alignment Legend::legendSymbolAlignment() const
503 {
504  return d->legendLineSymbolAlignment ;
505 }
506 
507 void Legend::setFloatingPosition( const RelativePosition& relativePosition )
508 {
509  d->position = Position::Floating;
510  if ( d->relativePosition != relativePosition ) {
511  d->relativePosition = relativePosition;
512  emitPositionChanged();
513  }
514 }
515 
517 {
518  return d->relativePosition;
519 }
520 
521 void Legend::setOrientation( Qt::Orientation orientation )
522 {
523  if ( d->orientation == orientation ) {
524  return;
525  }
526  d->orientation = orientation;
527  setNeedRebuild();
528  emitPositionChanged();
529 }
530 
531 Qt::Orientation Legend::orientation() const
532 {
533  return d->orientation;
534 }
535 
536 void Legend::setSortOrder( Qt::SortOrder order )
537 {
538  if ( d->order == order ) {
539  return;
540  }
541  d->order = order;
542  setNeedRebuild();
543  emitPositionChanged();
544 }
545 
546 Qt::SortOrder Legend::sortOrder() const
547 {
548  return d->order;
549 }
550 
551 void Legend::setShowLines( bool legendShowLines )
552 {
553  if ( d->showLines == legendShowLines ) {
554  return;
555  }
556  d->showLines = legendShowLines;
557  setNeedRebuild();
558  emitPositionChanged();
559 }
560 
561 bool Legend::showLines() const
562 {
563  return d->showLines;
564 }
565 
566 void Legend::setUseAutomaticMarkerSize( bool useAutomaticMarkerSize )
567 {
568  d->useAutomaticMarkerSize = useAutomaticMarkerSize;
569  setNeedRebuild();
570  emitPositionChanged();
571 }
572 
574 {
575  return d->useAutomaticMarkerSize;
576 }
577 
584 {
585  if ( !d->texts.count() ) {
586  return;
587  }
588  d->texts.clear();
589  setNeedRebuild();
590 }
591 
592 void Legend::setText( uint dataset, const QString& text )
593 {
594  if ( d->texts[ dataset ] == text ) {
595  return;
596  }
597  d->texts[ dataset ] = text;
598  setNeedRebuild();
599 }
600 
601 QString Legend::text( uint dataset ) const
602 {
603  if ( d->texts.find( dataset ) != d->texts.end() ) {
604  return d->texts[ dataset ];
605  } else {
606  return d->modelLabels[ dataset ];
607  }
608 }
609 
611 {
612  return d->texts;
613 }
614 
615 void Legend::setColor( uint dataset, const QColor& color )
616 {
617  if ( d->brushes[ dataset ] != color ) {
618  d->brushes[ dataset ] = color;
619  setNeedRebuild();
620  update();
621  }
622 }
623 
624 void Legend::setBrush( uint dataset, const QBrush& brush )
625 {
626  if ( d->brushes[ dataset ] != brush ) {
627  d->brushes[ dataset ] = brush;
628  setNeedRebuild();
629  update();
630  }
631 }
632 
633 QBrush Legend::brush( uint dataset ) const
634 {
635  if ( d->brushes.contains( dataset ) ) {
636  return d->brushes[ dataset ];
637  } else {
638  return d->modelBrushes[ dataset ];
639  }
640 }
641 
643 {
644  return d->brushes;
645 }
646 
647 
649 {
650  bool changed = false;
651  QList<QBrush> datasetBrushes = diagram->datasetBrushes();
652  for ( int i = 0; i < datasetBrushes.count(); i++ ) {
653  if ( d->brushes[ i ] != datasetBrushes[ i ] ) {
654  d->brushes[ i ] = datasetBrushes[ i ];
655  changed = true;
656  }
657  }
658  if ( changed ) {
659  setNeedRebuild();
660  update();
661  }
662 }
663 
664 
665 void Legend::setPen( uint dataset, const QPen& pen )
666 {
667  if ( d->pens[dataset] == pen ) {
668  return;
669  }
670  d->pens[dataset] = pen;
671  setNeedRebuild();
672  update();
673 }
674 
675 QPen Legend::pen( uint dataset ) const
676 {
677  if ( d->pens.find( dataset ) != d->pens.end() ) {
678  return d->pens[ dataset ];
679  } else {
680  return d->modelPens[ dataset ];
681  }
682 }
683 
685 {
686  return d->pens;
687 }
688 
689 
690 void Legend::setMarkerAttributes( uint dataset, const MarkerAttributes& markerAttributes )
691 {
692  if ( d->markerAttributes[dataset] == markerAttributes ) {
693  return;
694  }
695  d->markerAttributes[ dataset ] = markerAttributes;
696  setNeedRebuild();
697  update();
698 }
699 
701 {
702  if ( d->markerAttributes.find( dataset ) != d->markerAttributes.end() ) {
703  return d->markerAttributes[ dataset ];
704  } else if ( static_cast<uint>( d->modelMarkers.count() ) > dataset ) {
705  return d->modelMarkers[ dataset ];
706  } else {
707  return MarkerAttributes();
708  }
709 }
710 
712 {
713  return d->markerAttributes;
714 }
715 
716 
718 {
719  if ( d->textAttributes == a ) {
720  return;
721  }
722  d->textAttributes = a;
723  setNeedRebuild();
724 }
725 
727 {
728  return d->textAttributes;
729 }
730 
731 void Legend::setTitleText( const QString& text )
732 {
733  if ( d->titleText == text ) {
734  return;
735  }
736  d->titleText = text;
737  setNeedRebuild();
738 }
739 
740 QString Legend::titleText() const
741 {
742  return d->titleText;
743 }
744 
746 {
747  if ( d->titleTextAttributes == a ) {
748  return;
749  }
750  d->titleTextAttributes = a;
751  setNeedRebuild();
752 }
753 
755 {
756  return d->titleTextAttributes;
757 }
758 
760 {
761 #ifdef DEBUG_LEGEND_PAINT
762  qDebug() << "entering Legend::forceRebuild()";
763 #endif
764  buildLegend();
765 #ifdef DEBUG_LEGEND_PAINT
766  qDebug() << "leaving Legend::forceRebuild()";
767 #endif
768 }
769 
770 void Legend::setSpacing( uint space )
771 {
772  if ( d->spacing == space && d->layout->spacing() == int( space ) ) {
773  return;
774  }
775  d->spacing = space;
776  d->layout->setSpacing( space );
777  setNeedRebuild();
778 }
779 
780 uint Legend::spacing() const
781 {
782  return d->spacing;
783 }
784 
786 {
788  for ( int i = 0; i < pal.size(); i++ ) {
789  setBrush( i, pal.getBrush( i ) );
790  }
791 }
792 
794 {
796  for ( int i = 0; i < pal.size(); i++ ) {
797  setBrush( i, pal.getBrush( i ) );
798  }
799 }
800 
801 void Legend::setSubduedColors( bool ordered )
802 {
804  if ( ordered ) {
805  for ( int i = 0; i < pal.size(); i++ ) {
806  setBrush( i, pal.getBrush( i ) );
807  }
808  } else {
809  static const int s_subduedColorsCount = 18;
810  Q_ASSERT( pal.size() >= s_subduedColorsCount );
811  static const int order[ s_subduedColorsCount ] = {
812  0, 5, 10, 15, 2, 7, 12, 17, 4,
813  9, 14, 1, 6, 11, 16, 3, 8, 13
814  };
815  for ( int i = 0; i < s_subduedColorsCount; i++ ) {
816  setBrush( i, pal.getBrush( order[i] ) );
817  }
818  }
819 }
820 
821 void Legend::resizeEvent( QResizeEvent * event )
822 {
823  Q_UNUSED( event );
824 #ifdef DEBUG_LEGEND_PAINT
825  qDebug() << "Legend::resizeEvent() called";
826 #endif
827  forceRebuild();
828  sizeHint();
829  QTimer::singleShot( 0, this, SLOT(emitPositionChanged()) );
830 }
831 
832 void Legend::Private::fetchPaintOptions( Legend *q )
833 {
834  modelLabels.clear();
835  modelBrushes.clear();
836  modelPens.clear();
837  modelMarkers.clear();
838  // retrieve the diagrams' settings for all non-hidden datasets
839  for ( int i = 0; i < observers.size(); ++i ) {
840  const AbstractDiagram* diagram = observers.at( i )->diagram();
841  if ( !diagram ) {
842  continue;
843  }
844  const QStringList diagramLabels = diagram->datasetLabels();
845  const QList<QBrush> diagramBrushes = diagram->datasetBrushes();
846  const QList<QPen> diagramPens = diagram->datasetPens();
847  const QList<MarkerAttributes> diagramMarkers = diagram->datasetMarkers();
848 
849  const bool ascend = q->sortOrder() == Qt::AscendingOrder;
850  int dataset = ascend ? 0 : diagramLabels.count() - 1;
851  const int end = ascend ? diagramLabels.count() : -1;
852  for ( ; dataset != end; dataset += ascend ? 1 : -1 ) {
853  if ( diagram->isHidden( dataset ) || q->datasetIsHidden( dataset ) ) {
854  continue;
855  }
856  modelLabels += diagramLabels[ dataset ];
857  modelBrushes += diagramBrushes[ dataset ];
858  modelPens += diagramPens[ dataset ];
859  modelMarkers += diagramMarkers[ dataset ];
860  }
861  }
862 
863  Q_ASSERT( modelLabels.count() == modelBrushes.count() );
864 }
865 
866 QSizeF Legend::Private::markerSize( Legend *q, int dataset, qreal fontHeight ) const
867 {
868  QSizeF suppliedSize = q->markerAttributes( dataset ).markerSize();
869  if ( q->useAutomaticMarkerSize() || !suppliedSize.isValid() ) {
870  return QSizeF( fontHeight, fontHeight );
871  } else {
872  return suppliedSize;
873  }
874 }
875 
876 QSizeF Legend::Private::maxMarkerSize( Legend *q, qreal fontHeight ) const
877 {
878  QSizeF ret( 1.0, 1.0 );
879  if ( q->legendStyle() != LinesOnly ) {
880  for ( int dataset = 0; dataset < modelLabels.count(); ++dataset ) {
881  ret = ret.expandedTo( markerSize( q, dataset, fontHeight ) );
882  }
883  }
884  return ret;
885 }
886 
887 HDatasetItem::HDatasetItem()
888  : markerLine(0),
889  label(0),
890  separatorLine(0),
891  spacer(0)
892 {}
893 
895 {
896  while ( w ) {
897  if ( w->isTopLevel() ) {
898  // The null check has proved necessary during destruction of the Legend / Chart
899  if ( w->layout() ) {
900  w->layout()->update();
901  }
902  break;
903  } else {
904  w = qobject_cast< QWidget * >( w->parent() );
905  Q_ASSERT( w );
906  }
907  }
908 }
909 
910 void Legend::buildLegend()
911 {
912  /* Grid layout partitioning (horizontal orientation): row zero is the title, row one the divider
913  line between title and dataset items, row two for each item: line, marker, text label and separator
914  line in that order.
915  In a vertically oriented legend, row pairs (2, 3), ... contain a possible separator line (first row)
916  and (second row) line, marker, text label each. */
917  d->destroyOldLayout();
918 
919  if ( orientation() == Qt::Vertical ) {
920  d->layout->setColumnStretch( 6, 1 );
921  } else {
922  d->layout->setColumnStretch( 6, 0 );
923  }
924 
925  d->fetchPaintOptions( this );
926 
927  const KDChartEnums::MeasureOrientation measureOrientation =
930 
931  // legend caption
932  if ( !titleText().isEmpty() && titleTextAttributes().isVisible() ) {
933  TextLayoutItem* titleItem =
935  measureOrientation, d->textAlignment );
936  titleItem->setParentWidget( this );
937 
938  d->paintItems << titleItem;
939  d->layout->addItem( titleItem, 0, 0, 1, 5, Qt::AlignCenter );
940 
941  // The line between the title and the legend items, if any.
942  if ( showLines() && d->modelLabels.count() ) {
944  d->paintItems << lineItem;
945  d->layout->addItem( lineItem, 1, 0, 1, 5, Qt::AlignCenter );
946  }
947  }
948 
949  qreal fontHeight = textAttributes().calculatedFontSize( referenceArea(), measureOrientation );
950  {
951  QFont tmpFont = textAttributes().font();
952  tmpFont.setPointSizeF( fontHeight );
954  fontHeight = QFontMetricsF( tmpFont, GlobalMeasureScaling::paintDevice() ).height();
955  } else {
956  fontHeight = QFontMetricsF( tmpFont ).height();
957  }
958  }
959 
960  const QSizeF maxMarkerSize = d->maxMarkerSize( this, fontHeight );
961 
962  // If we show a marker on a line, we paint it after 8 pixels
963  // of the line have been painted. This allows to see the line style
964  // at the right side of the marker without the line needing to
965  // be too long.
966  // (having the marker in the middle of the line would require longer lines)
967  const int lineLengthLeftOfMarker = 8;
968 
969  int maxLineLength = 18;
970  {
971  bool hasComplexPenStyle = false;
972  for ( int dataset = 0; dataset < d->modelLabels.count(); ++dataset ) {
973  const QPen pn = pen( dataset );
974  const Qt::PenStyle ps = pn.style();
975  if ( ps != Qt::NoPen ) {
976  maxLineLength = qMax( pn.width() * 18, maxLineLength );
977  if ( ps != Qt::SolidLine ) {
978  hasComplexPenStyle = true;
979  }
980  }
981  }
982  if ( hasComplexPenStyle && legendStyle() != LinesOnly ) {
983  maxLineLength += lineLengthLeftOfMarker + int( maxMarkerSize.width() );
984  }
985  }
986 
987  // for all datasets: add (line)marker items and text items to the layout;
988  // actual layout happens in flowHDatasetItems() for horizontal layout, here for vertical
989  for ( int dataset = 0; dataset < d->modelLabels.count(); ++dataset ) {
990  const int vLayoutRow = 2 + dataset * 2;
991  HDatasetItem dsItem;
992 
993  // It is possible to set the marker brush through markerAttributes as well as
994  // the dataset brush set in the diagram - the markerAttributes have higher precedence.
995  MarkerAttributes markerAttrs = markerAttributes( dataset );
996  markerAttrs.setMarkerSize( d->markerSize( this, dataset, fontHeight ) );
997  const QBrush markerBrush = markerAttrs.markerColor().isValid() ?
998  QBrush( markerAttrs.markerColor() ) : brush( dataset );
999 
1000  switch ( legendStyle() ) {
1001  case MarkersOnly:
1002  dsItem.markerLine = new MarkerLayoutItem( diagram(), markerAttrs, markerBrush,
1003  markerAttrs.pen(), Qt::AlignLeft | Qt::AlignVCenter );
1004  break;
1005  case LinesOnly:
1006  dsItem.markerLine = new LineLayoutItem( diagram(), maxLineLength, pen( dataset ),
1007  d->legendLineSymbolAlignment, Qt::AlignCenter );
1008  break;
1009  case MarkersAndLines:
1010  dsItem.markerLine = new LineWithMarkerLayoutItem(
1011  diagram(), maxLineLength, pen( dataset ), lineLengthLeftOfMarker, markerAttrs,
1012  markerBrush, markerAttrs.pen(), Qt::AlignCenter );
1013  break;
1014  default:
1015  Q_ASSERT( false );
1016  }
1017 
1018  dsItem.label = new TextLayoutItem( text( dataset ), textAttributes(), referenceArea(),
1019  measureOrientation, d->textAlignment );
1020  dsItem.label->setParentWidget( this );
1021 
1022  // horizontal layout is deferred to flowDatasetItems()
1023 
1024  if ( orientation() == Qt::Horizontal ) {
1025  d->hLayoutDatasets << dsItem;
1026  continue;
1027  }
1028 
1029  // (actual) vertical layout here
1030 
1031  if ( dsItem.markerLine ) {
1032  d->layout->addItem( dsItem.markerLine, vLayoutRow, 1, 1, 1, Qt::AlignCenter );
1033  d->paintItems << dsItem.markerLine;
1034  }
1035  d->layout->addItem( dsItem.label, vLayoutRow, 3, 1, 1, Qt::AlignLeft | Qt::AlignVCenter );
1036  d->paintItems << dsItem.label;
1037 
1038  // horizontal separator line, only between items
1039  if ( showLines() && dataset != d->modelLabels.count() - 1 ) {
1041  d->layout->addItem( lineItem, vLayoutRow + 1, 0, 1, 5, Qt::AlignCenter );
1042  d->paintItems << lineItem;
1043  }
1044  }
1045 
1046  if ( orientation() == Qt::Horizontal ) {
1047  d->flowHDatasetItems( this );
1048  }
1049 
1050  // vertical line (only in vertical mode)
1051  if ( orientation() == Qt::Vertical && showLines() && d->modelLabels.count() ) {
1053  d->paintItems << lineItem;
1054  d->layout->addItem( lineItem, 2, 2, d->modelLabels.count() * 2, 1 );
1055  }
1056 
1057  updateToplevelLayout( this );
1058 
1059  emit propertiesChanged();
1060 #ifdef DEBUG_LEGEND_PAINT
1061  qDebug() << "leaving Legend::buildLegend()";
1062 #endif
1063 }
1064 
1065 int HDatasetItem::height() const
1066 {
1067  return qMax( markerLine->sizeHint().height(), label->sizeHint().height() );
1068 }
1069 
1070 void Legend::Private::reflowHDatasetItems( Legend *q )
1071 {
1072  if (hLayoutDatasets.isEmpty()) {
1073  return;
1074  }
1075 
1076  paintItems.clear();
1077  // Dissolve exactly the QHBoxLayout(s) created as "currentLine" in flowHDatasetItems - don't remove the
1078  // caption and line under the caption! Those are easily identified because they aren't QLayouts.
1079  for ( int i = layout->count() - 1; i >= 0; i-- ) {
1080  QLayoutItem *const item = layout->itemAt( i );
1081  QLayout *const hbox = item->layout();
1082  if ( !hbox ) {
1083  AbstractLayoutItem *alItem = dynamic_cast< AbstractLayoutItem * >( item );
1084  Q_ASSERT( alItem );
1085  paintItems << alItem;
1086  continue;
1087  }
1088  Q_ASSERT( dynamic_cast< QHBoxLayout * >( hbox ) );
1089  layout->takeAt( i );
1090  // detach children so they aren't deleted with the parent
1091  for ( int j = hbox->count() - 1; j >= 0; j-- ) {
1092  hbox->takeAt( j );
1093  }
1094  delete hbox;
1095  }
1096 
1097  flowHDatasetItems( q );
1098 }
1099 
1100 // this works pretty much like flow layout for text, and it is only applicable to dataset items
1101 // laid out horizontally
1102 void Legend::Private::flowHDatasetItems( Legend *q )
1103 {
1104  const int separatorLineWidth = 3; // hardcoded in VerticalLineLayoutItem::sizeHint()
1105 
1106  const int allowedWidth = q->areaGeometry().width();
1107 
1108  QHBoxLayout *currentLine = new QHBoxLayout;
1109  int mainLayoutRow = 1;
1110  layout->addItem( currentLine, mainLayoutRow++, /*column*/0,
1111  /*rowSpan*/1 , /*columnSpan*/5, Qt::AlignLeft | Qt::AlignVCenter );
1112 
1113  for ( int dataset = 0; dataset < hLayoutDatasets.size(); dataset++ ) {
1114  HDatasetItem *hdsItem = &hLayoutDatasets[ dataset ];
1115 
1116  bool spacerUsed = false;
1117  bool separatorUsed = false;
1118  if ( !currentLine->isEmpty() ) {
1119  const int separatorWidth = ( q->showLines() ? separatorLineWidth : 0 ) + q->spacing();
1120  const int payloadWidth = hdsItem->markerLine->sizeHint().width() +
1121  hdsItem->label->sizeHint().width();
1122  if ( currentLine->sizeHint().width() + separatorWidth + payloadWidth > allowedWidth ) {
1123  // too wide, "line break"
1124 #ifdef DEBUG_LEGEND_PAINT
1125  qDebug() << Q_FUNC_INFO << "break" << mainLayoutRow
1126  << currentLine->sizeHint().width()
1127  << currentLine->sizeHint().width() + separatorWidth + payloadWidth
1128  << allowedWidth;
1129 #endif
1130  currentLine = new QHBoxLayout;
1131  layout->addItem( currentLine, mainLayoutRow++, /*column*/0,
1132  /*rowSpan*/1 , /*columnSpan*/5, Qt::AlignLeft | Qt::AlignVCenter );
1133  } else {
1134  // > 1 dataset item in line, put spacing and maybe a separator between them
1135  if ( !hdsItem->spacer ) {
1136  hdsItem->spacer = new QSpacerItem( q->spacing(), 1 );
1137  }
1138  currentLine->addItem( hdsItem->spacer );
1139  spacerUsed = true;
1140 
1141  if ( q->showLines() ) {
1142  if ( !hdsItem->separatorLine ) {
1143  hdsItem->separatorLine = new VerticalLineLayoutItem;
1144  }
1145  paintItems << hdsItem->separatorLine;
1146  currentLine->addItem( hdsItem->separatorLine );
1147  separatorUsed = true;
1148  }
1149  }
1150  }
1151  // those have no parents in the current layout, so they wouldn't get cleaned up otherwise
1152  if ( !spacerUsed ) {
1153  delete hdsItem->spacer;
1154  hdsItem->spacer = 0;
1155  }
1156  if ( !separatorUsed ) {
1157  delete hdsItem->separatorLine;
1158  hdsItem->separatorLine = 0;
1159  }
1160 
1161  currentLine->addItem( hdsItem->markerLine );
1162  paintItems << hdsItem->markerLine;
1163  currentLine->addItem( hdsItem->label );
1164  paintItems << hdsItem->label;
1165  }
1166 }
1167 
1169 {
1170  // this is better than using orientation() because, for layout purposes, we're not height-for-width
1171  // *yet* before buildLegend() has been called, and the layout logic might get upset if we say
1172  // something that will only be true in the future
1173  return !d->hLayoutDatasets.isEmpty();
1174 }
1175 
1176 int Legend::heightForWidth( int width ) const
1177 {
1178  if ( d->hLayoutDatasets.isEmpty() ) {
1179  return -1;
1180  }
1181 
1182  int ret = 0;
1183  // space for caption and line under caption (if any)
1184  for (int i = 0; i < 2; i++) {
1185  if ( QLayoutItem *item = d->layout->itemAtPosition( i, 0 ) ) {
1186  ret += item->sizeHint().height();
1187  }
1188  }
1189  const int separatorLineWidth = 3; // ### hardcoded in VerticalLineLayoutItem::sizeHint()
1190 
1191  int currentLineWidth = 0;
1192  int currentLineHeight = 0;
1193  Q_FOREACH( const HDatasetItem &hdsItem, d->hLayoutDatasets ) {
1194  const int payloadWidth = hdsItem.markerLine->sizeHint().width() +
1195  hdsItem.label->sizeHint().width();
1196  if ( !currentLineWidth ) {
1197  // first iteration
1198  currentLineWidth = payloadWidth;
1199  } else {
1200  const int separatorWidth = ( showLines() ? separatorLineWidth : 0 ) + spacing();
1201  currentLineWidth += separatorWidth + payloadWidth;
1202  if ( currentLineWidth > width ) {
1203  // too wide, "line break"
1204 #ifdef DEBUG_LEGEND_PAINT
1205  qDebug() << Q_FUNC_INFO << "heightForWidth break" << currentLineWidth
1206  << currentLineWidth + separatorWidth + payloadWidth
1207  << width;
1208 #endif
1209  ret += currentLineHeight + spacing();
1210  currentLineWidth = payloadWidth;
1211  currentLineHeight = 0;
1212  }
1213  }
1214  currentLineHeight = qMax( currentLineHeight, hdsItem.height() );
1215  }
1216  ret += currentLineHeight; // one less spacings than lines
1217  return ret;
1218 }
1219 
1220 void Legend::Private::destroyOldLayout()
1221 {
1222  // in the horizontal layout case, the QHBoxLayout destructor also deletes child layout items
1223  // (it isn't documented that QLayoutItems delete their children)
1224  for ( int i = layout->count() - 1; i >= 0; i-- ) {
1225  delete layout->takeAt( i );
1226  }
1227  Q_ASSERT( !layout->count() );
1228  hLayoutDatasets.clear();
1229  paintItems.clear();
1230 }
1231 
1232 void Legend::setHiddenDatasets( const QList<uint> hiddenDatasets )
1233 {
1234  d->hiddenDatasets = hiddenDatasets;
1235 }
1236 
1238 {
1239  return d->hiddenDatasets;
1240 }
1241 
1242 void Legend::setDatasetHidden( uint dataset, bool hidden )
1243 {
1244  if ( hidden && !d->hiddenDatasets.contains( dataset ) ) {
1245  d->hiddenDatasets.append( dataset );
1246  } else if ( !hidden && d->hiddenDatasets.contains( dataset ) ) {
1247  d->hiddenDatasets.removeAll( dataset );
1248  }
1249 }
1250 
1251 bool Legend::datasetIsHidden( uint dataset ) const
1252 {
1253  return d->hiddenDatasets.contains( dataset );
1254 }
KDChart::GlobalMeasureScaling::paintDevice
static QPaintDevice * paintDevice()
Return the paint device to use for calculating font metrics.
Definition: KDChartMeasure.cpp:227
KDChart::Legend::Legend
Legend(QWidget *parent=0)
Definition: KDChartLegend.cpp:81
KDChart::DiagramObserver
A DiagramObserver watches the associated diagram for changes and deletion and emits corresponsing sig...
Definition: KDChartDiagramObserver.h:45
KDChart::Legend::setLegendSymbolAlignment
void setLegendSymbolAlignment(Qt::Alignment)
Specify the alignment of the legend symbol( alignment of Legend::LinesOnly) within the legend.
Definition: KDChartLegend.cpp:493
KDChart::FrameAttributes::setVisible
void setVisible(bool visible)
Definition: KDChartFrameAttributes.cpp:88
QWidget
Class only listed here to document inheritance of some KDChart classes.
KDChart::Legend::alignment
Qt::Alignment alignment() const
Returns the alignment of a non-floating legend.
Definition: KDChartLegend.cpp:474
KDChart::Position::Floating
static const Position & Floating
Definition: KDChartPosition.h:111
KDChart::Position
Defines a position, using compass terminology.
Definition: KDChartPosition.h:76
KDChart::MarkerAttributes
A set of attributes controlling the appearance of data set markers.
Definition: KDChartMarkerAttributes.h:44
KDChart::AbstractDiagram::datasetPens
QList< QPen > datasetPens() const
The set of dataset pens currently used, for use in legends, etc.
Definition: KDChartAbstractDiagram.cpp:916
KDChartDiagramObserver.h
KDChart::Legend::text
QString text(uint dataset) const
Definition: KDChartLegend.cpp:601
KDChart::Legend::LegendStyle
LegendStyle
Definition: KDChartLegend.h:68
QList
Definition: KDChartPosition.h:36
KDChart::Legend::resizeLayout
void resizeLayout(const QSize &size) override
Definition: KDChartLegend.cpp:161
KDChart::Legend::datasetCount
uint datasetCount() const
Definition: KDChartLegend.cpp:266
KDChart::Legend::titleText
QString titleText() const
Definition: KDChartLegend.cpp:740
KDChart::PositionPoints
Stores the absolute target points of a Position.
Definition: KDChartPosition.h:146
KDChart::AbstractAreaBase::setFrameAttributes
void setFrameAttributes(const FrameAttributes &a)
Definition: KDChartAbstractAreaBase.cpp:88
KDChart::Legend::setReferenceArea
void setReferenceArea(const QWidget *area)
Specifies the reference area for font size of title text, and for font size of the item texts,...
Definition: KDChartLegend.cpp:278
KDChart::AbstractAreaWidget
An area in the chart with a background, a frame, etc.
Definition: KDChartAbstractAreaWidget.h:45
KDTextDocument.h
updateToplevelLayout
static void updateToplevelLayout(QWidget *w)
Definition: KDChartLegend.cpp:894
KDChart::Legend::spacing
uint spacing() const
Definition: KDChartLegend.cpp:780
KDChart::Legend::needSizeHint
void needSizeHint() override
Call this to trigger an conditional re-building of the widget's internals.
Definition: KDChartLegend.cpp:156
KDChart::Legend::setFloatingPosition
void setFloatingPosition(const RelativePosition &relativePosition)
Definition: KDChartLegend.cpp:507
KDChart::MarkerLayoutItem
Layout item showing a data point marker.
Definition: KDChartLayoutItems.h:220
KDChart::MarkerAttributes::markerSize
QSizeF markerSize() const
Definition: KDChartMarkerAttributes.cpp:157
KDChart::Legend::LinesOnly
@ LinesOnly
Definition: KDChartLegend.h:69
KDChart::Legend::paint
void paint(QPainter *painter) override
Overwrite this to paint the inner contents of your widget.
Definition: KDChartLegend.cpp:245
KDChart::AbstractAreaBase::frameAttributes
FrameAttributes frameAttributes() const
Definition: KDChartAbstractAreaBase.cpp:97
KDChart::Palette::defaultPalette
static const Palette & defaultPalette()
Provide access to the three builtin palettes, one with standard bright colors, one with more subdued ...
Definition: KDChartPalette.cpp:107
KDChart::Legend::compare
bool compare(const Legend *other) const
Returns true if both legends have the same settings.
Definition: KDChartLegend.cpp:215
KDChart::Legend::propertiesChanged
void propertiesChanged()
Emitted upon change of a property of the Legend or any of its components.
KDChart::Legend::diagrams
DiagramList diagrams() const
The list of all diagrams associated with the legend.
Definition: KDChartLegend.cpp:301
KDChart::AbstractDiagram::datasetBrushes
QList< QBrush > datasetBrushes() const
The set of dataset brushes currently used, for use in legends, etc.
Definition: KDChartAbstractDiagram.cpp:903
KDChart::Legend::setSubduedColors
void setSubduedColors(bool ordered=false)
Definition: KDChartLegend.cpp:801
KDChart::Legend::orientation
Qt::Orientation orientation() const
Definition: KDChartLegend.cpp:531
KDChart
Definition: KDChartAbstractCartesianDiagram.h:30
KDChart::Legend::diagram
KDChart::AbstractDiagram * diagram() const
The first diagram of the legend or 0 if there was none added to the legend.
Definition: KDChartLegend.cpp:293
KDChart::Legend::sizeHint
QSize sizeHint() const override
Definition: KDChartLegend.cpp:145
KDChart::Legend::setPen
void setPen(uint dataset, const QPen &pen)
Definition: KDChartLegend.cpp:665
d
#define d
Definition: KDChartLegend.cpp:78
KDChart::AbstractAreaWidget::positionChanged
void positionChanged(AbstractAreaWidget *)
KDChart::Legend::setUseAutomaticMarkerSize
void setUseAutomaticMarkerSize(bool useAutomaticMarkerSize)
This option is on by default, it means that Marker sizes in the Legend will be the same as the font h...
Definition: KDChartLegend.cpp:566
KDChart::AbstractDiagram::isHidden
bool isHidden() const
Retrieve the hidden status specified globally.
Definition: KDChartAbstractDiagram.cpp:278
KDChart::Legend::brushes
const QMap< uint, QBrush > brushes() const
Definition: KDChartLegend.cpp:642
KDChart::Legend::pens
const QMap< uint, QPen > pens() const
Definition: KDChartLegend.cpp:684
KDChart::Legend::pen
QPen pen(uint dataset) const
Definition: KDChartLegend.cpp:675
KDChartEnums::MeasureOrientationHorizontal
@ MeasureOrientationHorizontal
Definition: KDChartEnums.h:291
KDChartLegend.h
KDChart::Legend::legendStyle
LegendStyle legendStyle() const
Definition: KDChartLegend.cpp:192
KDChart::Legend::setBrush
void setBrush(uint dataset, const QBrush &brush)
Definition: KDChartLegend.cpp:624
KDChart::TextAttributes
A set of text attributes.
Definition: KDChartTextAttributes.h:47
KDChart::Measure
Measure is used to specify relative and absolute sizes in KDChart, e.g.
Definition: KDChartMeasure.h:52
KDChart::FrameAttributes::setPen
void setPen(const QPen &pen)
Definition: KDChartFrameAttributes.cpp:98
KDChart::AbstractLayoutItem::setParentWidget
virtual void setParentWidget(QWidget *widget)
Inform the item about its widget: This enables the item, to trigger that widget's update,...
Definition: KDChartLayoutItems.cpp:59
KDChart::Legend::brush
QBrush brush(uint dataset) const
Definition: KDChartLegend.cpp:633
KDChart::Legend::setMarkerAttributes
void setMarkerAttributes(uint dataset, const MarkerAttributes &)
Note that any sizes specified via setMarkerAttributes are ignored, unless you disable the automatic s...
Definition: KDChartLegend.cpp:690
KDChart::AbstractAreaWidget::areaGeometry
QRect areaGeometry() const override
Definition: KDChartAbstractAreaWidget.cpp:179
KDChart::TextAttributes::setMinimalFontSize
void setMinimalFontSize(const Measure &measure)
Set the minimal size of the font used for rendering text.
Definition: KDChartTextAttributes.cpp:150
KDChart::Palette::getBrush
QBrush getBrush(int position) const
Query the palette for a brush at the specified position.
Definition: KDChartPalette.cpp:172
KDChart::Legend::legendSymbolAlignment
Qt::Alignment legendSymbolAlignment() const
Returns the alignment used while drawing legend symbol(alignment of Legend::LinesOnly) within the leg...
Definition: KDChartLegend.cpp:502
KDChart::VerticalLineLayoutItem
Layout item showing a vertial line.
Definition: KDChartLayoutItems.h:360
KDChart::Palette::subduedPalette
static const Palette & subduedPalette()
Definition: KDChartPalette.cpp:113
KDChart::Legend::setTextAlignment
void setTextAlignment(Qt::Alignment)
Specify the alignment of the text elements within the legend.
Definition: KDChartLegend.cpp:479
KDChart::AbstractDiagram::datasetMarkers
QList< MarkerAttributes > datasetMarkers() const
The set of dataset markers currently used, for use in legends, etc.
Definition: KDChartAbstractDiagram.cpp:929
KDChart::Legend::setLegendStyle
void setLegendStyle(LegendStyle style)
Definition: KDChartLegend.cpp:183
KDChartMarkerAttributes.h
KDChart::Legend::setTitleTextAttributes
void setTitleTextAttributes(const TextAttributes &a)
Definition: KDChartLegend.cpp:745
KDChart::Legend::useAutomaticMarkerSize
bool useAutomaticMarkerSize() const
Definition: KDChartLegend.cpp:573
KDChart::Legend::~Legend
~Legend() override
Definition: KDChartLegend.cpp:96
KDChart::RelativePosition
Defines relative position information: reference area, position in this area (reference position),...
Definition: KDChartRelativePosition.h:58
KDChart::Legend::setRainbowColors
void setRainbowColors()
Definition: KDChartLegend.cpp:793
KDChart::Legend::markerAttributes
const QMap< uint, MarkerAttributes > markerAttributes() const
Definition: KDChartLegend.cpp:711
KDChart::AbstractLayoutItem::paint
virtual void paint(QPainter *)=0
KDChartAbstractDiagram.h
KDChart::Legend::destroyedLegend
void destroyedLegend(Legend *)
KDChartEnums::MeasureCalculationModeAbsolute
@ MeasureCalculationModeAbsolute
Definition: KDChartEnums.h:222
KDChart::Legend::markerAttributes
MarkerAttributes markerAttributes(uint dataset) const
Definition: KDChartLegend.cpp:700
KDChart::Palette::rainbowPalette
static const Palette & rainbowPalette()
Definition: KDChartPalette.cpp:119
KDChart::Legend::referenceArea
const QWidget * referenceArea() const
Returns the reference area, that is used for font size of title text, and for font size of the item t...
Definition: KDChartLegend.cpp:287
KDChart::Position::NorthEast
static const Position & NorthEast
Definition: KDChartPosition.h:104
KDChart::Legend::constDiagrams
ConstDiagramList constDiagrams() const
Definition: KDChartLegend.cpp:310
KDChart::Position::NorthWest
static const Position & NorthWest
Definition: KDChartPosition.h:102
KDChartPalette.h
KDChart::LineLayoutItem
Layout item showing a coloured line.
Definition: KDChartLayoutItems.h:259
KDChart::Legend::setDefaultColors
void setDefaultColors()
Definition: KDChartLegend.cpp:785
KDChart::LineWithMarkerLayoutItem
Layout item showing a coloured line and a data point marker.
Definition: KDChartLayoutItems.h:299
KDChart::Legend::addDiagram
void addDiagram(KDChart::AbstractDiagram *newDiagram)
Add the given diagram to the legend.
Definition: KDChartLegend.cpp:319
KDChart::TextAttributes::setFontSize
void setFontSize(const Measure &measure)
Set the size of the font used for rendering text.
Definition: KDChartTextAttributes.cpp:140
KDChart::Legend::setBrushesFromDiagram
void setBrushesFromDiagram(KDChart::AbstractDiagram *diagram)
Definition: KDChartLegend.cpp:648
KDChartLayoutItems.h
KDChart::Legend::setPosition
void setPosition(Position position)
Specify the position of a non-floating legend.
Definition: KDChartLegend.cpp:444
KDChart::Legend::heightForWidth
int heightForWidth(int width) const override
Definition: KDChartLegend.cpp:1176
KDChartEnums::MeasureOrientation
MeasureOrientation
Measure orientation mode: the way how the absolute value of a KDChart::Measure is determined during K...
Definition: KDChartEnums.h:290
KDChart::Legend::setHiddenDatasets
void setHiddenDatasets(const QList< uint > hiddenDatasets)
Sets a list of datasets that are to be hidden in the legend.
Definition: KDChartLegend.cpp:1232
KDChart::DiagramObserver::diagram
const AbstractDiagram * diagram() const
Definition: KDChartDiagramObserver.cpp:48
KDChart::AbstractDiagram
AbstractDiagram defines the interface for diagram classes.
Definition: KDChartAbstractDiagram.h:51
KDChart::Legend::removeDiagram
void removeDiagram(KDChart::AbstractDiagram *oldDiagram)
Removes the diagram from the legend's list of diagrams.
Definition: KDChartLegend.cpp:343
KDChart::MarkerAttributes::markerColor
QColor markerColor() const
Definition: KDChartMarkerAttributes.cpp:167
KDChart::Legend::resizeEvent
void resizeEvent(QResizeEvent *event) override
Definition: KDChartLegend.cpp:821
KDChart::Legend::minimumSizeHint
QSize minimumSizeHint() const override
Definition: KDChartLegend.cpp:138
KDChart::Legend::setDatasetHidden
void setDatasetHidden(uint dataset, bool hidden)
Definition: KDChartLegend.cpp:1242
KDChart::Legend::floatingPosition
const RelativePosition floatingPosition() const
Returns the position of a floating legend.
Definition: KDChartLegend.cpp:516
KDChart::Legend::sortOrder
Qt::SortOrder sortOrder() const
Definition: KDChartLegend.cpp:546
KDChart::Legend
Legend defines the interface for the legend drawing class.
Definition: KDChartLegend.h:56
KDChart::Legend::resetTexts
void resetTexts()
Removes all legend texts that might have been set by setText.
Definition: KDChartLegend.cpp:583
KDChart::FrameAttributes::setPadding
void setPadding(int padding)
Definition: KDChartFrameAttributes.cpp:118
KDChart::FrameAttributes
A set of attributes for frames around items.
Definition: KDChartFrameAttributes.h:37
KDChart::Legend::setOrientation
void setOrientation(Qt::Orientation orientation)
Definition: KDChartLegend.cpp:521
KDChart::Legend::setDiagram
void setDiagram(KDChart::AbstractDiagram *newDiagram)
A convenience method doing the same as replaceDiagram( newDiagram, 0 );.
Definition: KDChartLegend.cpp:420
KDChart::Legend::clone
virtual Legend * clone() const
Creates an exact copy of this legend.
Definition: KDChartLegend.cpp:200
KDChart::Legend::setTextAttributes
void setTextAttributes(const TextAttributes &a)
Definition: KDChartLegend.cpp:717
KDChart::Palette
A Palette is a set of brushes (or colors) to be used for painting data sets.
Definition: KDChartPalette.h:50
KDChart::Palette::size
int size() const
Definition: KDChartPalette.cpp:157
KDChartTextAttributes.h
KDChart::Legend::hasHeightForWidth
bool hasHeightForWidth() const
Definition: KDChartLegend.cpp:1168
KDChart::Legend::replaceDiagram
void replaceDiagram(KDChart::AbstractDiagram *newDiagram, KDChart::AbstractDiagram *oldDiagram=0)
Replaces the old diagram, or appends the new diagram, it there is none yet.
Definition: KDChartLegend.cpp:384
KDChart::Legend::removeDiagrams
void removeDiagrams()
Removes all diagrams from the legend's list of diagrams.
Definition: KDChartLegend.cpp:371
KDChart::HorizontalLineLayoutItem
Layout item showing a horizontal line.
Definition: KDChartLayoutItems.h:337
KDChart::TextAttributes::setPen
void setPen(const QPen &pen)
Set the pen to use for rendering the text.
Definition: KDChartTextAttributes.cpp:256
KDChart::AbstractAreaBase::compare
bool compare(const AbstractAreaBase *other) const
Returns true if both areas have the same settings.
Definition: KDChartAbstractAreaBase.cpp:71
KDChart::TextLayoutItem
Layout item showing a text.
Definition: KDChartLayoutItems.h:100
KDChart::Legend::titleTextAttributes
TextAttributes titleTextAttributes() const
Definition: KDChartLegend.cpp:754
QMap
Definition: KDChartMarkerAttributes.h:35
KDChart::Legend::MarkersOnly
@ MarkersOnly
Definition: KDChartLegend.h:68
KDChart::Legend::setSpacing
void setSpacing(uint space)
Definition: KDChartLegend.cpp:770
KDChart::Legend::forceRebuild
void forceRebuild() override
Call this to trigger an unconditional re-building of the widget's internals.
Definition: KDChartLegend.cpp:759
KDChart::Legend::setSortOrder
void setSortOrder(Qt::SortOrder order)
Definition: KDChartLegend.cpp:536
KDChart::AbstractLayoutItem
Base class for all layout items of KD Chart.
Definition: KDChartLayoutItems.h:52
KDChart::Legend::textAttributes
TextAttributes textAttributes() const
Definition: KDChartLegend.cpp:726
QObject
KDChart::Legend::datasetIsHidden
bool datasetIsHidden(uint dataset) const
Definition: KDChartLegend.cpp:1251
KDChart::TextAttributes::setFont
void setFont(const QFont &font)
Set the font to be used for rendering the text.
Definition: KDChartTextAttributes.cpp:128
KDChart::Legend::showLines
bool showLines() const
Definition: KDChartLegend.cpp:561
KDChart::Legend::setColor
void setColor(uint dataset, const QColor &color)
Note: there is no color() getter method, since setColor just sets a QBrush with the respective color,...
Definition: KDChartLegend.cpp:615
KDChart::Legend::setText
void setText(uint dataset, const QString &text)
Definition: KDChartLegend.cpp:592
KDChart::Legend::setVisible
void setVisible(bool visible) override
Definition: KDChartLegend.cpp:430
KDChart::Legend::textAlignment
Qt::Alignment textAlignment() const
Returns the alignment used while rendering text elements within the legend.
Definition: KDChartLegend.cpp:488
KDChart::Legend::setShowLines
void setShowLines(bool legendShowLines)
Definition: KDChartLegend.cpp:551
KDChart::MarkerAttributes::pen
QPen pen() const
Definition: KDChartMarkerAttributes.cpp:187
KDChart::Legend::texts
const QMap< uint, QString > texts() const
Definition: KDChartLegend.cpp:610
KDChart::Legend::MarkersAndLines
@ MarkersAndLines
Definition: KDChartLegend.h:70
QLayoutItem
Class only listed here to document inheritance of some KDChart classes.
KDChart::TextAttributes::font
QFont font() const
Definition: KDChartTextAttributes.cpp:135
KDChart::Legend::hiddenDatasets
const QList< uint > hiddenDatasets() const
Definition: KDChartLegend.cpp:1237
KDChartEnums::MeasureOrientationMinimum
@ MeasureOrientationMinimum
Definition: KDChartEnums.h:293
KDChart::Legend::setTitleText
void setTitleText(const QString &text)
Definition: KDChartLegend.cpp:731
KDChart::AbstractDiagram::datasetLabels
QStringList datasetLabels() const
The set of dataset labels currently displayed, for use in legends, etc.
Definition: KDChartAbstractDiagram.cpp:890
KDChart::Legend::dataSetOffset
uint dataSetOffset(KDChart::AbstractDiagram *diagram)
Returns the offset of the first dataset of diagram.
Definition: KDChartLegend.cpp:402
KDChart::TextAttributes::calculatedFontSize
qreal calculatedFontSize(const QSizeF &referenceSize, KDChartEnums::MeasureOrientation autoReferenceOrientation) const
Returns the font size that is used at drawing time.
Definition: KDChartTextAttributes.cpp:166
KDChart::Legend::setAlignment
void setAlignment(Qt::Alignment)
Specify the alignment of a non-floating legend.
Definition: KDChartLegend.cpp:465
KDChart::MarkerAttributes::setMarkerSize
void setMarkerSize(const QSizeF &size)
Normally you need to specify a valid QSizeF here, but for Legends you can use the invalid size QSizeF...
Definition: KDChartMarkerAttributes.cpp:152
KDChart::Legend::position
Position position() const
Returns the position of a non-floating legend.
Definition: KDChartLegend.cpp:460

Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/

https://www.kdab.com/development-resources/qt-tools/kd-chart/