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
30using namespace KChart;
31
32BarDiagram::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
44BarDiagram::Private::~Private()
45{
46 delete normalDiagram;
47 delete stackedDiagram;
48 delete percentDiagram;
49 delete normalLyingDiagram;
50 delete stackedLyingDiagram;
51 delete percentLyingDiagram;
52}
53
54void 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
105BarDiagram::BarDiagram( QWidget* parent, CartesianCoordinatePlane* plane ) :
106 AbstractCartesianDiagram( new Private(), parent, plane )
107{
108 init();
109}
110
111void 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
123BarDiagram::~BarDiagram()
124{
125}
126
128{
129
130 BarDiagram* newDiagram = new BarDiagram( new Private( *d ) );
131 newDiagram->setType( type() );
132 return newDiagram;
133}
134
135bool 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
148void 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
174void BarDiagram::setBarAttributes( int column, const BarAttributes& ba )
175{
176 d->setDatasetAttrs( column, QVariant::fromValue( ba ), BarAttributesRole );
178}
179
181{
183 d->attributesModel->mapFromSource( index ),
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
217void 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
256qreal BarDiagram::threeDItemDepth( const QModelIndex& index ) const
257{
258 return threeDBarAttributes( index ).validDepth();
259}
260
261qreal BarDiagram::threeDItemDepth( int column ) const
262{
263 return threeDBarAttributes( column ).validDepth();
264}
265
266void BarDiagram::resizeEvent ( QResizeEvent*)
267{
268
269}
270
271const QPair<QPointF, QPointF> BarDiagram::calculateDataBoundaries() const
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
287void 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
324void 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)
333const
334#endif
336{
337 return d->attributesModel->rowCount(attributesModelRootIndex());
338}
339
340#if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
341const
342#endif
344{
345 return d->attributesModel->columnCount(attributesModelRootIndex());
346}
347
348//#undef d
Base class for diagrams based on a cartesian coordianate system.
bool compare(const AbstractCartesianDiagram *other) const
Returns true if both diagrams have the same settings.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
QModelIndex attributesModelRootIndex() const
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
void propertiesChanged()
Emitted upon change of a property of the Diagram.
void layoutChanged(KChart::AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes.
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
static bool isBoundariesValid(const QRectF &r)
Checks whether both coordinates of r are valid according to isValueValid.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
\reimpl
Set of attributes for changing the appearance of bar charts.
BarDiagram defines a common bar diagram.
void setThreeDBarAttributes(const ThreeDBarAttributes &a)
Sets the global 3D bar attributes to threeDAttrs.
ThreeDBarAttributes threeDBarAttributes() const
int numberOfAbscissaSegments() const override
\reimpl
BarAttributes barAttributes() const
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
\reimpl
bool compare(const BarDiagram *other) const
Returns true if both diagrams have the same settings.
Qt::Orientation orientation() const
virtual BarDiagram * clone() const
Creates an exact copy of this diagram.
void setBarAttributes(const BarAttributes &a)
Sets the global bar attributes to ba.
void paint(PaintContext *paintContext) override
Draw the diagram contents to the rectangle and painter, that are passed in as part of the paint conte...
int numberOfOrdinateSegments() const override
\reimpl
void setOrientation(Qt::Orientation orientation)
Sets the orientation of the bar diagram.
void resize(const QSizeF &area) override
Called by the widget's sizeEvent.
void setType(const BarType type)
Sets the bar diagram's type to type.
qreal threeDItemDepth(const QModelIndex &index) const override
Stores information about painting diagrams.
A set of 3D bar attributes.
QCA_EXPORT void init()
QAbstractItemModel * model() const const
QModelIndex rootIndex() const const
QWidget * viewport() const const
Q_EMITQ_EMIT
Vertical
QVariant fromValue(T &&value)
bool isValid() const const
T value() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:02:46 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.