KChart

KChartCartesianCoordinatePlane.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 KCHARTCARTESIANCOORDINATEPLANE_H
10 #define KCHARTCARTESIANCOORDINATEPLANE_H
11 
12 #include "KChartAbstractCoordinatePlane.h"
13 
14 namespace KChart {
15 
16  class Chart;
17  class PaintContext;
18  class AbstractDiagram;
19  class CartesianAxis;
20  class CartesianGrid;
21 
22  /**
23  * @brief Cartesian coordinate plane
24  */
26  {
27  Q_OBJECT
28 
29  Q_DISABLE_COPY( CartesianCoordinatePlane )
30  KCHART_DECLARE_PRIVATE_DERIVED_PARENT( CartesianCoordinatePlane, Chart* )
31 
32  friend class CartesianAxis;
33  friend class CartesianGrid;
34 
35  public:
36  explicit CartesianCoordinatePlane ( Chart* parent = nullptr );
38 
39  void addDiagram ( AbstractDiagram* diagram ) override;
40 
41  /**
42  * If @p onOff is true, enforce that X and Y distances are scaled by the same factor.
43  * This makes the plane's height a function of its width, and hasHeightForWidth()
44  * will return true.
45  */
46  void setIsometricScaling ( bool onOff );
47 
48  bool doesIsometricScaling() const;
49 
50  const QPointF translate ( const QPointF& diagramPoint ) const override;
51 
52  /**
53  * \sa setZoomFactorX, setZoomCenter
54  */
55  qreal zoomFactorX() const override;
56  /**
57  * \sa setZoomFactorY, setZoomCenter
58  */
59  qreal zoomFactorY() const override;
60 
61  /**
62  * \sa setZoomFactorX,setZoomFactorY
63  */
64  void setZoomFactors( qreal factorX, qreal factorY ) override;
65  /**
66  * \sa zoomFactorX, setZoomCenter
67  */
68  void setZoomFactorX( qreal factor ) override;
69  /**
70  * \sa zoomFactorY, setZoomCenter
71  */
72  void setZoomFactorY( qreal factor ) override;
73 
74  /**
75  * \sa setZoomCenter, setZoomFactorX, setZoomFactorY
76  */
77  QPointF zoomCenter() const override;
78 
79  /**
80  * \sa zoomCenter, setZoomFactorX, setZoomFactorY
81  */
82  void setZoomCenter( const QPointF& center ) override;
83 
84  /**
85  * Allows to specify a fixed data-space / coordinate-space relation. If set
86  * to true then fixed bar widths are used, so you see more bars as the window
87  * is made wider.
88  *
89  * This allows to completely restrict the size of bars in a graph such that,
90  * upon resizing a window, the graphs coordinate plane will grow (add more
91  * ticks to x- and y-coordinates) rather than have the image grow.
92  */
93  void setFixedDataCoordinateSpaceRelation( bool fixed );
94  bool hasFixedDataCoordinateSpaceRelation() const;
95 
96  /**
97  * Allows to fix the lower bound of X axis to zero when diagram is in first quadrant.
98  *
99  * The default behavior is to lower x or y bound to be 0. If this behaviour is not wanted,
100  * either \a CartesianCoordinatePlane::setHorizontalRange could be used instead of letting
101  * KChart auto-adjust the ranges, or this method can be used to disable this behavior.
102  */
103  void setXAxisStartAtZero(bool fixedStart);
104  bool xAxisStartAtZero() const;
105 
106  /**
107  * \brief Set the boundaries of the visible value space displayed in horizontal direction.
108  *
109  * This is also known as the horizontal viewport.
110  *
111  * By default the horizontal range is adjusted to the range covered by the model's data,
112  * see setAutoAdjustHorizontalRangeToData for details.
113  * Calling setHorizontalRange with a valid range disables this default automatic adjusting,
114  * while on the other hand automatic adjusting will set these ranges.
115  *
116  * To disable use of this range you can either pass an empty pair by using the default
117  * constructor QPair() or you can set both values to the same which constitutes
118  * a null range.
119  *
120  * \note By default the visible data range often is larger than the
121  * range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.).
122  * This is due to the built-in grid calculation feature: The visible start/end
123  * values get adjusted so that they match a main-grid line.
124  * You can turn this feature off for any of the four bounds by calling
125  * GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes
126  * or for the horizontal/vertical attrs separately.
127  *
128  * \note To set only one of the ends of the range to a fixed value while keeping
129  * the other dynamically adjusted, use std::numeric_limits< qreal >::quiet_NaN()
130  * for the dynamic value.
131  *
132  * \note If you use user defined vertical ranges together with logarithmic scale, only
133  * positive values are supported. If you set it to negative values, the result is undefined.
134  *
135  * \param range a pair of values representing the smallest and the largest
136  * horizontal value space coordinate displayed.
137  *
138  * \sa setAutoAdjustHorizontalRangeToData, setVerticalRange
139  * \sa GridAttributes::setAdjustBoundsToGrid()
140  */
141  void setHorizontalRange( const QPair<qreal, qreal> & range );
142 
143  /**
144  * \brief Set the boundaries of the visible value space displayed in vertical direction.
145  *
146  * This is also known as the vertical viewport.
147  *
148  * By default the vertical range is adjusted to the range covered by the model's data,
149  * see setAutoAdjustVerticalRangeToData for details.
150  * Calling setVerticalRange with a valid range disables this default automatic adjusting,
151  * while on the other hand automatic adjusting will set these ranges.
152  *
153  * To disable use of this range you can either pass an empty pair by using the default
154  * constructor QPair() or you can set setting both values to the same which constitutes
155  * a null range.
156  *
157  * \note By default the visible data range often is larger than the
158  * range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.).
159  * This is due to the built-in grid calculation feature: The visible start/end
160  * values get adjusted so that they match a main-grid line.
161  * You can turn this feature off for any of the four bounds by calling
162  * GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes
163  * or for the horizontal/vertical attrs separately.
164  *
165  * \note To set only one of the ends of the range to a fixed value while keeping
166  * the other dynamically adjusted, use std::numeric_limits< qreal >::quiet_NaN()
167  * for the dynamic value.
168  *
169  * \note If you use user defined vertical ranges together with logarithmic scale, only
170  * positive values are supported. If you set it to negative values, the result is undefined.
171  *
172  * \param range a pair of values representing the smallest and the largest
173  * vertical value space coordinate displayed.
174  *
175  * \sa setAutoAdjustVerticalRangeToData, setHorizontalRange
176  * \sa GridAttributes::setAdjustBoundsToGrid()
177  */
178  void setVerticalRange( const QPair<qreal, qreal> & range );
179 
180  /**
181  * @return The largest and smallest visible horizontal value space
182  * value. If this is not explicitly set,or if both values are the same,
183  * the plane will use the union of the dataBoundaries of all
184  * associated diagrams.
185  * \see KChart::AbstractDiagram::dataBoundaries
186  */
187  QPair<qreal, qreal> horizontalRange() const;
188 
189  /**
190  * @return The largest and smallest visible horizontal value space
191  * value. If this is not explicitly set, or if both values are the same,
192  * the plane will use the union of the dataBoundaries of all
193  * associated diagrams.
194  * \see KChart::AbstractDiagram::dataBoundaries
195  */
196  QPair<qreal, qreal> verticalRange() const;
197 
198  /**
199  * \brief Automatically adjust horizontal range settings to the ranges covered by
200  * the model's values, when ever the data have changed, and then emit horizontalRangeAutomaticallyAdjusted.
201  *
202  * By default the horizontal range is adjusted automatically, if more than 67 percent of
203  * the available horizontal space would be empty otherwise.
204  *
205  * Range setting is adjusted if more than \c percentEmpty percent of the horizontal
206  * space covered by the coordinate plane would otherwise be empty.
207  * Automatic range adjusting can happen, when either all of the data are positive or all are negative.
208  *
209  * Set percentEmpty to 100 to disable automatic range adjusting.
210  *
211  * \param percentEmpty The maximal percentage of horizontal space that may be empty.
212  *
213  * \sa horizontalRangeAutomaticallyAdjusted
214  * \sa autoAdjustHorizontalRangeToData, adjustRangesToData
215  * \sa setHorizontalRange, setVerticalRange
216  * \sa setAutoAdjustVerticalRangeToData
217  */
218  void setAutoAdjustHorizontalRangeToData( unsigned int percentEmpty = 67 );
219 
220  /**
221  * \brief Automatically adjust vertical range settings to the ranges covered by
222  * the model's values, when ever the data have changed, and then emit verticalRangeAutomaticallyAdjusted.
223  *
224  * By default the vertical range is adjusted automatically, if more than 67 percent of
225  * the available vertical space would be empty otherwise.
226  *
227  * Range setting is adjusted if more than \c percentEmpty percent of the horizontal
228  * space covered by the coordinate plane would otherwise be empty.
229  * Automatic range adjusting can happen, when either all of the data are positive or all are negative.
230  *
231  * Set percentEmpty to 100 to disable automatic range adjusting.
232  *
233  * \param percentEmpty The maximal percentage of horizontal space that may be empty.
234  *
235  * \sa verticalRangeAutomaticallyAdjusted
236  * \sa autoAdjustVerticalRangeToData, adjustRangesToData
237  * \sa setHorizontalRange, setVerticalRange
238  * \sa setAutoAdjustHorizontalRangeToData
239  */
240  void setAutoAdjustVerticalRangeToData( unsigned int percentEmpty = 67 );
241 
242  /**
243  * \brief Returns the maximal allowed percent of the horizontal
244  * space covered by the coordinate plane that may be empty.
245  *
246  * \return A percent value indicating how much of the horizontal space may be empty.
247  * If more than this is empty, automatic range adjusting is applied.
248  * A return value of 100 indicates that no such automatic adjusting is done at all.
249  *
250  * \sa setAutoAdjustHorizontalRangeToData, adjustRangesToData
251  */
252  unsigned int autoAdjustHorizontalRangeToData() const;
253 
254  /**
255  * \brief Returns the maximal allowed percent of the vertical
256  * space covered by the coordinate plane that may be empty.
257  *
258  * \return A percent value indicating how much of the vertical space may be empty.
259  * If more than this is empty, automatic range adjusting is applied.
260  * A return value of 100 indicates that no such automatic adjusting is done at all.
261  *
262  * \sa setAutoAdjustVerticalRangeToData, adjustRangesToData
263  */
264  unsigned int autoAdjustVerticalRangeToData() const;
265 
266 
267  /**
268  * Set the attributes to be used for grid lines drawn in horizontal
269  * direction (or in vertical direction, resp.).
270  *
271  * To disable horizontal grid painting, for example, your code should like this:
272  * \code
273  * GridAttributes ga = plane->gridAttributes( Qt::Horizontal );
274  * ga.setGridVisible( false );
275  * plane-setGridAttributes( Qt::Horizontal, ga );
276  * \endcode
277  *
278  * \note setGridAttributes overwrites the global attributes that
279  * were set by AbstractCoordinatePlane::setGlobalGridAttributes.
280  * To re-activate these global attributes you can call
281  * resetGridAttributes.
282  *
283  * \sa resetGridAttributes, gridAttributes
284  * \sa setAutoAdjustGridToZoom
285  * \sa AbstractCoordinatePlane::setGlobalGridAttributes
286  * \sa hasOwnGridAttributes
287  */
288  void setGridAttributes( Qt::Orientation orientation, const GridAttributes & );
289 
290  /**
291  * Reset the attributes to be used for grid lines drawn in horizontal
292  * direction (or in vertical direction, resp.).
293  * By calling this method you specify that the global attributes set by
294  * AbstractCoordinatePlane::setGlobalGridAttributes be used.
295  *
296  * \sa setGridAttributes, gridAttributes
297  * \sa setAutoAdjustGridToZoom
298  * \sa AbstractCoordinatePlane::globalGridAttributes
299  * \sa hasOwnGridAttributes
300  */
301  void resetGridAttributes( Qt::Orientation orientation );
302 
303  /**
304  * \return The attributes used for grid lines drawn in horizontal
305  * direction (or in vertical direction, resp.).
306  *
307  * \note This function always returns a valid set of grid attributes:
308  * If no special grid attributes were set foe this orientation
309  * the global attributes are returned, as returned by
310  * AbstractCoordinatePlane::globalGridAttributes.
311  *
312  * \sa setGridAttributes
313  * \sa resetGridAttributes
314  * \sa AbstractCoordinatePlane::globalGridAttributes
315  * \sa hasOwnGridAttributes
316  */
317  const GridAttributes gridAttributes( Qt::Orientation orientation ) const;
318 
319  /**
320  * \return Returns whether the grid attributes have been set for the
321  * respective direction via setGridAttributes( orientation ).
322  *
323  * If false, the grid will use the global attributes set
324  * by AbstractCoordinatePlane::globalGridAttributes (or the default
325  * attributes, resp.)
326  *
327  * \sa setGridAttributes
328  * \sa resetGridAttributes
329  * \sa AbstractCoordinatePlane::globalGridAttributes
330  */
331  bool hasOwnGridAttributes( Qt::Orientation orientation ) const;
332 
333  /**
334  * Disable / re-enable the built-in grid adjusting feature.
335  *
336  * By default additional lines will be drawn in a Linear grid when zooming in.
337  *
338  * \sa autoAdjustGridToZoom, setGridAttributes
339  */
340  void setAutoAdjustGridToZoom( bool autoAdjust );
341 
342  /**
343  * Return the status of the built-in grid adjusting feature.
344  *
345  * \sa setAutoAdjustGridToZoom
346  */
347 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
348  const bool autoAdjustGridToZoom() const;
349 #else
350  bool autoAdjustGridToZoom() const;
351 #endif
352 
353  AxesCalcMode axesCalcModeY() const;
354  AxesCalcMode axesCalcModeX() const;
355 
356  /** Specifies the calculation modes for all axes */
357  void setAxesCalcModes( AxesCalcMode mode );
358  /** Specifies the calculation mode for all Ordinate axes */
359  void setAxesCalcModeY( AxesCalcMode mode );
360  /** Specifies the calculation mode for all Abscissa axes */
361  void setAxesCalcModeX( AxesCalcMode mode );
362 
363  /** reimpl */
364  void paint( QPainter* ) override;
365 
366  /** reimpl */
367  AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = nullptr ) override;
368 
369  /**
370  * Returns the currently visible data range. Might be greater than the
371  * range of the grid.
372  */
373  QRectF visibleDataRange() const;
374 
375  /**
376  * Returns the logical area, i.e., the rectangle defined by the very top
377  * left and very bottom right coordinate.
378  */
379  QRectF logicalArea() const;
380 
381  /**
382  * Returns the (physical) area occupied by the diagram. Unless zoom is applied
383  * (which is also true when a fixed data coordinate / space relation is used),
384  * \code diagramArea() == drawingArea() \endcode .
385  * \sa setFixedDataCoordinateSpaceRelation
386  * \sa drawingArea
387  */
388  QRectF diagramArea() const;
389 
390  /**
391  * Returns the visible part of the diagram area, i.e.
392  * \code diagramArea().intersected( drawingArea() ) \endcode
393  * \sa diagramArea
394  */
395  QRectF visibleDiagramArea() const;
396 
397  /**
398  * Sets whether the horizontal range should be reversed or not, i.e.
399  * small values to the left and large values to the right (the default)
400  * or vice versa.
401  * \param reverse Whether the horizontal range should be reversed or not
402  */
403  void setHorizontalRangeReversed( bool reverse );
404 
405  /**
406  * \return Whether the horizontal range is reversed or not
407  */
408  bool isHorizontalRangeReversed() const;
409 
410  /**
411  * Sets whether the vertical range should be reversed or not, i.e.
412  * small values at the bottom and large values at the top (the default)
413  * or vice versa.
414  * \param reverse Whether the vertical range should be reversed or not
415  */
416  void setVerticalRangeReversed( bool reverse );
417 
418  /**
419  * \return Whether the vertical range is reversed or not
420  */
421  bool isVerticalRangeReversed() const;
422 
423  /**
424  * reimplemented from AbstractCoordinatePlane
425  */
426  void setGeometry( const QRect& r ) override;
427 
428  // reimplemented
429  Qt::Orientations expandingDirections() const override;
430 
431 
432  public Q_SLOTS:
433  /**
434  * \brief Adjust both, horizontal and vertical range settings to the
435  * ranges covered by the model's data values.
436  *
437  * \sa setHorizontalRange, setVerticalRange
438  * \sa adjustHorizontalRangeToData, adjustVerticalRangeToData
439  * \sa setAutoAdjustHorizontalRangeToData, setAutoAdjustVerticalRangeToData
440  */
441  void adjustRangesToData();
442 
443  /**
444  * Adjust horizontal range settings to the ranges covered by the model's data values.
445  * \sa adjustRangesToData
446  */
447  void adjustHorizontalRangeToData();
448 
449  /**
450  * Adjust vertical range settings to the ranges covered by the model's data values.
451  * \sa adjustRangesToData
452  */
453  void adjustVerticalRangeToData();
454 
455  protected:
456  QRectF getRawDataBoundingRectFromDiagrams() const;
457  QRectF adjustedToMaxEmptyInnerPercentage(
458  const QRectF& r, unsigned int percentX, unsigned int percentY ) const;
459  virtual QRectF calculateRawDataBoundingRect() const;
460  DataDimensionsList getDataDimensionsList() const override;
461  // the whole drawing area, includes diagrams and axes, but maybe smaller
462  // than (width, height):
463  virtual QRectF drawingArea() const;
464  public:
465  const QPointF translateBack( const QPointF& screenPoint ) const;
466  protected:
467  void paintEvent ( QPaintEvent* );
468  void layoutDiagrams() override;
469  // the following three return true if the new value is different from the old
470  bool doneSetZoomFactorX( qreal factor );
471  bool doneSetZoomFactorY( qreal factor );
472  bool doneSetZoomCenter( const QPointF& center );
473 
474  void handleFixedDataCoordinateSpaceRelation( const QRectF& geometry );
475 
476  // reimplemented from QLayoutItem, via AbstractLayoutItem, AbstractArea, AbstractCoordinatePlane
477  bool hasHeightForWidth() const override;
478  int heightForWidth( int w ) const override;
479  QSize sizeHint() const override;
480 
481  protected Q_SLOTS:
482  void slotLayoutChanged( KChart::AbstractDiagram* );
483 
484  private:
485  void setHasOwnGridAttributes(
486  Qt::Orientation orientation, bool on );
487  };
488 
489 }
490 
491 #endif
AbstractDiagram defines the interface for diagram classes.
The class for cartesian axes.
Class for the grid in a cartesian plane.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane.
A set of attributes controlling the appearance of grids.
A chart with one or more diagrams.
Definition: KChartChart.h:84
Orientation
Global namespace.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Oct 21 2021 22:37:37 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.