KD Chart API Documentation 3.0
Loading...
Searching...
No Matches
KDChartAbstractCoordinatePlane.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
12#include "KDChartAbstractCoordinatePlane_p.h"
13
14#include "KDChartChart.h"
16
17#include <KDABLibFakes>
18
19#include <QGridLayout>
20#include <QMouseEvent>
21#include <QRubberBand>
22#include <QtCore/qmath.h>
23
24using namespace KDChart;
25
26#define d d_func()
27
28AbstractCoordinatePlane::Private::Private()
29 : AbstractArea::Private()
30{
31 // this block left empty intentionally
32}
33
35 : AbstractArea(new Private())
36{
37 d->parent = parent;
38 d->init();
39}
40
45
46void AbstractCoordinatePlane::init()
47{
48 d->initialize(); // virtual method to init the correct grid: cartesian, polar, ...
52}
53
55{
56 // diagrams are invisible and paint through their paint() method
57 diagram->hide();
58
59 d->diagrams.append(diagram);
60 diagram->setParent(d->parent);
63 layoutPlanes(); // there might be new axes, etc
64 connect(diagram, SIGNAL(modelsChanged()), this, SLOT(layoutPlanes()));
65 connect(diagram, SIGNAL(modelDataChanged()), this, SLOT(update()));
66 connect(diagram, SIGNAL(modelDataChanged()), this, SLOT(relayout()));
68
69 update();
71}
72
73/*virtual*/
75{
76 if (diagram && oldDiagram_ != diagram) {
78 if (d->diagrams.count()) {
79 if (!oldDiagram) {
80 oldDiagram = d->diagrams.first();
81 if (oldDiagram == diagram)
82 return;
83 }
85 }
86 delete oldDiagram;
89 layoutPlanes(); // there might be new axes, etc
90 update();
91 }
92}
93
94/*virtual*/
96{
97 const int idx = d->diagrams.indexOf(diagram);
98 if (idx != -1) {
99 d->diagrams.removeAt(idx);
100 diagram->setParent(nullptr);
101 diagram->setCoordinatePlane(nullptr);
102 disconnect(diagram, SIGNAL(modelsChanged()), this, SLOT(layoutPlanes()));
103 disconnect(diagram, SIGNAL(modelDataChanged()), this, SLOT(update()));
104 disconnect(diagram, SIGNAL(modelDataChanged()), this, SLOT(relayout()));
106 update();
107 }
108}
109
111{
112 if (d->diagrams.isEmpty()) {
113 return nullptr;
114 } else {
115 return d->diagrams.first();
116 }
117}
118
123
125{
127#ifndef QT_NO_STL
128 qCopy(d->diagrams.begin(), d->diagrams.end(), std::back_inserter(list));
129#else
130 Q_FOREACH (AbstractDiagram *a, d->diagrams)
131 list.push_back(a);
132#endif
133 return list;
134}
135
137{
138 d->gridAttributes = a;
139 update();
140}
141
143{
144 return d->gridAttributes;
145}
146
151
153{
154 d->grid->setNeedRecalculate();
155}
156
158{
159 d->referenceCoordinatePlane = plane;
160}
161
166
171
176
181
182/* pure virtual in QLayoutItem */
184{
185 return false; // never empty!
186 // coordinate planes with no associated diagrams
187 // are showing a default grid of ()1..10, 1..10) stepWidth 1
188}
189/* pure virtual in QLayoutItem */
194/* pure virtual in QLayoutItem */
196{
197 // No maximum size set. Especially not parent()->size(), we are not layouting
198 // to the parent widget's size when using Chart::paint()!
199 return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
200}
201/* pure virtual in QLayoutItem */
203{
204 return QSize(60, 60); // this default can be overwritten by derived classes
205}
206/* pure virtual in QLayoutItem */
208{
209 // we return our maxiumu (which is the full size of the Chart)
210 // even if we know the plane will be smaller
211 return maximumSize();
212}
213/* pure virtual in QLayoutItem */
215{
216 if (d->geometry != r) {
217 // inform the outside word by Signal geometryChanged()
218 // via a queued connection to internal_geometryChanged()
219 emit internal_geometryChanged(d->geometry, r);
220
221 d->geometry = r;
222 // Note: We do *not* call update() here
223 // because it would invoke KDChart::update() recursively.
224 }
225}
226/* pure virtual in QLayoutItem */
228{
229 return d->geometry;
230}
231
233{
234 // qDebug("KDChart::AbstractCoordinatePlane::update() called");
235 emit needUpdate();
236}
237
239{
240 // qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
241 emit needRelayout();
242}
243
245{
246 // qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
247 emit needLayoutPlanes();
248}
249
251{
252 d->enableRubberBandZooming = enable;
253
254 if (!enable && d->rubberBand != nullptr) {
255 delete d->rubberBand;
256 d->rubberBand = nullptr;
257 }
258}
259
261{
262 return d->enableRubberBandZooming;
263}
264
266{
267 if (d->enableCornerSpacers == enable)
268 return;
269
270 d->enableCornerSpacers = enable;
271 emit needRelayout();
272}
273
275{
276 return d->enableCornerSpacers;
277}
278
280{
281 if (event->button() == Qt::LeftButton) {
282 if (d->enableRubberBandZooming && d->rubberBand == nullptr)
283 d->rubberBand = new QRubberBand(QRubberBand::Rectangle, qobject_cast<QWidget *>(parent()));
284
285 if (d->rubberBand != nullptr) {
286 d->rubberBandOrigin = event->pos();
287 d->rubberBand->setGeometry(QRect(event->pos(), QSize()));
288 d->rubberBand->show();
289
290 event->accept();
291 }
292 } else if (event->button() == Qt::RightButton) {
293 if (d->enableRubberBandZooming && !d->rubberBandZoomConfigHistory.isEmpty()) {
294 // restore the last config from the stack
295 ZoomParameters config = d->rubberBandZoomConfigHistory.pop();
296 setZoomFactorX(config.xFactor);
297 setZoomFactorY(config.yFactor);
298 setZoomCenter(config.center());
299
300 QWidget *const p = qobject_cast<QWidget *>(parent());
301 if (p != nullptr)
302 p->update();
303
304 event->accept();
305 }
306 }
307
308 Q_FOREACH (AbstractDiagram *a, d->diagrams) {
309 a->mousePressEvent(event);
310 }
311}
312
314{
315 if (event->button() == Qt::RightButton) {
316 // otherwise the second click gets lost
317 // which is pretty annoying when zooming out fast
318 mousePressEvent(event);
319 }
320 Q_FOREACH (AbstractDiagram *a, d->diagrams) {
321 a->mouseDoubleClickEvent(event);
322 }
323}
324
326{
327 if (d->rubberBand != nullptr) {
328 // save the old config on the stack
329 d->rubberBandZoomConfigHistory.push(ZoomParameters(zoomFactorX(), zoomFactorY(), zoomCenter()));
330
331 // this is the height/width of the rubber band in pixel space
332 const auto rubberWidth = static_cast<qreal>(d->rubberBand->width());
333 const auto rubberHeight = static_cast<qreal>(d->rubberBand->height());
334
335 if (rubberWidth > 0.0 && rubberHeight > 0.0) {
336 // this is the center of the rubber band in pixel space
337 const qreal centerX = qFloor(d->rubberBand->geometry().width() / 2.0 + d->rubberBand->geometry().x());
338 const qreal centerY = qCeil(d->rubberBand->geometry().height() / 2.0 + d->rubberBand->geometry().y());
339
340 const qreal rubberCenterX = static_cast<qreal>(centerX - geometry().x());
341 const qreal rubberCenterY = static_cast<qreal>(centerY - geometry().y());
342
343 // this is the height/width of the plane in pixel space
344 const qreal myWidth = static_cast<qreal>(geometry().width());
345 const qreal myHeight = static_cast<qreal>(geometry().height());
346
347 // this describes the new center of zooming, relative to the plane pixel space
348 const qreal newCenterX = rubberCenterX / myWidth / zoomFactorX() + zoomCenter().x() - 0.5 / zoomFactorX();
349 const qreal newCenterY = rubberCenterY / myHeight / zoomFactorY() + zoomCenter().y() - 0.5 / zoomFactorY();
350
351 // this will be the new zoom factor
352 const qreal newZoomFactorX = zoomFactorX() * myWidth / rubberWidth;
353 const qreal newZoomFactorY = zoomFactorY() * myHeight / rubberHeight;
354
355 // and this the new center
356 const QPointF newZoomCenter(newCenterX, newCenterY);
357
358 setZoomFactorX(newZoomFactorX);
359 setZoomFactorY(newZoomFactorY);
360 setZoomCenter(newZoomCenter);
361 }
362
363 d->rubberBand->parentWidget()->update();
364 delete d->rubberBand;
365 d->rubberBand = nullptr;
366
367 event->accept();
368 }
369
370 Q_FOREACH (AbstractDiagram *a, d->diagrams) {
371 a->mouseReleaseEvent(event);
372 }
373}
374
376{
377 if (d->rubberBand != nullptr) {
378 const QRect normalized = QRect(d->rubberBandOrigin, event->pos()).normalized();
379 d->rubberBand->setGeometry(normalized & geometry());
380
381 event->accept();
382 }
383
384 Q_FOREACH (AbstractDiagram *a, d->diagrams) {
385 a->mouseMoveEvent(event);
386 }
387}
388
389#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
390const
391#endif
392 bool
394{
395 return d->isVisiblePoint(this, point);
396}
397
403
404#if !defined(QT_NO_DEBUG_STREAM)
405#include "KDChartEnums.h"
406
408{
409 stream << "DataDimension("
410 << " start=" << r.start
411 << " end=" << r.end
413 << " isCalculated=" << r.isCalculated
414 << " calcMode=" << (r.calcMode == AbstractCoordinatePlane::Logarithmic ? "Logarithmic" : "Linear")
415 << " stepWidth=" << r.stepWidth
416 << " subStepWidth=" << r.subStepWidth
417 << " )";
418 return stream;
419}
420#endif
421
422#undef d
Definition of global enums.
static QString granularitySequenceToString(GranularitySequence sequence)
An area in the chart with a background, a frame, etc.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
void destroyedCoordinatePlane(AbstractCoordinatePlane *)
virtual void addDiagram(AbstractDiagram *diagram)
virtual void mousePressEvent(QMouseEvent *event)
virtual void replaceDiagram(AbstractDiagram *diagram, AbstractDiagram *oldDiagram=nullptr)
virtual AbstractCoordinatePlane * sharedAxisMasterPlane(QPainter *p=nullptr)
bool isVisiblePoint(const QPointF &point) const
virtual void mouseReleaseEvent(QMouseEvent *event)
Qt::Orientations expandingDirections() const override
void setReferenceCoordinatePlane(AbstractCoordinatePlane *plane)
virtual void mouseDoubleClickEvent(QMouseEvent *event)
void internal_geometryChanged(QRect, QRect)
void geometryChanged(QRect, QRect)
AbstractCoordinatePlane * referenceCoordinatePlane() const
virtual void takeDiagram(AbstractDiagram *diagram)
virtual void mouseMoveEvent(QMouseEvent *event)
AbstractDiagram defines the interface for diagram classes.
virtual void setCoordinatePlane(AbstractCoordinatePlane *plane)
A chart with one or more diagrams.
Helper class for one dimension of data, e.g. for the rows in a data model, or for the labels of an ax...
AbstractCoordinatePlane::AxesCalcMode calcMode
KDChartEnums::GranularitySequence sequence
A set of attributes controlling the appearance of grids.
const QPointF center() const
QDebug operator<<(QDebug stream, const DataDimension &r)
virtual void mouseDoubleClickEvent(QMouseEvent *event) override
virtual void mouseMoveEvent(QMouseEvent *event) override
virtual void mousePressEvent(QMouseEvent *event) override
virtual void mouseReleaseEvent(QMouseEvent *event) override
Qt::MouseButton button() const const
QPoint pos() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QObject * parent() const const
T qobject_cast(QObject *object)
QRect normalized() const const
QueuedConnection
LeftButton
typedef Orientations
void hide()
void setParent(QWidget *parent)
void update()

© 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 on Fri Feb 23 2024 00:02:58 for KD Chart API Documentation by doxygen 1.9.8