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 );
171  Q_EMIT propertiesChanged();
172 }
173 
174 void BarDiagram::setBarAttributes( int column, const BarAttributes& ba )
175 {
176  d->setDatasetAttrs( column, QVariant::fromValue( ba ), BarAttributesRole );
177  Q_EMIT propertiesChanged();
178 }
179 
181 {
182  attributesModel()->setData(
183  d->attributesModel->mapFromSource( index ),
184  QVariant::fromValue( ba ),
185  BarAttributesRole );
186  Q_EMIT propertiesChanged();
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 );
214  Q_EMIT propertiesChanged();
215 }
216 
217 void BarDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes& threeDAttrs )
218 {
219  setDataBoundariesDirty();
220  d->setDatasetAttrs( column, QVariant::fromValue( threeDAttrs ), ThreeDBarAttributesRole );
221  //emit layoutChanged( this );
222  Q_EMIT propertiesChanged();
223 }
224 
226 {
227  setDataBoundariesDirty();
228  d->attributesModel->setData(
229  d->attributesModel->mapFromSource(index),
230  QVariant::fromValue( threeDAttrs ),
231  ThreeDBarAttributesRole );
232  //emit layoutChanged( this );
233  Q_EMIT propertiesChanged();
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;
299  if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) 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
Qt::Orientation orientation() const
void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
Class only listed here to document inheritance of some KChart classes.
static bool isBoundariesValid(const QRectF &r)
Checks whether both coordinates of r are valid according to isValueValid.
T value() const const
void layoutChanged(KChart::AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes...
ThreeDBarAttributes threeDBarAttributes() const
void propertiesChanged()
Emitted upon change of a property of the Diagram.
Set of attributes for changing the appearance of bar charts.
Stores information about painting diagrams.
void paint(PaintContext *paintContext) override
Draw the diagram contents to the rectangle and painter, that are passed in as part of the paint conte...
Base class for diagrams based on a cartesian coordianate system.
BarAttributes barAttributes() const
void setBarAttributes(const BarAttributes &a)
Sets the global bar attributes to ba.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane.
int numberOfOrdinateSegments() const override
int numberOfAbscissaSegments() const override
void setType(const BarType type)
Sets the bar diagram&#39;s type to type.
void resize(const QSizeF &area) override
Called by the widget&#39;s sizeEvent.
BarType type() const
QVariant fromValue(const T &value)
QCA_EXPORT void init()
void setThreeDBarAttributes(const ThreeDBarAttributes &a)
Sets the global 3D bar attributes to threeDAttrs.
virtual void resize(const QSizeF &area)
Called by the widget&#39;s sizeEvent.
virtual BarDiagram * clone() const
Creates an exact copy of this diagram.
BarDiagram defines a common bar diagram.
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
qreal threeDItemDepth(const QModelIndex &index) const override
void setOrientation(Qt::Orientation orientation)
Sets the orientation of the bar diagram.
Vertical
bool compare(const BarDiagram *other) const
Returns true if both diagrams have the same settings.
qreal height() const const
Global namespace.
A set of 3D bar attributes.
qreal width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jan 27 2022 22:33:22 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.