KChart

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

KDE's Doxygen guidelines are available online.