KChart

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