KD Chart 2  [rev.2.8]
KDChartAbstractCoordinatePlane.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2021 Klaralvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Chart library.
5 **
6 ** Licensees holding valid commercial KD Chart licenses may use this file in
7 ** accordance with the KD Chart Commercial License Agreement provided with
8 ** the Software.
9 **
10 **
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 and version 3 as published by the
13 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
14 **
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 **
18 ** Contact info@kdab.com if any conditions of this licensing are not
19 ** clear to you.
20 **
21 **********************************************************************/
22 
24 #include "KDChartAbstractCoordinatePlane_p.h"
25 
26 #include "KDChartChart.h"
27 #include "KDChartGridAttributes.h"
28 
29 #include <KDABLibFakes>
30 
31 #include <QGridLayout>
32 #include <QRubberBand>
33 #include <QMouseEvent>
34 #include <QtCore/qmath.h>
35 
36 using namespace KDChart;
37 
38 #define d d_func()
39 
40 AbstractCoordinatePlane::Private::Private()
41  : AbstractArea::Private()
42  , parent( 0 )
43  , grid( 0 )
44  , referenceCoordinatePlane( 0 )
45  , enableCornerSpacers( true )
46  , enableRubberBandZooming( false )
47  , rubberBand( 0 )
48 {
49  // this bloc left empty intentionally
50 }
51 
52 
53 AbstractCoordinatePlane::AbstractCoordinatePlane ( KDChart::Chart* parent )
54  : AbstractArea ( new Private() )
55 {
56  d->parent = parent;
57  d->init();
58 }
59 
61 {
62  emit destroyedCoordinatePlane( this );
63 }
64 
65 void AbstractCoordinatePlane::init()
66 {
67  d->initialize(); // virtual method to init the correct grid: cartesian, polar, ...
68  connect( this, SIGNAL(internal_geometryChanged( QRect, QRect )),
69  this, SIGNAL(geometryChanged( QRect, QRect )),
70  Qt::QueuedConnection );
71 }
72 
74 {
75  // diagrams are invisible and paint through their paint() method
76  diagram->hide();
77 
78  d->diagrams.append( diagram );
79  diagram->setParent( d->parent );
80  diagram->setCoordinatePlane( this );
82  layoutPlanes(); // there might be new axes, etc
83  connect( diagram, SIGNAL( modelsChanged() ), this, SLOT( layoutPlanes() ) );
84  connect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( update()) );
85  connect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( relayout()) );
86  connect( this, SIGNAL( boundariesChanged() ), diagram, SIGNAL( boundariesChanged() ) );
87 
88  update();
89  emit boundariesChanged();
90 }
91 
92 /*virtual*/
94 {
95  if ( diagram && oldDiagram_ != diagram ) {
96  AbstractDiagram* oldDiagram = oldDiagram_;
97  if ( d->diagrams.count() ) {
98  if ( ! oldDiagram ) {
99  oldDiagram = d->diagrams.first();
100  if ( oldDiagram == diagram )
101  return;
102  }
103  takeDiagram( oldDiagram );
104  }
105  delete oldDiagram;
106  addDiagram( diagram );
107  layoutDiagrams();
108  layoutPlanes(); // there might be new axes, etc
109  update();
110  }
111 }
112 
113 /*virtual*/
115 {
116  const int idx = d->diagrams.indexOf( diagram );
117  if ( idx != -1 ) {
118  d->diagrams.removeAt( idx );
119  diagram->setParent( 0 );
121  disconnect( diagram, SIGNAL( modelsChanged() ), this, SLOT( layoutPlanes() ) );
122  disconnect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( update()) );
123  disconnect( diagram, SIGNAL( modelDataChanged() ), this, SLOT( relayout()) );
124  layoutDiagrams();
125  update();
126  }
127 }
128 
129 
131 {
132  if ( d->diagrams.isEmpty() )
133  {
134  return 0;
135  } else {
136  return d->diagrams.first();
137  }
138 }
139 
141 {
142  return d->diagrams;
143 }
144 
146 {
148 #ifndef QT_NO_STL
149  qCopy( d->diagrams.begin(), d->diagrams.end(), std::back_inserter( list ) );
150 #else
151  Q_FOREACH( AbstractDiagram * a, d->diagrams )
152  list.push_back( a );
153 #endif
154  return list;
155 }
156 
158 {
159  d->gridAttributes = a;
160  update();
161 }
162 
164 {
165  return d->gridAttributes;
166 }
167 
169 {
170  return d->grid->updateData( this );
171 }
172 
174 {
175  d->grid->setNeedRecalculate();
176 }
177 
179 {
180  d->referenceCoordinatePlane = plane;
181 }
182 
184 {
185  return d->referenceCoordinatePlane;
186 }
187 
189 {
190  d->parent = parent;
191 }
192 
194 {
195  return d->parent;
196 }
197 
199 {
200  return d->parent;
201 }
202 
203 /* pure virtual in QLayoutItem */
205 {
206  return false; // never empty!
207  // coordinate planes with no associated diagrams
208  // are showing a default grid of ()1..10, 1..10) stepWidth 1
209 }
210 /* pure virtual in QLayoutItem */
212 {
213  return Qt::Vertical | Qt::Horizontal;
214 }
215 /* pure virtual in QLayoutItem */
217 {
218  // No maximum size set. Especially not parent()->size(), we are not layouting
219  // to the parent widget's size when using Chart::paint()!
220  return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
221 }
222 /* pure virtual in QLayoutItem */
224 {
225  return QSize(60, 60); // this default can be overwritten by derived classes
226 }
227 /* pure virtual in QLayoutItem */
229 {
230  // we return our maxiumu (which is the full size of the Chart)
231  // even if we know the plane will be smaller
232  return maximumSize();
233 }
234 /* pure virtual in QLayoutItem */
236 {
237  if ( d->geometry != r ) {
238  // inform the outside word by Signal geometryChanged()
239  // via a queued connection to internal_geometryChanged()
240  emit internal_geometryChanged( d->geometry, r );
241 
242  d->geometry = r;
243  // Note: We do *not* call update() here
244  // because it would invoke KDChart::update() recursively.
245  }
246 }
247 /* pure virtual in QLayoutItem */
249 {
250  return d->geometry;
251 }
252 
254 {
255  //qDebug("KDChart::AbstractCoordinatePlane::update() called");
256  emit needUpdate();
257 }
258 
260 {
261  //qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
262  emit needRelayout();
263 }
264 
266 {
267  //qDebug("KDChart::AbstractCoordinatePlane::relayout() called");
268  emit needLayoutPlanes();
269 }
270 
272 {
273  d->enableRubberBandZooming = enable;
274 
275  if ( !enable && d->rubberBand != 0 )
276  {
277  delete d->rubberBand;
278  d->rubberBand = 0;
279  }
280 }
281 
283 {
284  return d->enableRubberBandZooming;
285 }
286 
288 {
289  if ( d->enableCornerSpacers == enable ) return;
290 
291  d->enableCornerSpacers = enable;
292  emit needRelayout();
293 }
294 
296 {
297  return d->enableCornerSpacers;
298 }
299 
301 {
302  if ( event->button() == Qt::LeftButton )
303  {
304  if ( d->enableRubberBandZooming && d->rubberBand == 0 )
305  d->rubberBand = new QRubberBand( QRubberBand::Rectangle, qobject_cast< QWidget* >( parent() ) );
306 
307  if ( d->rubberBand != 0 )
308  {
309  d->rubberBandOrigin = event->pos();
310  d->rubberBand->setGeometry( QRect( event->pos(), QSize() ) );
311  d->rubberBand->show();
312 
313  event->accept();
314  }
315  }
316  else if ( event->button() == Qt::RightButton )
317  {
318  if ( d->enableRubberBandZooming && !d->rubberBandZoomConfigHistory.isEmpty() )
319  {
320  // restore the last config from the stack
321  ZoomParameters config = d->rubberBandZoomConfigHistory.pop();
322  setZoomFactorX( config.xFactor );
323  setZoomFactorY( config.yFactor );
324  setZoomCenter( config.center() );
325 
326  QWidget* const p = qobject_cast< QWidget* >( parent() );
327  if ( p != 0 )
328  p->update();
329 
330  event->accept();
331  }
332  }
333 
334  KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
335  {
336  a->mousePressEvent( event );
337  }
338 }
339 
341 {
342  if ( event->button() == Qt::RightButton )
343  {
344  // othewise the second click gets lost
345  // which is pretty annoying when zooming out fast
346  mousePressEvent( event );
347  }
348  KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
349  {
350  a->mouseDoubleClickEvent( event );
351  }
352 }
353 
355 {
356  if ( d->rubberBand != 0 )
357  {
358  // save the old config on the stack
359  d->rubberBandZoomConfigHistory.push( ZoomParameters( zoomFactorX(), zoomFactorY(), zoomCenter() ) );
360 
361  // this is the height/width of the rubber band in pixel space
362  const qreal rubberWidth = static_cast< qreal >( d->rubberBand->width() );
363  const qreal rubberHeight = static_cast< qreal >( d->rubberBand->height() );
364 
365  if ( rubberWidth > 0.0 && rubberHeight > 0.0 )
366  {
367  // this is the center of the rubber band in pixel space
368  const qreal centerX = qFloor( d->rubberBand->geometry().width() / 2.0 + d->rubberBand->geometry().x() );
369  const qreal centerY = qCeil( d->rubberBand->geometry().height() / 2.0 + d->rubberBand->geometry().y() );
370 
371  const qreal rubberCenterX = static_cast< qreal >( centerX - geometry().x() );
372  const qreal rubberCenterY = static_cast< qreal >( centerY - geometry().y() );
373 
374  // this is the height/width of the plane in pixel space
375  const qreal myWidth = static_cast< qreal >( geometry().width() );
376  const qreal myHeight = static_cast< qreal >( geometry().height() );
377 
378  // this describes the new center of zooming, relative to the plane pixel space
379  const qreal newCenterX = rubberCenterX / myWidth / zoomFactorX() + zoomCenter().x() - 0.5 / zoomFactorX();
380  const qreal newCenterY = rubberCenterY / myHeight / zoomFactorY() + zoomCenter().y() - 0.5 / zoomFactorY();
381 
382  // this will be the new zoom factor
383  const qreal newZoomFactorX = zoomFactorX() * myWidth / rubberWidth;
384  const qreal newZoomFactorY = zoomFactorY() * myHeight / rubberHeight;
385 
386  // and this the new center
387  const QPointF newZoomCenter( newCenterX, newCenterY );
388 
389  setZoomFactorX( newZoomFactorX );
390  setZoomFactorY( newZoomFactorY );
391  setZoomCenter( newZoomCenter );
392  }
393 
394  d->rubberBand->parentWidget()->update();
395  delete d->rubberBand;
396  d->rubberBand = 0;
397 
398  event->accept();
399  }
400 
401  KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
402  {
403  a->mouseReleaseEvent( event );
404  }
405 }
406 
408 {
409  if ( d->rubberBand != 0 )
410  {
411  const QRect normalized = QRect( d->rubberBandOrigin, event->pos() ).normalized();
412  d->rubberBand->setGeometry( normalized & geometry() );
413 
414  event->accept();
415  }
416 
417  KDAB_FOREACH( AbstractDiagram * a, d->diagrams )
418  {
419  a->mouseMoveEvent( event );
420  }
421 }
422 
423 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
424 const
425 #endif
426 bool KDChart::AbstractCoordinatePlane::isVisiblePoint( const QPointF& point ) const
427 {
428  return d->isVisiblePoint( this, point );
429 }
430 
432 {
433  Q_UNUSED( p );
434  return this;
435 }
436 
437 #if !defined(QT_NO_DEBUG_STREAM)
438 #include "KDChartEnums.h"
439 
440 QDebug KDChart::operator<<( QDebug stream, const DataDimension& r )
441 {
442  stream << "DataDimension("
443  << " start=" << r.start
444  << " end=" << r.end
446  << " isCalculated=" << r.isCalculated
447  << " calcMode=" << ( r.calcMode == AbstractCoordinatePlane::Logarithmic ? "Logarithmic" : "Linear" )
448  << " stepWidth=" << r.stepWidth
449  << " subStepWidth=" << r.subStepWidth
450  << " )";
451  return stream;
452 }
453 #endif
454 
455 #undef d
KDChart::AbstractCoordinatePlane::sharedAxisMasterPlane
virtual AbstractCoordinatePlane * sharedAxisMasterPlane(QPainter *p=0)
Definition: KDChartAbstractCoordinatePlane.cpp:431
QWidget
Class only listed here to document inheritance of some KDChart classes.
KDChart::AbstractCoordinatePlane::boundariesChanged
void boundariesChanged()
KDChart::AbstractCoordinatePlane::setParent
void setParent(Chart *parent)
Called internally by KDChart::Chart.
Definition: KDChartAbstractCoordinatePlane.cpp:188
KDChartEnums::granularitySequenceToString
static QString granularitySequenceToString(GranularitySequence sequence)
Converts the specified granularity sequence enum to a string representation.
Definition: KDChartEnums.h:109
QList
Definition: KDChartPosition.h:36
KDChart::AbstractCoordinatePlane::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *event)
Definition: KDChartAbstractCoordinatePlane.cpp:407
KDChart::AbstractCoordinatePlane::relayout
void relayout()
Calling relayout() on the plane triggers the global KDChart::Chart::slotRelayout()
Definition: KDChartAbstractCoordinatePlane.cpp:259
KDChart::AbstractCoordinatePlane::mousePressEvent
virtual void mousePressEvent(QMouseEvent *event)
Definition: KDChartAbstractCoordinatePlane.cpp:300
KDChart::AbstractCoordinatePlane::layoutPlanes
void layoutPlanes()
Calling layoutPlanes() on the plane triggers the global KDChart::Chart::slotLayoutPlanes()
Definition: KDChartAbstractCoordinatePlane.cpp:265
KDChart::AbstractCoordinatePlane::internal_geometryChanged
void internal_geometryChanged(QRect, QRect)
KDChart::GridAttributes
A set of attributes controlling the appearance of grids.
Definition: KDChartGridAttributes.h:40
KDChart::AbstractCoordinatePlane::geometry
QRect geometry() const override
pure virtual in QLayoutItem
Definition: KDChartAbstractCoordinatePlane.cpp:248
KDChart::AbstractCoordinatePlane::destroyedCoordinatePlane
void destroyedCoordinatePlane(AbstractCoordinatePlane *)
Emitted when this coordinate plane is destroyed.
KDChart::AbstractCoordinatePlane::update
void update()
Calling update() on the plane triggers the global KDChart::Chart::update()
Definition: KDChartAbstractCoordinatePlane.cpp:253
KDChart::AbstractCoordinatePlane::setReferenceCoordinatePlane
void setReferenceCoordinatePlane(AbstractCoordinatePlane *plane)
Set another coordinate plane to be used as the reference plane for this one.
Definition: KDChartAbstractCoordinatePlane.cpp:178
KDChart::AbstractCoordinatePlane::takeDiagram
virtual void takeDiagram(AbstractDiagram *diagram)
Removes the diagram from the plane, without deleting it.
Definition: KDChartAbstractCoordinatePlane.cpp:114
KDChart
Definition: KDChartAbstractCartesianDiagram.h:30
KDChart::AbstractCoordinatePlane::diagram
AbstractDiagram * diagram()
Definition: KDChartAbstractCoordinatePlane.cpp:130
KDChart::DataDimension::isCalculated
bool isCalculated
Definition: KDChartAbstractCoordinatePlane.h:434
KDChart::ZoomParameters::yFactor
qreal yFactor
Definition: KDChartZoomParameters.h:73
KDChart::AbstractCoordinatePlane::replaceDiagram
virtual void replaceDiagram(AbstractDiagram *diagram, AbstractDiagram *oldDiagram=0)
Replaces the old diagram, or appends the diagram, it there is none yet.
Definition: KDChartAbstractCoordinatePlane.cpp:93
KDChart::operator<<
QDebug operator<<(QDebug stream, const DataDimension &r)
Definition: KDChartAbstractCoordinatePlane.cpp:440
KDChart::AbstractCoordinatePlane::parent
Chart * parent()
Definition: KDChartAbstractCoordinatePlane.cpp:198
KDChart::AbstractCoordinatePlane::globalGridAttributes
GridAttributes globalGridAttributes() const
Definition: KDChartAbstractCoordinatePlane.cpp:163
KDChart::AbstractCoordinatePlane::referenceCoordinatePlane
AbstractCoordinatePlane * referenceCoordinatePlane() const
There are two ways, in which planes can be caused to interact, in where they are put layouting wise: ...
Definition: KDChartAbstractCoordinatePlane.cpp:183
KDChart::DataDimension::sequence
KDChartEnums::GranularitySequence sequence
Definition: KDChartAbstractCoordinatePlane.h:436
KDChart::AbstractCoordinatePlane::setGlobalGridAttributes
void setGlobalGridAttributes(const GridAttributes &)
Set the grid attributes to be used by this coordinate plane.
Definition: KDChartAbstractCoordinatePlane.cpp:157
KDChart::AbstractCoordinatePlane::setCornerSpacersEnabled
void setCornerSpacersEnabled(bool enable)
Enables or disables the use of spacers in the plane corners.
Definition: KDChartAbstractCoordinatePlane.cpp:287
KDChartEnums.h
Definition of global enums.
KDChart::ZoomParameters::center
const QPointF center() const
Definition: KDChartZoomParameters.h:67
KDChart::AbstractCoordinatePlane::Logarithmic
@ Logarithmic
Definition: KDChartAbstractCoordinatePlane.h:53
KDChart::AbstractCoordinatePlane::sizeHint
QSize sizeHint() const override
pure virtual in QLayoutItem
Definition: KDChartAbstractCoordinatePlane.cpp:228
KDChart::DataDimension::end
qreal end
Definition: KDChartAbstractCoordinatePlane.h:433
KDChart::ZoomParameters::xFactor
qreal xFactor
Definition: KDChartZoomParameters.h:72
KDChart::AbstractCoordinatePlane::diagrams
AbstractDiagramList diagrams()
Definition: KDChartAbstractCoordinatePlane.cpp:140
KDChart::AbstractCoordinatePlane::isRubberBandZoomingEnabled
bool isRubberBandZoomingEnabled() const
Definition: KDChartAbstractCoordinatePlane.cpp:282
KDChart::DataDimension::start
qreal start
Definition: KDChartAbstractCoordinatePlane.h:432
KDChart::AbstractDiagram
AbstractDiagram defines the interface for diagram classes.
Definition: KDChartAbstractDiagram.h:51
KDChartGridAttributes.h
KDChart::AbstractCoordinatePlane::~AbstractCoordinatePlane
~AbstractCoordinatePlane() override
Definition: KDChartAbstractCoordinatePlane.cpp:60
d
#define d
Definition: KDChartAbstractCoordinatePlane.cpp:38
KDChart::AbstractCoordinatePlane::setGridNeedsRecalculate
void setGridNeedsRecalculate()
Used by the chart to clear the cached grid data.
Definition: KDChartAbstractCoordinatePlane.cpp:173
KDChart::AbstractCoordinatePlane::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *event)
Definition: KDChartAbstractCoordinatePlane.cpp:354
KDChart::AbstractArea
An area in the chart with a background, a frame, etc.
Definition: KDChartAbstractArea.h:50
KDChart::AbstractCoordinatePlane::isVisiblePoint
bool isVisiblePoint(const QPointF &point) const
Tests, if a point is visible on the coordinate plane.
Definition: KDChartAbstractCoordinatePlane.cpp:426
KDChart::AbstractCoordinatePlane::setRubberBandZoomingEnabled
void setRubberBandZoomingEnabled(bool enable)
Enables or disables zooming with a rubber band using the mouse.
Definition: KDChartAbstractCoordinatePlane.cpp:271
KDChartChart.h
KDChart::AbstractCoordinatePlane::gridDimensionsList
DataDimensionsList gridDimensionsList()
Returns the dimensions used for drawing the grid lines.
Definition: KDChartAbstractCoordinatePlane.cpp:168
KDChartAbstractCoordinatePlane.h
KDChart::AbstractCoordinatePlane::mouseDoubleClickEvent
virtual void mouseDoubleClickEvent(QMouseEvent *event)
Definition: KDChartAbstractCoordinatePlane.cpp:340
KDChart::AbstractCoordinatePlane::isCornerSpacersEnabled
bool isCornerSpacersEnabled() const
Definition: KDChartAbstractCoordinatePlane.cpp:295
KDChart::DataDimension::stepWidth
qreal stepWidth
Definition: KDChartAbstractCoordinatePlane.h:437
KDChart::ZoomParameters
ZoomParameters stores the center and the factor of zooming internally.
Definition: KDChartZoomParameters.h:44
KDChart::AbstractCoordinatePlane::geometryChanged
void geometryChanged(QRect, QRect)
Emitted after the geometry of the Coordinate Plane has been changed.
KDChart::DataDimension::subStepWidth
qreal subStepWidth
Definition: KDChartAbstractCoordinatePlane.h:438
KDChart::AbstractCoordinatePlane::expandingDirections
Qt::Orientations expandingDirections() const override
pure virtual in QLayoutItem
Definition: KDChartAbstractCoordinatePlane.cpp:211
KDChart::AbstractCoordinatePlane::minimumSize
QSize minimumSize() const override
pure virtual in QLayoutItem
Definition: KDChartAbstractCoordinatePlane.cpp:223
KDChart::Chart
A chart with one or more diagrams.
Definition: KDChartChart.h:99
KDChart::AbstractCoordinatePlane::addDiagram
virtual void addDiagram(AbstractDiagram *diagram)
Adds a diagram to this coordinate plane.
Definition: KDChartAbstractCoordinatePlane.cpp:73
KDChart::AbstractCoordinatePlane::isEmpty
bool isEmpty() const override
pure virtual in QLayoutItem
Definition: KDChartAbstractCoordinatePlane.cpp:204
KDChart::DataDimension::calcMode
AbstractCoordinatePlane::AxesCalcMode calcMode
Definition: KDChartAbstractCoordinatePlane.h:435
KDChart::AbstractDiagram::setCoordinatePlane
virtual void setCoordinatePlane(AbstractCoordinatePlane *plane)
Set the coordinate plane associated with the diagram.
Definition: KDChartAbstractDiagram.cpp:231
KDChart::DataDimension
Helper class for one dimension of data, e.g.
Definition: KDChartAbstractCoordinatePlane.h:378
KDChart::AbstractCoordinatePlane::setGeometry
void setGeometry(const QRect &r) override
pure virtual in QLayoutItem
Definition: KDChartAbstractCoordinatePlane.cpp:235
KDChart::AbstractCoordinatePlane
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
Definition: KDChartAbstractCoordinatePlane.h:45
KDChart::AbstractCoordinatePlane::maximumSize
QSize maximumSize() const override
pure virtual in QLayoutItem
Definition: KDChartAbstractCoordinatePlane.cpp:216
KDChart::AbstractCoordinatePlane::layoutDiagrams
virtual void layoutDiagrams()=0
Distribute the available space among the diagrams and axes.

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/