KD Chart API Documentation  3.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
KDChartBarDiagram.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** This file is part of the KD Chart library.
4 **
5 ** SPDX-FileCopyrightText: 2001 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6 **
7 ** SPDX-License-Identifier: MIT
8 **
9 ****************************************************************************/
10 
11 #include "KDChartBarDiagram.h"
12 #include "KDChartBarDiagram_p.h"
13 
14 #include "KDChartAbstractGrid.h"
15 #include "KDChartAttributesModel.h"
16 #include "KDChartPainterSaver_p.h"
17 #include "KDChartPosition.h"
19 
20 #include <QDebug>
21 #include <QPainter>
22 
23 #include <KDABLibFakes>
24 
25 #include "KDChartNormalBarDiagram_p.h"
26 #include "KDChartNormalLyingBarDiagram_p.h"
27 #include "KDChartPercentBarDiagram_p.h"
28 #include "KDChartPercentLyingBarDiagram_p.h"
29 #include "KDChartStackedBarDiagram_p.h"
30 #include "KDChartStackedLyingBarDiagram_p.h"
31 
32 using namespace KDChart;
33 
34 BarDiagram::Private::Private()
35 {
36 }
37 
38 BarDiagram::Private::~Private()
39 {
40  delete normalDiagram;
41  delete stackedDiagram;
42  delete percentDiagram;
43  delete normalLyingDiagram;
44  delete stackedLyingDiagram;
45  delete percentLyingDiagram;
46 }
47 
48 void BarDiagram::Private::setOrientationAndType(Qt::Orientation o, BarDiagram::BarType type)
49 {
50  if (orientation == o && implementor->type() == type) {
51  return;
52  }
53  auto *barDia = qobject_cast<BarDiagram *>(diagram);
54 
55  orientation = o;
56 
57  if (orientation == Qt::Vertical) {
58  switch (type) {
59  case Normal:
60  implementor = normalDiagram;
61  break;
62  case Stacked:
63  implementor = stackedDiagram;
64  break;
65  case Percent:
66  implementor = percentDiagram;
67  break;
68  default:
69  Q_ASSERT_X(false, "BarDiagram::setType", "unknown diagram subtype");
70  }
71  } else {
72  switch (type) {
73  case Normal:
74  implementor = normalLyingDiagram;
75  break;
76  case Stacked:
77  implementor = stackedLyingDiagram;
78  break;
79  case Percent:
80  implementor = percentLyingDiagram;
81  break;
82  default:
83  Q_ASSERT_X(false, "BarDiagram::setType", "unknown diagram subtype");
84  }
85  }
86 
87  Q_ASSERT(implementor->type() == type);
88 
89  // AbstractAxis settings - see AbstractDiagram and CartesianAxis
90  barDia->setPercentMode(type == BarDiagram::Percent);
91  barDia->setDataBoundariesDirty();
92  Q_EMIT barDia->layoutChanged(barDia);
93  Q_EMIT barDia->propertiesChanged();
94 }
95 
96 #define d d_func()
97 
99  : AbstractCartesianDiagram(new Private(), parent, plane)
100 {
101  init();
102 }
103 
104 void BarDiagram::init()
105 {
106  d->normalDiagram = new NormalBarDiagram(this);
107  d->stackedDiagram = new StackedBarDiagram(this);
108  d->percentDiagram = new PercentBarDiagram(this);
109  d->normalLyingDiagram = new NormalLyingBarDiagram(this);
110  d->stackedLyingDiagram = new StackedLyingBarDiagram(this);
111  d->percentLyingDiagram = new PercentLyingBarDiagram(this);
112  d->implementor = d->normalDiagram;
113  d->compressor.setModel(attributesModel());
114 }
115 
117 {
118 }
119 
124 {
125  auto *newDiagram = new BarDiagram(new Private(*d));
126  newDiagram->setType(type());
127  return newDiagram;
128 }
129 
130 bool BarDiagram::compare(const BarDiagram *other) const
131 {
132  if (other == this)
133  return true;
134  if (!other) {
135  return false;
136  }
137 
138  return // compare the base class
139  (static_cast<const AbstractCartesianDiagram *>(this)->compare(other)) &&
140  // compare own properties
141  (type() == other->type());
142 }
143 
148 void BarDiagram::setType(const BarType type)
149 {
150  d->setOrientationAndType(d->orientation, type);
151 }
152 
157 {
158  return d->implementor->type();
159 }
160 
164 void BarDiagram::setOrientation(Qt::Orientation orientation)
165 {
166  d->setOrientationAndType(orientation, d->implementor->type());
167 }
168 
172 Qt::Orientation BarDiagram::orientation() const
173 {
174  return d->orientation;
175 }
176 
181 {
182  d->attributesModel->setModelData(QVariant::fromValue(ba), BarAttributesRole);
183  Q_EMIT propertiesChanged();
184 }
185 
189 void BarDiagram::setBarAttributes(int column, const BarAttributes &ba)
190 {
191  d->setDatasetAttrs(column, QVariant::fromValue(ba), BarAttributesRole);
192  Q_EMIT propertiesChanged();
193 }
194 
198 void BarDiagram::setBarAttributes(const QModelIndex &index, const BarAttributes &ba)
199 {
201  d->attributesModel->mapFromSource(index),
202  QVariant::fromValue(ba),
204  Q_EMIT propertiesChanged();
205 }
206 
211 {
212  return d->attributesModel->data(KDChart::BarAttributesRole).value<BarAttributes>();
213 }
214 
219 {
220  const QVariant attrs(d->datasetAttrs(column, KDChart::BarAttributesRole));
221  if (attrs.isValid())
222  return attrs.value<BarAttributes>();
223  return barAttributes();
224 }
225 
229 BarAttributes BarDiagram::barAttributes(const QModelIndex &index) const
230 {
231  return d->attributesModel->data(
232  d->attributesModel->mapFromSource(index),
234  .value<BarAttributes>();
235 }
236 
241 {
243  d->attributesModel->setModelData(QVariant::fromValue(threeDAttrs), ThreeDBarAttributesRole);
244  Q_EMIT layoutChanged(this);
245  Q_EMIT propertiesChanged();
246 }
247 
251 void BarDiagram::setThreeDBarAttributes(int column, const ThreeDBarAttributes &threeDAttrs)
252 {
254  d->setDatasetAttrs(column, QVariant::fromValue(threeDAttrs), ThreeDBarAttributesRole);
255  // Q_EMIT layoutChanged( this );
256  Q_EMIT propertiesChanged();
257 }
258 
262 void BarDiagram::setThreeDBarAttributes(const QModelIndex &index, const ThreeDBarAttributes &threeDAttrs)
263 {
265  d->attributesModel->setData(
266  d->attributesModel->mapFromSource(index),
267  QVariant::fromValue(threeDAttrs),
269  // Q_EMIT layoutChanged( this );
270  Q_EMIT propertiesChanged();
271 }
272 
277 {
278  return d->attributesModel->data(KDChart::ThreeDBarAttributesRole).value<ThreeDBarAttributes>();
279 }
280 
285 {
286  const QVariant attrs(d->datasetAttrs(column, KDChart::ThreeDBarAttributesRole));
287  if (attrs.isValid())
288  return attrs.value<ThreeDBarAttributes>();
289  return threeDBarAttributes();
290 }
291 
296 {
297  return d->attributesModel->data(
298  d->attributesModel->mapFromSource(index),
300  .value<ThreeDBarAttributes>();
301 }
302 
303 qreal BarDiagram::threeDItemDepth(const QModelIndex &index) const
304 {
305  return threeDBarAttributes(index).validDepth();
306 }
307 
308 qreal BarDiagram::threeDItemDepth(int column) const
309 {
310  return threeDBarAttributes(column).validDepth();
311 }
312 
313 void BarDiagram::resizeEvent(QResizeEvent *)
314 {
315 }
316 
317 const QPair<QPointF, QPointF> BarDiagram::calculateDataBoundaries() const
318 {
319  d->compressor.setResolution(static_cast<int>(this->size().width() * coordinatePlane()->zoomFactorX()),
320  static_cast<int>(this->size().height() * coordinatePlane()->zoomFactorY()));
321 
322  if (!checkInvariants(true)) {
323  return QPair<QPointF, QPointF>(QPointF(0, 0), QPointF(0, 0));
324  }
325 
326  // note: calculateDataBoundaries() is ignoring the hidden flags.
327  // That's not a bug but a feature: Hiding data does not mean removing them.
328  // For totally removing data from KD Chart's view people can use e.g. a proxy model
329  // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
330  return d->implementor->calculateDataBoundaries();
331 }
332 
333 void BarDiagram::paintEvent(QPaintEvent *)
334 {
335  QPainter painter(viewport());
336  PaintContext ctx;
337  ctx.setPainter(&painter);
338  ctx.setRectangle(QRectF(0, 0, width(), height()));
339  paint(&ctx);
340 }
341 
343 {
344  if (!checkInvariants(true))
345  return;
347  return;
348  const PainterSaver p(ctx->painter());
349  if (model()->rowCount(rootIndex()) == 0 || model()->columnCount(rootIndex()) == 0)
350  return; // nothing to paint for us
351 
352  AbstractCoordinatePlane *const plane = ctx->coordinatePlane();
353  ctx->setCoordinatePlane(plane->sharedAxisMasterPlane(ctx->painter()));
354 
355  // This was intended as a fix for KDCH-515, however it caused KDCH-816
356  // and the original problem in KDCH-515 had by then been fixed in another way.
357  // Bottom line is, this code is wrong because the above call to
358  // plane->sharedAxisMasterPlane() performs a translation of the painter, which
359  // also translates the clip rect, so if we set the old clip rect again afterwards,
360  // we get a wrong clipping.
361  // Also, this code is unnecessary because CartesianCoordinatePlane::paint()
362  // already sets the clipping properly before calling this method.
363  // ctx->painter()->setClipping( true );
364  // ctx->painter()->setClipRect( ctx->rectangle() );
365 
366  // paint different bar types Normal - Stacked - Percent - Default Normal
367  d->implementor->paint(ctx);
368 
369  ctx->setCoordinatePlane(plane);
370 }
371 
372 void BarDiagram::resize(const QSizeF &size)
373 {
374  d->compressor.setResolution(static_cast<int>(size.width() * coordinatePlane()->zoomFactorX()),
375  static_cast<int>(size.height() * coordinatePlane()->zoomFactorY()));
377  QAbstractItemView::resize(size.toSize());
378 }
379 
380 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
381 const
382 #endif
383  int
385 {
386  return d->attributesModel->rowCount(attributesModelRootIndex());
387 }
388 
389 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
390 const
391 #endif
392  int
394 {
395  return d->attributesModel->columnCount(attributesModelRootIndex());
396 }
397 
398 // #undef d
#define d
Base class for diagrams based on a cartesian coordianate system.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
virtual AbstractCoordinatePlane * sharedAxisMasterPlane(QPainter *p=nullptr)
virtual AttributesModel * attributesModel() const
virtual bool checkInvariants(bool justReturnTheStatus=false) const
void layoutChanged(AbstractDiagram *)
QModelIndex attributesModelRootIndex() const
returns a QModelIndex pointing into the AttributesModel that corresponds to the root index of the dia...
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
AbstractCoordinatePlane * coordinatePlane() const
static bool isBoundariesValid(const QRectF &r)
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
Set of attributes for changing the appearance of bar charts.
BarDiagram defines a common bar diagram.
void setThreeDBarAttributes(const ThreeDBarAttributes &a)
ThreeDBarAttributes threeDBarAttributes() const
BarDiagram(QWidget *parent=nullptr, CartesianCoordinatePlane *plane=nullptr)
int numberOfAbscissaSegments() const override
BarAttributes barAttributes() const
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
bool compare(const BarDiagram *other) const
void paintEvent(QPaintEvent *) override
void resizeEvent(QResizeEvent *) override
Qt::Orientation orientation() const
virtual BarDiagram * clone() const
void setBarAttributes(const BarAttributes &a)
void paint(PaintContext *paintContext) override
int numberOfOrdinateSegments() const override
void setOrientation(Qt::Orientation orientation)
void resize(const QSizeF &area) override
void setType(const BarType type)
qreal threeDItemDepth(const QModelIndex &index) const override
Stores information about painting diagrams.
void setPainter(QPainter *painter)
void setCoordinatePlane(AbstractCoordinatePlane *plane)
void setRectangle(const QRectF &rect)
AbstractCoordinatePlane * coordinatePlane() const
QPainter * painter() const
@ ThreeDBarAttributesRole
@ BarAttributesRole

© 2001 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/
Generated by doxygen 1.9.1