KChart

KChartBarDiagram.cpp
1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "KChartBarDiagram.h"
21 #include "KChartBarDiagram_p.h"
22 
23 #include "KChartThreeDBarAttributes.h"
24 #include "KChartPosition.h"
25 #include "KChartAttributesModel.h"
26 #include "KChartAbstractGrid.h"
27 #include "KChartPainterSaver_p.h"
28 
29 #include <QPainter>
30 #include <QDebug>
31 
32 #include "KChartNormalBarDiagram_p.h"
33 #include "KChartStackedBarDiagram_p.h"
34 #include "KChartPercentBarDiagram_p.h"
35 #include "KChartNormalLyingBarDiagram_p.h"
36 #include "KChartStackedLyingBarDiagram_p.h"
37 #include "KChartPercentLyingBarDiagram_p.h"
38 #include "KChartMath_p.h"
39 
40 
41 using namespace KChart;
42 
43 BarDiagram::Private::Private()
44  : orientation( Qt::Vertical )
45  , implementor( nullptr )
46  , normalDiagram( nullptr )
47  , stackedDiagram( nullptr )
48  , percentDiagram( nullptr )
49  , normalLyingDiagram( nullptr )
50  , stackedLyingDiagram( nullptr )
51  , percentLyingDiagram( nullptr )
52 {
53 }
54 
55 BarDiagram::Private::~Private()
56 {
57  delete normalDiagram;
58  delete stackedDiagram;
59  delete percentDiagram;
60  delete normalLyingDiagram;
61  delete stackedLyingDiagram;
62  delete percentLyingDiagram;
63 }
64 
65 void BarDiagram::Private::setOrientationAndType( Qt::Orientation o, BarDiagram::BarType type )
66 {
67  if ( orientation == o && implementor->type() == type ) {
68  return;
69  }
70  BarDiagram *barDia = qobject_cast< BarDiagram * >( diagram );
71 
72  orientation = o;
73 
74  if ( orientation == Qt::Vertical ) {
75  switch ( type ) {
76  case Normal:
77  implementor = normalDiagram;
78  break;
79  case Stacked:
80  implementor = stackedDiagram;
81  break;
82  case Percent:
83  implementor = percentDiagram;
84  break;
85  default:
86  Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
87  }
88  } else {
89  switch ( type ) {
90  case Normal:
91  implementor = normalLyingDiagram;
92  break;
93  case Stacked:
94  implementor = stackedLyingDiagram;
95  break;
96  case Percent:
97  implementor = percentLyingDiagram;
98  break;
99  default:
100  Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
101  }
102  }
103 
104  Q_ASSERT( implementor->type() == type );
105 
106  // AbstractAxis settings - see AbstractDiagram and CartesianAxis
107  barDia->setPercentMode( type == BarDiagram::Percent );
108  barDia->setDataBoundariesDirty();
109  Q_EMIT barDia->layoutChanged( barDia );
110  Q_EMIT barDia->propertiesChanged();
111 }
112 
113 #define d d_func()
114 
115 
116 BarDiagram::BarDiagram( QWidget* parent, CartesianCoordinatePlane* plane ) :
117  AbstractCartesianDiagram( new Private(), parent, plane )
118 {
119  init();
120 }
121 
122 void BarDiagram::init()
123 {
124  d->normalDiagram = new NormalBarDiagram( this );
125  d->stackedDiagram = new StackedBarDiagram( this );
126  d->percentDiagram = new PercentBarDiagram( this );
127  d->normalLyingDiagram = new NormalLyingBarDiagram( this );
128  d->stackedLyingDiagram = new StackedLyingBarDiagram( this );
129  d->percentLyingDiagram = new PercentLyingBarDiagram( this );
130  d->implementor = d->normalDiagram;
131  d->compressor.setModel( attributesModel() );
132 }
133 
134 BarDiagram::~BarDiagram()
135 {
136 }
137 
139 {
140 
141  BarDiagram* newDiagram = new BarDiagram( new Private( *d ) );
142  newDiagram->setType( type() );
143  return newDiagram;
144 }
145 
146 bool BarDiagram::compare( const BarDiagram* other ) const
147 {
148  if ( other == this ) return true;
149  if ( ! other ) {
150  return false;
151  }
152 
153  return // compare the base class
154  ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
155  // compare own properties
156  (type() == other->type());
157 }
158 
159 void BarDiagram::setType( const BarType type )
160 {
161  d->setOrientationAndType( d->orientation, type );
162 }
163 
165 {
166  return d->implementor->type();
167 }
168 
170 {
171  d->setOrientationAndType( orientation, d->implementor->type() );
172 }
173 
175 {
176  return d->orientation;
177 }
178 
180 {
181  d->attributesModel->setModelData( QVariant::fromValue( ba ), BarAttributesRole );
182  Q_EMIT propertiesChanged();
183 }
184 
185 void BarDiagram::setBarAttributes( int column, const BarAttributes& ba )
186 {
187  d->setDatasetAttrs( column, QVariant::fromValue( ba ), BarAttributesRole );
188  Q_EMIT propertiesChanged();
189 }
190 
192 {
193  attributesModel()->setData(
194  d->attributesModel->mapFromSource( index ),
195  QVariant::fromValue( ba ),
196  BarAttributesRole );
197  Q_EMIT propertiesChanged();
198 }
199 
201 {
202  return d->attributesModel->data( KChart::BarAttributesRole ).value<BarAttributes>();
203 }
204 
206 {
207  const QVariant attrs( d->datasetAttrs( column, KChart::BarAttributesRole ) );
208  if ( attrs.isValid() )
209  return attrs.value<BarAttributes>();
210  return barAttributes();
211 }
212 
214 {
215  return d->attributesModel->data(
216  d->attributesModel->mapFromSource( index ),
217  KChart::BarAttributesRole ).value<BarAttributes>();
218 }
219 
221 {
222  setDataBoundariesDirty();
223  d->attributesModel->setModelData( QVariant::fromValue( threeDAttrs ), ThreeDBarAttributesRole );
224  Q_EMIT layoutChanged( this );
225  Q_EMIT propertiesChanged();
226 }
227 
228 void BarDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes& threeDAttrs )
229 {
230  setDataBoundariesDirty();
231  d->setDatasetAttrs( column, QVariant::fromValue( threeDAttrs ), ThreeDBarAttributesRole );
232  //emit layoutChanged( this );
233  Q_EMIT propertiesChanged();
234 }
235 
237 {
238  setDataBoundariesDirty();
239  d->attributesModel->setData(
240  d->attributesModel->mapFromSource(index),
241  QVariant::fromValue( threeDAttrs ),
242  ThreeDBarAttributesRole );
243  //emit layoutChanged( this );
244  Q_EMIT propertiesChanged();
245 }
246 
248 {
249  return d->attributesModel->data( KChart::ThreeDBarAttributesRole ).value<ThreeDBarAttributes>();
250 }
251 
253 {
254  const QVariant attrs( d->datasetAttrs( column, KChart::ThreeDBarAttributesRole ) );
255  if ( attrs.isValid() )
256  return attrs.value<ThreeDBarAttributes>();
257  return threeDBarAttributes();
258 }
259 
261 {
262  return d->attributesModel->data(
263  d->attributesModel->mapFromSource(index),
264  KChart::ThreeDBarAttributesRole ).value<ThreeDBarAttributes>();
265 }
266 
267 qreal BarDiagram::threeDItemDepth( const QModelIndex& index ) const
268 {
269  return threeDBarAttributes( index ).validDepth();
270 }
271 
272 qreal BarDiagram::threeDItemDepth( int column ) const
273 {
274  return threeDBarAttributes( column ).validDepth();
275 }
276 
277 void BarDiagram::resizeEvent ( QResizeEvent*)
278 {
279 
280 }
281 
283 {
284  d->compressor.setResolution( static_cast<int>( this->size().width() * coordinatePlane()->zoomFactorX() ),
285  static_cast<int>( this->size().height() * coordinatePlane()->zoomFactorY() ) );
286 
287  if ( !checkInvariants( true ) ) {
288  return QPair< QPointF, QPointF >( QPointF( 0, 0 ), QPointF( 0, 0 ) );
289  }
290 
291  // note: calculateDataBoundaries() is ignoring the hidden flags.
292  // That's not a bug but a feature: Hiding data does not mean removing them.
293  // For totally removing data from KD Chart's view people can use e.g. a proxy model
294  // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
295  return d->implementor->calculateDataBoundaries();
296 }
297 
298 void BarDiagram::paintEvent ( QPaintEvent*)
299 {
300  QPainter painter ( viewport() );
301  PaintContext ctx;
302  ctx.setPainter ( &painter );
303  ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
304  paint ( &ctx );
305 }
306 
308 {
309  if ( !checkInvariants( true ) ) return;
310  if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
311  const PainterSaver p( ctx->painter() );
312  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
313  return; // nothing to paint for us
314 
315  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
316  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
317 
318  // This was intended as a fix for KDCH-515, however it caused KDCH-816
319  // and the original problem in KDCH-515 had by then been fixed in another way.
320  // Bottom line is, this code is wrong because the above call to
321  // plane->sharedAxisMasterPlane() performs a translation of the painter, which
322  // also translates the clip rect, so if we set the old clip rect again afterwards,
323  // we get a wrong clipping.
324  // Also, this code is unnecessary because CartesianCoordinatePlane::paint()
325  // already sets the clipping properly before calling this method.
326  // ctx->painter()->setClipping( true );
327  // ctx->painter()->setClipRect( ctx->rectangle() );
328 
329  // paint different bar types Normal - Stacked - Percent - Default Normal
330  d->implementor->paint( ctx );
331 
332  ctx->setCoordinatePlane( plane );
333 }
334 
335 void BarDiagram::resize( const QSizeF& size )
336 {
337  d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
338  static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
339  setDataBoundariesDirty();
341 }
342 
343 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
344 const
345 #endif
347 {
348  return d->attributesModel->rowCount(attributesModelRootIndex());
349 }
350 
351 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
352 const
353 #endif
355 {
356  return d->attributesModel->columnCount(attributesModelRootIndex());
357 }
358 
359 //#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
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.
void layoutChanged(AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes...
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-2021 The KDE developers.
Generated on Wed Jan 20 2021 22:39:30 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.