KChart

KChartAbstractCoordinatePlane.h
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 #ifndef KCHARTABSTRACTCOORDINATEPLANE_H
10 #define KCHARTABSTRACTCOORDINATEPLANE_H
11 
12 #include <QObject>
13 #include <QList>
14 
15 #include "KChartAbstractArea.h"
16 #include "KChartAbstractDiagram.h"
17 #include "KChartEnums.h"
18 
19 namespace KChart {
20 
21  class Chart;
22  class GridAttributes;
23  class DataDimension;
24 
25  typedef QList<DataDimension> DataDimensionsList;
26 
27  /**
28  * @brief Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane
29  */
30  class KCHART_EXPORT AbstractCoordinatePlane : public AbstractArea
31  {
32  Q_OBJECT
33 
34  KCHART_DECLARE_PRIVATE_DERIVED_PARENT( AbstractCoordinatePlane, Chart* )
35 
36  friend class AbstractGrid;
37 
38  public:
39  enum AxesCalcMode { Linear, Logarithmic };
40 
41  protected:
42  explicit AbstractCoordinatePlane( Chart* parent = nullptr );
43 
44  public:
45  ~AbstractCoordinatePlane() override;
46 
47  /**
48  * Adds a diagram to this coordinate plane.
49  * @param diagram The diagram to add.
50  *
51  * \sa replaceDiagram, takeDiagram
52  */
53  virtual void addDiagram( AbstractDiagram* diagram );
54 
55  /**
56  * Replaces the old diagram, or appends the
57  * diagram, it there is none yet.
58  *
59  * @param diagram The diagram to be used instead of the old diagram.
60  * This parameter must not be zero, or the method will do nothing.
61  *
62  * @param oldDiagram The diagram to be removed by the new diagram. This
63  * diagram will be deleted automatically. If the parameter is omitted,
64  * the very first diagram will be replaced. In case, there was no
65  * diagram yet, the new diagram will just be added.
66  *
67  * \note If you want to re-use the old diagram, call takeDiagram and
68  * addDiagram, instead of using replaceDiagram.
69  *
70  * \sa addDiagram, takeDiagram
71  */
72  virtual void replaceDiagram( AbstractDiagram* diagram, AbstractDiagram* oldDiagram = nullptr );
73 
74  /**
75  * Removes the diagram from the plane, without deleting it.
76  *
77  * The plane no longer owns the diagram, so it is
78  * the caller's responsibility to delete the diagram.
79  *
80  * \sa addDiagram, replaceDiagram
81  */
82  virtual void takeDiagram( AbstractDiagram* diagram );
83 
84  /**
85  * @return The first diagram associated with this coordinate plane.
86  */
87  AbstractDiagram* diagram();
88 
89  /**
90  * @return The list of diagrams associated with this coordinate plane.
91  */
92  AbstractDiagramList diagrams();
93 
94  /**
95  * @return The list of diagrams associated with this coordinate plane.
96  */
97  ConstAbstractDiagramList diagrams() const;
98 
99  /**
100  * Distribute the available space among the diagrams and axes.
101  */
102  virtual void layoutDiagrams() = 0;
103 
104  /**
105  * Translate the given point in value space coordinates to a position
106  * in pixel space.
107  * @param diagramPoint The point in value coordinates.
108  * @returns The translated point.
109  */
110  virtual const QPointF translate( const QPointF& diagramPoint ) const = 0;
111 
112  /**
113  * @return Whether zooming with a rubber band using the mouse is enabled.
114  */
115  bool isRubberBandZoomingEnabled() const;
116 
117  /**
118  * Enables or disables zooming with a rubber band using the mouse.
119  */
120  void setRubberBandZoomingEnabled( bool enable );
121 
122  /**
123  * @return The zoom factor in horizontal direction, that is applied
124  * to all coordinate transformations.
125  */
126  virtual qreal zoomFactorX() const { return 1.0; }
127 
128  /**
129  * @return The zoom factor in vertical direction, that is applied
130  * to all coordinate transformations.
131  */
132  virtual qreal zoomFactorY() const { return 1.0; }
133 
134  /**
135  * Sets both zoom factors in one go.
136  * \sa setZoomFactorX,setZoomFactorY
137  */
138  virtual void setZoomFactors( qreal factorX, qreal factorY ) { Q_UNUSED( factorX ); Q_UNUSED( factorY ); }
139 
140  /**
141  * Sets the zoom factor in horizontal direction, that is applied
142  * to all coordinate transformations.
143  * @param factor The new zoom factor
144  */
145  virtual void setZoomFactorX( qreal factor ) { Q_UNUSED( factor ); }
146 
147  /**
148  * Sets the zoom factor in vertical direction, that is applied
149  * to all coordinate transformations.
150  * @param factor The new zoom factor
151  */
152  virtual void setZoomFactorY( qreal factor ) { Q_UNUSED( factor ); }
153 
154  /**
155  * @return The center point (in value coordinates) of the
156  * coordinate plane, that is used for zoom operations.
157  */
158  virtual QPointF zoomCenter() const { return QPointF(0.0, 0.0); }
159 
160  /**
161  * Set the point (in value coordinates) to be used as the
162  * center point in zoom operations.
163  * @param center The point to use.
164  */
165  virtual void setZoomCenter( const QPointF& center ) { Q_UNUSED( center ); }
166 
167  /**
168  * Set the grid attributes to be used by this coordinate plane.
169  * To disable grid painting, for example, your code should like this:
170  * \code
171  * GridAttributes ga = plane->globalGridAttributes();
172  * ga.setGlobalGridVisible( false );
173  * plane->setGlobalGridAttributes( ga );
174  * \endcode
175  * \sa globalGridAttributes
176  * \sa CartesianCoordinatePlane::setGridAttributes
177  */
178  void setGlobalGridAttributes( const GridAttributes & );
179 
180  /**
181  * @return The grid attributes used by this coordinate plane.
182  * \sa setGlobalGridAttributes
183  * \sa CartesianCoordinatePlane::gridAttributes
184  */
185  GridAttributes globalGridAttributes() const;
186 
187  /**
188  * Returns the dimensions used for drawing the grid lines.
189  *
190  * Returned data is the result of (cached) grid calculations,
191  * so - if you need that information for your own tasks - make sure to
192  * call again this function after every data modification that has changed
193  * the data range, since grid calculation is based upon the data range,
194  * thus the grid start/end might have changed if the data was changed.
195  *
196  * @note Returned list will contain different numbers of DataDimension,
197  * depending on the kind of coordinate plane used.
198  * For CartesianCoordinatePlane two DataDimension are returned: the first
199  * representing grid lines in X direction (matching the Abscissa axes)
200  * and the second indicating vertical grid lines (or Ordinate axes, resp.).
201  *
202  * @return The dimensions used for drawing the grid lines.
203  * @sa DataDimension
204  */
205  DataDimensionsList gridDimensionsList();
206 
207  /**
208  * Set another coordinate plane to be used as the reference plane
209  * for this one.
210  * @param plane The coordinate plane to be used the reference plane
211  * for this one.
212  * @see referenceCoordinatePlane
213  */
214  void setReferenceCoordinatePlane( AbstractCoordinatePlane * plane );
215 
216  /**
217  * There are two ways, in which planes can be caused to interact, in
218  * where they are put layouting wise: The first is the reference plane. If
219  * such a reference plane is set, on a plane, it will use the same cell in the
220  * layout as that one. In addition to this, planes can share an axis. In that case
221  * they will be laid out in relation to each other as suggested by the position
222  * of the axis. If, for example Plane1 and Plane2 share an axis at position Left,
223  * that will result in the layout: Axis Plane1 Plane 2, vertically. If Plane1
224  * also happens to be Plane2's reference plane, both planes are drawn over each
225  * other. The reference plane concept allows two planes to share the same space
226  * even if neither has any axis, and in case there are shared axis, it is used
227  * to decided, whether the planes should be painted on top of each other or
228  * laid out vertically or horizontally next to each other.
229  * @return The reference coordinate plane associated with this one.
230  */
231  AbstractCoordinatePlane * referenceCoordinatePlane() const;
232 
233  /**
234  * @return Whether this plane should have spacers in the corners
235  * formed by the presence of axes.
236  */
237  bool isCornerSpacersEnabled() const;
238 
239  /**
240  * Enables or disables the use of spacers in the plane corners.
241  */
242  void setCornerSpacersEnabled( bool enable );
243 
244  virtual AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = nullptr ); // KChart 3: const method?
245 
246 
247  /** pure virtual in QLayoutItem */
248  bool isEmpty() const override;
249  /** pure virtual in QLayoutItem */
250  Qt::Orientations expandingDirections() const override;
251  /** pure virtual in QLayoutItem */
252  QSize maximumSize() const override;
253  /** pure virtual in QLayoutItem */
254  QSize minimumSize() const override;
255  /** pure virtual in QLayoutItem */
256  QSize sizeHint() const override;
257  /** pure virtual in QLayoutItem
258  *
259  * \note Do not call this function directly, unless you know
260  * exactly what you are doing. Geometry management is done
261  * by KChart's internal layouting measures.
262  */
263  void setGeometry( const QRect& r ) override;
264  /** pure virtual in QLayoutItem */
265  QRect geometry() const override;
266 
267  virtual void mousePressEvent( QMouseEvent* event );
268  virtual void mouseDoubleClickEvent( QMouseEvent* event );
269  virtual void mouseMoveEvent( QMouseEvent* event );
270  virtual void mouseReleaseEvent( QMouseEvent* event );
271 
272  /**
273  * Called internally by KChart::Chart
274  */
275  void setParent( Chart* parent );
276  Chart* parent();
277  const Chart* parent() const;
278 
279  /**
280  * Tests, if a point is visible on the coordinate plane.
281  *
282  * \note Before calling this function the point must have been translated into coordinate plane space.
283  */
284 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
285  const bool isVisiblePoint( const QPointF& point ) const;
286 #else
287  bool isVisiblePoint( const QPointF& point ) const;
288 #endif
289 
290  public Q_SLOTS:
291  /**
292  * Calling update() on the plane triggers the global KChart::Chart::update()
293  */
294  void update();
295  /**
296  * Calling relayout() on the plane triggers the global KChart::Chart::slotRelayout()
297  */
298  void relayout();
299  /**
300  * Calling layoutPlanes() on the plane triggers the global KChart::Chart::slotLayoutPlanes()
301  */
302  void layoutPlanes();
303  /**
304  * Used by the chart to clear the cached grid data.
305  */
306  void setGridNeedsRecalculate();
307 
308  Q_SIGNALS:
309  /** Emitted when this coordinate plane is destroyed. */
310  void destroyedCoordinatePlane( KChart::AbstractCoordinatePlane* );
311 
312  /** Emitted when plane needs to update its drawings. */
313  void needUpdate();
314 
315  /** Emitted when plane needs to trigger the Chart's layouting. */
316  void needRelayout();
317 
318  /** Emitted when plane needs to trigger the Chart's layouting of the coord. planes. */
319  void needLayoutPlanes();
320 
321  /** Emitted upon change of a property of the Coordinate Plane or any of its components. */
322  void propertiesChanged();
323 
324  void boundariesChanged();
325 
326  /** Emitted after the geometry of the Coordinate Plane has been changed.
327  * and control has returned to the event loop.
328  *
329  * Parameters are the old geometry, the new geometry.
330  */
331  void geometryChanged( QRect, QRect );
332 
333  private:
334  Q_SIGNALS:
335  // Emitted from inside the setGeometry()
336  // This is connected via QueuedConnection to the geometryChanged() Signal
337  // that users can connect to safely then.
338  void internal_geometryChanged( QRect, QRect );
339  /** Emitted upon change of the view coordinate system */
340  void viewportCoordinateSystemChanged();
341 
342  protected:
343  virtual DataDimensionsList getDataDimensionsList() const = 0;
344 
345  //KCHART_DECLARE_PRIVATE_DERIVED( AbstractCoordinatePlane )
346  };
347 
348  /**
349  * \brief Helper class for one dimension of data, e.g. for the rows in a data model,
350  * or for the labels of an axis, or for the vertical lines in a grid.
351  *
352  * isCalculated specifies whether this dimension's values are calculated or counted.
353  * (counted == "Item 1", "Item 2", "Item 3" ...)
354  *
355  * sequence is the GranularitySequence, as specified at for the respective
356  * coordinate plane.
357  *
358  * Step width is an optional parameter, to be omitted (or set to Zero, resp.)
359  * if the step width is unknown.
360  *
361  * The default c'tor just gets you counted values from 1..10, using step width 1,
362  * used by the CartesianGrid, when showing an empty plane without any diagrams.
363  */
365  public:
366  DataDimension()
367  : start( 1.0 )
368  , end( 10.0 )
369  , isCalculated( false )
370  , calcMode( AbstractCoordinatePlane::Linear )
371  , sequence( KChartEnums::GranularitySequence_10_20 )
372  , stepWidth( 1.0 )
373  , subStepWidth( 0.0 )
374  {}
375  DataDimension( qreal start_,
376  qreal end_,
377  bool isCalculated_,
378  AbstractCoordinatePlane::AxesCalcMode calcMode_,
380  qreal stepWidth_=0.0,
381  qreal subStepWidth_=0.0 )
382  : start( start_ )
383  , end( end_ )
384  , isCalculated( isCalculated_ )
385  , calcMode( calcMode_ )
386  , sequence( sequence_ )
387  , stepWidth( stepWidth_ )
388  , subStepWidth( subStepWidth_ )
389  {}
390  /**
391  * Returns the size of the distance,
392  * equivalent to the width() (or height(), resp.) of a QRectF.
393  *
394  * Note that this value can be negative, e.g. indicating axis labels
395  * going in reversed direction.
396  */
397  qreal distance() const
398  {
399  return end-start;
400  }
401 
402  bool operator==( const DataDimension& r ) const
403  {
404  return
405  (start == r.start) &&
406  (end == r.end) &&
407  (sequence == r.sequence) &&
408  (isCalculated == r.isCalculated) &&
409  (calcMode == r.calcMode) &&
410  (stepWidth == r.stepWidth) &&
411  (subStepWidth == r.subStepWidth);
412  }
413 
414  bool operator!=( const DataDimension& other ) const
415  { return !operator==( other ); }
416 
417 
418  qreal start;
419  qreal end;
420  bool isCalculated;
421  AbstractCoordinatePlane::AxesCalcMode calcMode;
423  qreal stepWidth;
424  qreal subStepWidth;
425  };
426 
427 #if !defined(QT_NO_DEBUG_STREAM)
428  QDebug operator<<( QDebug stream, const DataDimension& r );
429 #endif
430 
431 }
432 #endif
qreal distance() const
Returns the size of the distance, equivalent to the width() (or height(), resp.) of a QRectF.
An area in the chart with a background, a frame, etc.
virtual void setZoomFactorX(qreal factor)
Sets the zoom factor in horizontal direction, that is applied to all coordinate transformations.
virtual void setZoomCenter(const QPointF &center)
Set the point (in value coordinates) to be used as the center point in zoom operations.
KCALENDARCORE_EXPORT QDataStream & operator<<(QDataStream &out, const KCalendarCore::Alarm::Ptr &)
virtual void setZoomFactors(qreal factorX, qreal factorY)
Sets both zoom factors in one go.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
Abstract base class for grid classes: cartesian, polar, ...
virtual void setZoomFactorY(qreal factor)
Sets the zoom factor in vertical direction, that is applied to all coordinate transformations.
typedef Orientations
GranularitySequence
GranularitySequence specifies the values, that may be applied, to determine a step width within a giv...
Definition: KChartEnums.h:78
Definition of global enums.
A set of attributes controlling the appearance of grids.
AbstractDiagram defines the interface for diagram classes.
Helper class for one dimension of data, e.g.
A chart with one or more diagrams.
Definition: KChartChart.h:84
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Nov 30 2023 03:54:21 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.