KChart

KChartBarDiagram.cpp
1 /*
2  * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "KChartBarDiagram.h"
10 #include "KChartBarDiagram_p.h"
11 
12 #include "KChartThreeDBarAttributes.h"
13 #include "KChartPosition.h"
14 #include "KChartAttributesModel.h"
15 #include "KChartAbstractGrid.h"
16 #include "KChartPainterSaver_p.h"
17 
18 #include <QPainter>
19 #include <QDebug>
20 
21 #include "KChartNormalBarDiagram_p.h"
22 #include "KChartStackedBarDiagram_p.h"
23 #include "KChartPercentBarDiagram_p.h"
24 #include "KChartNormalLyingBarDiagram_p.h"
25 #include "KChartStackedLyingBarDiagram_p.h"
26 #include "KChartPercentLyingBarDiagram_p.h"
27 #include "KChartMath_p.h"
28 
29 
30 using namespace KChart;
31 
32 BarDiagram::Private::Private()
33  : orientation( Qt::Vertical )
34  , implementor( nullptr )
35  , normalDiagram( nullptr )
36  , stackedDiagram( nullptr )
37  , percentDiagram( nullptr )
38  , normalLyingDiagram( nullptr )
39  , stackedLyingDiagram( nullptr )
40  , percentLyingDiagram( nullptr )
41 {
42 }
43 
44 BarDiagram::Private::~Private()
45 {
46  delete normalDiagram;
47  delete stackedDiagram;
48  delete percentDiagram;
49  delete normalLyingDiagram;
50  delete stackedLyingDiagram;
51  delete percentLyingDiagram;
52 }
53 
54 void BarDiagram::Private::setOrientationAndType( Qt::Orientation o, BarDiagram::BarType type )
55 {
56  if ( orientation == o && implementor->type() == type ) {
57  return;
58  }
59  BarDiagram *barDia = qobject_cast< BarDiagram * >( diagram );
60 
61  orientation = o;
62 
63  if ( orientation == Qt::Vertical ) {
64  switch ( type ) {
65  case Normal:
66  implementor = normalDiagram;
67  break;
68  case Stacked:
69  implementor = stackedDiagram;
70  break;
71  case Percent:
72  implementor = percentDiagram;
73  break;
74  default:
75  Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
76  }
77  } else {
78  switch ( type ) {
79  case Normal:
80  implementor = normalLyingDiagram;
81  break;
82  case Stacked:
83  implementor = stackedLyingDiagram;
84  break;
85  case Percent:
86  implementor = percentLyingDiagram;
87  break;
88  default:
89  Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
90  }
91  }
92 
93  Q_ASSERT( implementor->type() == type );
94 
95  // AbstractAxis settings - see AbstractDiagram and CartesianAxis
96  barDia->setPercentMode( type == BarDiagram::Percent );
97  barDia->setDataBoundariesDirty();
98  Q_EMIT barDia->layoutChanged( barDia );
99  Q_EMIT barDia->propertiesChanged();
100 }
101 
102 #define d d_func()
103 
104 
105 BarDiagram::BarDiagram( QWidget* parent, CartesianCoordinatePlane* plane ) :
106  AbstractCartesianDiagram( new Private(), parent, plane )
107 {
108  init();
109 }
110 
111 void BarDiagram::init()
112 {
113  d->normalDiagram = new NormalBarDiagram( this );
114  d->stackedDiagram = new StackedBarDiagram( this );
115  d->percentDiagram = new PercentBarDiagram( this );
116  d->normalLyingDiagram = new NormalLyingBarDiagram( this );
117  d->stackedLyingDiagram = new StackedLyingBarDiagram( this );
118  d->percentLyingDiagram = new PercentLyingBarDiagram( this );
119  d->implementor = d->normalDiagram;
120  d->compressor.setModel( attributesModel() );
121 }
122 
123 BarDiagram::~BarDiagram()
124 {
125 }
126 
128 {
129 
130  BarDiagram* newDiagram = new BarDiagram( new Private( *d ) );
131  newDiagram->setType( type() );
132  return newDiagram;
133 }
134 
135 bool BarDiagram::compare( const BarDiagram* other ) const
136 {
137  if ( other == this ) return true;
138  if ( ! other ) {
139  return false;
140  }
141 
142  return // compare the base class
143  ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
144  // compare own properties
145  (type() == other->type());
146 }
147 
148 void BarDiagram::setType( const BarType type )
149 {
150  d->setOrientationAndType( d->orientation, type );
151 }
152 
154 {
155  return d->implementor->type();
156 }
157 
159 {
160  d->setOrientationAndType( orientation, d->implementor->type() );
161 }
162 
164 {
165  return d->orientation;
166 }
167 
169 {
170  d->attributesModel->setModelData( QVariant::fromValue( ba ), BarAttributesRole );
172 }
173 
174 void BarDiagram::setBarAttributes( int column, const BarAttributes& ba )
175 {
176  d->setDatasetAttrs( column, QVariant::fromValue( ba ), BarAttributesRole );
178 }
179 
181 {
183  d->attributesModel->mapFromSource( index ),
184  QVariant::fromValue( ba ),
185  BarAttributesRole );
187 }
188 
190 {
191  return d->attributesModel->data( KChart::BarAttributesRole ).value<BarAttributes>();
192 }
193 
195 {
196  const QVariant attrs( d->datasetAttrs( column, KChart::BarAttributesRole ) );
197  if ( attrs.isValid() )
198  return attrs.value<BarAttributes>();
199  return barAttributes();
200 }
201 
203 {
204  return d->attributesModel->data(
205  d->attributesModel->mapFromSource( index ),
206  KChart::BarAttributesRole ).value<BarAttributes>();
207 }
208 
210 {
211  setDataBoundariesDirty();
212  d->attributesModel->setModelData( QVariant::fromValue( threeDAttrs ), ThreeDBarAttributesRole );
213  Q_EMIT layoutChanged( this );
215 }
216 
217 void BarDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes& threeDAttrs )
218 {
219  setDataBoundariesDirty();
220  d->setDatasetAttrs( column, QVariant::fromValue( threeDAttrs ), ThreeDBarAttributesRole );
221  //Q_EMIT layoutChanged( this );
223 }
224 
226 {
227  setDataBoundariesDirty();
228  d->attributesModel->setData(
229  d->attributesModel->mapFromSource(index),
230  QVariant::fromValue( threeDAttrs ),
231  ThreeDBarAttributesRole );
232  //Q_EMIT layoutChanged( this );
234 }
235 
237 {
238  return d->attributesModel->data( KChart::ThreeDBarAttributesRole ).value<ThreeDBarAttributes>();
239 }
240 
242 {
243  const QVariant attrs( d->datasetAttrs( column, KChart::ThreeDBarAttributesRole ) );
244  if ( attrs.isValid() )
245  return attrs.value<ThreeDBarAttributes>();
246  return threeDBarAttributes();
247 }
248 
250 {
251  return d->attributesModel->data(
252  d->attributesModel->mapFromSource(index),
253  KChart::ThreeDBarAttributesRole ).value<ThreeDBarAttributes>();
254 }
255 
256 qreal BarDiagram::threeDItemDepth( const QModelIndex& index ) const
257 {
258  return threeDBarAttributes( index ).validDepth();
259 }
260 
261 qreal BarDiagram::threeDItemDepth( int column ) const
262 {
263  return threeDBarAttributes( column ).validDepth();
264 }
265 
266 void BarDiagram::resizeEvent ( QResizeEvent*)
267 {
268 
269 }
270 
272 {
273  d->compressor.setResolution( static_cast<int>( this->size().width() * coordinatePlane()->zoomFactorX() ),
274  static_cast<int>( this->size().height() * coordinatePlane()->zoomFactorY() ) );
275 
276  if ( !checkInvariants( true ) ) {
277  return QPair< QPointF, QPointF >( QPointF( 0, 0 ), QPointF( 0, 0 ) );
278  }
279 
280  // note: calculateDataBoundaries() is ignoring the hidden flags.
281  // That's not a bug but a feature: Hiding data does not mean removing them.
282  // For totally removing data from KD Chart's view people can use e.g. a proxy model
283  // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
284  return d->implementor->calculateDataBoundaries();
285 }
286 
287 void BarDiagram::paintEvent ( QPaintEvent*)
288 {
289  QPainter painter ( viewport() );
290  PaintContext ctx;
291  ctx.setPainter ( &painter );
292  ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
293  paint ( &ctx );
294 }
295 
297 {
298  if ( !checkInvariants( true ) ) return;
300  const PainterSaver p( ctx->painter() );
301  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
302  return; // nothing to paint for us
303 
304  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
305  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
306 
307  // This was intended as a fix for KDCH-515, however it caused KDCH-816
308  // and the original problem in KDCH-515 had by then been fixed in another way.
309  // Bottom line is, this code is wrong because the above call to
310  // plane->sharedAxisMasterPlane() performs a translation of the painter, which
311  // also translates the clip rect, so if we set the old clip rect again afterwards,
312  // we get a wrong clipping.
313  // Also, this code is unnecessary because CartesianCoordinatePlane::paint()
314  // already sets the clipping properly before calling this method.
315  // ctx->painter()->setClipping( true );
316  // ctx->painter()->setClipRect( ctx->rectangle() );
317 
318  // paint different bar types Normal - Stacked - Percent - Default Normal
319  d->implementor->paint( ctx );
320 
321  ctx->setCoordinatePlane( plane );
322 }
323 
324 void BarDiagram::resize( const QSizeF& size )
325 {
326  d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
327  static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
328  setDataBoundariesDirty();
330 }
331 
332 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
333 const
334 #endif
336 {
337  return d->attributesModel->rowCount(attributesModelRootIndex());
338 }
339 
340 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
341 const
342 #endif
344 {
345  return d->attributesModel->columnCount(attributesModelRootIndex());
346 }
347 
348 //#undef d
qreal threeDItemDepth(const QModelIndex &index) const override
int numberOfOrdinateSegments() const override
\reimpl
Qt::Orientation orientation() const
BarType type() const
bool isValid() const const
int numberOfAbscissaSegments() const override
\reimpl
QVariant fromValue(const T &value)
Q_EMITQ_EMIT
QAbstractItemModel * model() const const
T value() const const
Class only listed here to document inheritance of some KChart classes.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
\reimpl
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
bool compare(const BarDiagram *other) const
Returns true if both diagrams have the same settings.
void propertiesChanged()
Emitted upon change of a property of the Diagram.
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
Stores information about painting diagrams.
ThreeDBarAttributes threeDBarAttributes() const
BarDiagram defines a common bar diagram.
void setType(const BarType type)
Sets the bar diagram's type to type.
BarAttributes barAttributes() const
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
void setOrientation(Qt::Orientation orientation)
Sets the orientation of the bar diagram.
Vertical
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 setBarAttributes(const BarAttributes &a)
Sets the global bar attributes to ba.
QModelIndex attributesModelRootIndex() const
QModelIndex rootIndex() const const
A set of 3D bar attributes.
void resize(const QSizeF &area) override
Called by the widget's sizeEvent.
virtual BarDiagram * clone() const
Creates an exact copy of this diagram.
static bool isBoundariesValid(const QRectF &r)
Checks whether both coordinates of r are valid according to isValueValid.
void init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
virtual void resize(const QSizeF &area)
Called by the widget's sizeEvent.
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
\reimpl
void setThreeDBarAttributes(const ThreeDBarAttributes &a)
Sets the global 3D bar attributes to threeDAttrs.
Set of attributes for changing the appearance of bar charts.
QWidget * viewport() const const
void layoutChanged(KChart::AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes.
Base class for diagrams based on a cartesian coordianate system.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Dec 4 2023 03:54:50 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.