KD Chart 2  [rev.2.7]
KDChartBarDiagram.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2020 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 "KDChartBarDiagram.h"
24 #include "KDChartBarDiagram_p.h"
25 
27 #include "KDChartPosition.h"
28 #include "KDChartAttributesModel.h"
29 #include "KDChartAbstractGrid.h"
30 #include "KDChartPainterSaver_p.h"
31 
32 #include <QPainter>
33 #include <QDebug>
34 
35 #include <KDABLibFakes>
36 
37 #include "KDChartNormalBarDiagram_p.h"
38 #include "KDChartStackedBarDiagram_p.h"
39 #include "KDChartPercentBarDiagram_p.h"
40 #include "KDChartNormalLyingBarDiagram_p.h"
41 #include "KDChartStackedLyingBarDiagram_p.h"
42 #include "KDChartPercentLyingBarDiagram_p.h"
43 
44 
45 using namespace KDChart;
46 
47 BarDiagram::Private::Private()
48  : orientation( Qt::Vertical )
49  , implementor( 0 )
50  , normalDiagram( 0 )
51  , stackedDiagram( 0 )
52  , percentDiagram( 0 )
53  , normalLyingDiagram( 0 )
54  , stackedLyingDiagram( 0 )
55  , percentLyingDiagram( 0 )
56 {
57 }
58 
59 BarDiagram::Private::~Private()
60 {
61  delete normalDiagram;
62  delete stackedDiagram;
63  delete percentDiagram;
64  delete normalLyingDiagram;
65  delete stackedLyingDiagram;
66  delete percentLyingDiagram;
67 }
68 
69 void BarDiagram::Private::setOrientationAndType( Qt::Orientation o, BarDiagram::BarType type )
70 {
71  if ( orientation == o && implementor->type() == type ) {
72  return;
73  }
74  BarDiagram *barDia = qobject_cast< BarDiagram * >( diagram );
75 
76  orientation = o;
77 
78  if ( orientation == Qt::Vertical ) {
79  switch ( type ) {
80  case Normal:
81  implementor = normalDiagram;
82  break;
83  case Stacked:
84  implementor = stackedDiagram;
85  break;
86  case Percent:
87  implementor = percentDiagram;
88  break;
89  default:
90  Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
91  }
92  } else {
93  switch ( type ) {
94  case Normal:
95  implementor = normalLyingDiagram;
96  break;
97  case Stacked:
98  implementor = stackedLyingDiagram;
99  break;
100  case Percent:
101  implementor = percentLyingDiagram;
102  break;
103  default:
104  Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
105  }
106  }
107 
108  Q_ASSERT( implementor->type() == type );
109 
110  // AbstractAxis settings - see AbstractDiagram and CartesianAxis
111  barDia->setPercentMode( type == BarDiagram::Percent );
112  barDia->setDataBoundariesDirty();
113  emit barDia->layoutChanged( barDia );
114  emit barDia->propertiesChanged();
115 }
116 
117 #define d d_func()
118 
119 
121  AbstractCartesianDiagram( new Private(), parent, plane )
122 {
123  init();
124 }
125 
126 void BarDiagram::init()
127 {
128  d->normalDiagram = new NormalBarDiagram( this );
129  d->stackedDiagram = new StackedBarDiagram( this );
130  d->percentDiagram = new PercentBarDiagram( this );
131  d->normalLyingDiagram = new NormalLyingBarDiagram( this );
132  d->stackedLyingDiagram = new StackedLyingBarDiagram( this );
133  d->percentLyingDiagram = new PercentLyingBarDiagram( this );
134  d->implementor = d->normalDiagram;
135  d->compressor.setModel( attributesModel() );
136 }
137 
139 {
140 }
141 
146 {
147 
148  BarDiagram* newDiagram = new BarDiagram( new Private( *d ) );
149  newDiagram->setType( type() );
150  return newDiagram;
151 }
152 
153 bool BarDiagram::compare( const BarDiagram* other ) const
154 {
155  if ( other == this ) return true;
156  if ( ! other ) {
157  return false;
158  }
159 
160  return // compare the base class
161  ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
162  // compare own properties
163  (type() == other->type());
164 }
165 
170 void BarDiagram::setType( const BarType type )
171 {
172  d->setOrientationAndType( d->orientation, type );
173 }
174 
179 {
180  return d->implementor->type();
181 }
182 
186 void BarDiagram::setOrientation( Qt::Orientation orientation )
187 {
188  d->setOrientationAndType( orientation, d->implementor->type() );
189 }
190 
194 Qt::Orientation BarDiagram::orientation() const
195 {
196  return d->orientation;
197 }
198 
203 {
204  d->attributesModel->setModelData( qVariantFromValue( ba ), BarAttributesRole );
205  emit propertiesChanged();
206 }
207 
211 void BarDiagram::setBarAttributes( int column, const BarAttributes& ba )
212 {
213  d->setDatasetAttrs( column, qVariantFromValue( ba ), BarAttributesRole );
214  emit propertiesChanged();
215 }
216 
220 void BarDiagram::setBarAttributes( const QModelIndex& index, const BarAttributes& ba )
221 {
223  d->attributesModel->mapFromSource( index ),
224  qVariantFromValue( ba ),
226  emit propertiesChanged();
227 }
228 
233 {
234  return d->attributesModel->data( KDChart::BarAttributesRole ).value<BarAttributes>();
235 }
236 
241 {
242  const QVariant attrs( d->datasetAttrs( column, KDChart::BarAttributesRole ) );
243  if ( attrs.isValid() )
244  return attrs.value<BarAttributes>();
245  return barAttributes();
246 }
247 
251 BarAttributes BarDiagram::barAttributes( const QModelIndex& index ) const
252 {
253  return d->attributesModel->data(
254  d->attributesModel->mapFromSource( index ),
255  KDChart::BarAttributesRole ).value<BarAttributes>();
256 }
257 
262 {
264  d->attributesModel->setModelData( qVariantFromValue( threeDAttrs ), ThreeDBarAttributesRole );
265  emit layoutChanged( this );
266  emit propertiesChanged();
267 }
268 
272 void BarDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes& threeDAttrs )
273 {
275  d->setDatasetAttrs( column, qVariantFromValue( threeDAttrs ), ThreeDBarAttributesRole );
276  //emit layoutChanged( this );
277  emit propertiesChanged();
278 }
279 
283 void BarDiagram::setThreeDBarAttributes( const QModelIndex& index, const ThreeDBarAttributes& threeDAttrs )
284 {
286  d->attributesModel->setData(
287  d->attributesModel->mapFromSource(index),
288  qVariantFromValue( threeDAttrs ),
290  //emit layoutChanged( this );
291  emit propertiesChanged();
292 }
293 
298 {
299  return d->attributesModel->data( KDChart::ThreeDBarAttributesRole ).value<ThreeDBarAttributes>();
300 }
301 
306 {
307  const QVariant attrs( d->datasetAttrs( column, KDChart::ThreeDBarAttributesRole ) );
308  if ( attrs.isValid() )
309  return attrs.value<ThreeDBarAttributes>();
310  return threeDBarAttributes();
311 }
312 
316 ThreeDBarAttributes BarDiagram::threeDBarAttributes( const QModelIndex& index ) const
317 {
318  return d->attributesModel->data(
319  d->attributesModel->mapFromSource(index),
320  KDChart::ThreeDBarAttributesRole ).value<ThreeDBarAttributes>();
321 }
322 
323 qreal BarDiagram::threeDItemDepth( const QModelIndex& index ) const
324 {
325  return threeDBarAttributes( index ).validDepth();
326 }
327 
328 qreal BarDiagram::threeDItemDepth( int column ) const
329 {
330  return threeDBarAttributes( column ).validDepth();
331 }
332 
333 void BarDiagram::resizeEvent ( QResizeEvent*)
334 {
335 
336 }
337 
339 {
340  d->compressor.setResolution( static_cast<int>( this->size().width() * coordinatePlane()->zoomFactorX() ),
341  static_cast<int>( this->size().height() * coordinatePlane()->zoomFactorY() ) );
342 
343  if ( !checkInvariants( true ) ) {
344  return QPair< QPointF, QPointF >( QPointF( 0, 0 ), QPointF( 0, 0 ) );
345  }
346 
347  // note: calculateDataBoundaries() is ignoring the hidden flags.
348  // That's not a bug but a feature: Hiding data does not mean removing them.
349  // For totally removing data from KD Chart's view people can use e.g. a proxy model
350  // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
351  return d->implementor->calculateDataBoundaries();
352 }
353 
354 void BarDiagram::paintEvent ( QPaintEvent*)
355 {
356  QPainter painter ( viewport() );
357  PaintContext ctx;
358  ctx.setPainter ( &painter );
359  ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
360  paint ( &ctx );
361 }
362 
364 {
365  if ( !checkInvariants( true ) ) return;
366  if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
367  const PainterSaver p( ctx->painter() );
368  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
369  return; // nothing to paint for us
370 
371  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
372  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
373 
374  // This was intended as a fix for KDCH-515, however it caused KDCH-816
375  // and the original problem in KDCH-515 had by then been fixed in another way.
376  // Bottom line is, this code is wrong because the above call to
377  // plane->sharedAxisMasterPlane() performs a translation of the painter, which
378  // also translates the clip rect, so if we set the old clip rect again afterwards,
379  // we get a wrong clipping.
380  // Also, this code is unnecessary because CartesianCoordinatePlane::paint()
381  // already sets the clipping properly before calling this method.
382  // ctx->painter()->setClipping( true );
383  // ctx->painter()->setClipRect( ctx->rectangle() );
384 
385  // paint different bar types Normal - Stacked - Percent - Default Normal
386  d->implementor->paint( ctx );
387 
388  ctx->setCoordinatePlane( plane );
389 }
390 
391 void BarDiagram::resize( const QSizeF& size )
392 {
393  d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
394  static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
396  QAbstractItemView::resize( size.toSize() );
397 }
398 
399 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
400 const
401 #endif
403 {
404  return d->attributesModel->rowCount(attributesModelRootIndex());
405 }
406 
407 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
408 const
409 #endif
411 {
412  return d->attributesModel->columnCount(attributesModelRootIndex());
413 }
414 
415 //#undef d
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
[reimplemented]
virtual AbstractCoordinatePlane * sharedAxisMasterPlane(QPainter *p=0)
void paintEvent(QPaintEvent *) override
virtual BarDiagram * clone() const
Creates an exact copy of this diagram.
BarAttributes barAttributes() const
void setPainter(QPainter *painter)
virtual bool checkInvariants(bool justReturnTheStatus=false) const
AbstractCoordinatePlane * coordinatePlane() const
Set of attributes for changing the appearance of bar charts.
void setType(const BarType type)
Sets the bar diagram&#39;s type to type.
void setBarAttributes(const BarAttributes &a)
Sets the global bar attributes to ba.
void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
QPainter * painter() const
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
BarDiagram defines a common bar diagram.
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
[reimplemented]
qreal threeDItemDepth(const QModelIndex &index) const override
void paint(PaintContext *paintContext) override
Draw the diagram contents to the rectangle and painter, that are passed in as part of the paint conte...
void setThreeDBarAttributes(const ThreeDBarAttributes &a)
Sets the global 3D bar attributes to threeDAttrs.
BarDiagram(QWidget *parent=0, CartesianCoordinatePlane *plane=0)
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
bool compare(const BarDiagram *other) const
Returns true if both diagrams have the same settings.
void resizeEvent(QResizeEvent *) override
void propertiesChanged()
Emitted upon change of a property of the Diagram.
Qt::Orientation orientation() const
Base class for diagrams based on a cartesian coordianate system.
Stores information about painting diagrams.
A set of 3D bar attributes.
const int numberOfAbscissaSegments() const
[reimplemented]
const int numberOfOrdinateSegments() const
[reimplemented]
#define d
ThreeDBarAttributes threeDBarAttributes() const
void layoutChanged(AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes...
QModelIndex attributesModelRootIndex() const
void setCoordinatePlane(AbstractCoordinatePlane *plane)
void setRectangle(const QRectF &rect)
Class only listed here to document inheritance of some KDChart classes.
void resize(const QSizeF &area) override
Called by the widget&#39;s sizeEvent.
void setOrientation(Qt::Orientation orientation)
Sets the orientation of the bar diagram.

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/