/**************************************************************************** ** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved. ** ** This file is part of the KD Chart library. ** ** Licensees holding valid commercial KD Chart licenses may use this file in ** accordance with the KD Chart Commercial License Agreement provided with ** the Software. ** ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 and version 3 as published by the ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** Contact info@kdab.com if any conditions of this licensing are not ** clear to you. ** **********************************************************************/ #ifndef KDCHARTCARTESIANCOORDINATEPLANE_H #define KDCHARTCARTESIANCOORDINATEPLANE_H #include "KDChartAbstractCoordinatePlane.h" namespace KDChart { class Chart; class PaintContext; class AbstractDiagram; class CartesianAxis; class CartesianGrid; /** * @brief Cartesian coordinate plane */ class KDCHART_EXPORT CartesianCoordinatePlane : public AbstractCoordinatePlane { Q_OBJECT Q_DISABLE_COPY( CartesianCoordinatePlane ) KDCHART_DECLARE_PRIVATE_DERIVED_PARENT( CartesianCoordinatePlane, Chart* ) friend class CartesianAxis; friend class CartesianGrid; public: explicit CartesianCoordinatePlane ( Chart* parent = 0 ); ~CartesianCoordinatePlane(); void addDiagram ( AbstractDiagram* diagram ); void setIsometricScaling ( bool onOff ); bool doesIsometricScaling() const; const QPointF translate ( const QPointF& diagramPoint ) const; /** * \sa setZoomFactorX, setZoomCenter */ virtual double zoomFactorX() const; /** * \sa setZoomFactorY, setZoomCenter */ virtual double zoomFactorY() const; /** * \sa setZoomFactorX,setZoomFactorY */ virtual void setZoomFactors( double factorX, double factorY ); /** * \sa zoomFactorX, setZoomCenter */ virtual void setZoomFactorX( double factor ); /** * \sa zoomFactorY, setZoomCenter */ virtual void setZoomFactorY( double factor ); /** * \sa setZoomCenter, setZoomFactorX, setZoomFactorY */ virtual QPointF zoomCenter() const; /** * \sa zoomCenter, setZoomFactorX, setZoomFactorY */ virtual void setZoomCenter( const QPointF& center ); /** * Allows to specify a fixed data-space / coordinate-space relation. If set * to true then fixed bar widths are used, so you see more bars as the window * is made wider. * * This allows to completely restrict the size of bars in a graph such that, * upon resizing a window, the graphs coordinate plane will grow (add more * ticks to x- and y-coordinates) rather than have the image grow. */ void setFixedDataCoordinateSpaceRelation( bool fixed ); bool hasFixedDataCoordinateSpaceRelation() const; /** * Allows to fix the lower bound of X axis to zero when diagram is in first quadrant. * * The default behavior is to lower x or y bound to be 0. If this behaviour is not wanted, * either \a CartesianCoordinatePlane::setHorizontalRange could be used instead of letting * KDChart auto-adjust the ranges, or this method can be used to disable this behavior. */ void setXAxisStartAtZero(bool fixedStart); bool xAxisStartAtZero() const; /** * \brief Set the boundaries of the visible value space displayed in horizontal direction. * * This is also known as the horizontal viewport. * * By default the horizontal range is adjusted to the range covered by the model's data, * see setAutoAdjustHorizontalRangeToData for details. * Calling setHorizontalRange with a valid range disables this default automatic adjusting, * while on the other hand automatic adjusting will set these ranges. * * To disable use of this range you can either pass an empty pair by using the default * constructor QPair() or you can set both values to the same which constitutes * a null range. * * \note By default the visible data range often is larger than the * range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.). * This is due to the built-in grid calculation feature: The visible start/end * values get adjusted so that they match a main-grid line. * You can turn this feature off for any of the four bounds by calling * GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes * or for the horizontal/vertical attrs separately. * * \note If you use user defined vertical ranges together with logarithmic scale, only * positive values are supported. If you set it to negative values, the result is undefined. * * \param range a pair of values representing the smalles and the largest * horizontal value space coordinate displayed. * * \sa setAutoAdjustHorizontalRangeToData, setVerticalRange * \sa GridAttributes::setAdjustBoundsToGrid() */ void setHorizontalRange( const QPair & range ); /** * \brief Set the boundaries of the visible value space displayed in vertical direction. * * This is also known as the vertical viewport. * * By default the vertical range is adjusted to the range covered by the model's data, * see setAutoAdjustVerticalRangeToData for details. * Calling setVerticalRange with a valid range disables this default automatic adjusting, * while on the other hand automatic adjusting will set these ranges. * * To disable use of this range you can either pass an empty pair by using the default * constructor QPair() or you can set setting both values to the same which constitutes * a null range. * * \note By default the visible data range often is larger than the * range calculated from the data model (or set by setHoriz.|Vert.Range(), resp.). * This is due to the built-in grid calculation feature: The visible start/end * values get adjusted so that they match a main-grid line. * You can turn this feature off for any of the four bounds by calling * GridAttributes::setAdjustBoundsToGrid() for either the global grid-attributes * or for the horizontal/vertical attrs separately. * * \note If you use user defined vertical ranges together with logarithmic scale, only * positive values are supported. If you set it to negative values, the result is undefined. * * \param range a pair of values representing the smalles and the largest * vertical value space coordinate displayed. * * \sa setAutoAdjustVerticalRangeToData, setHorizontalRange * \sa GridAttributes::setAdjustBoundsToGrid() */ void setVerticalRange( const QPair & range ); /** * @return The largest and smallest visible horizontal value space * value. If this is not explicitly set,or if both values are the same, * the plane will use the union of the dataBoundaries of all * associated diagrams. * \see KDChart::AbstractDiagram::dataBoundaries */ QPair horizontalRange() const; /** * @return The largest and smallest visible horizontal value space * value. If this is not explicitly set, or if both values are the same, * the plane will use the union of the dataBoundaries of all * associated diagrams. * \see KDChart::AbstractDiagram::dataBoundaries */ QPair verticalRange() const; /** * \brief Automatically adjust horizontal range settings to the ranges covered by * the model's values, when ever the data have changed, and then emit horizontalRangeAutomaticallyAdjusted. * * By default the horizontal range is adjusted automatically, if more than 67 percent of * the available horizontal space would be empty otherwise. * * Range setting is adjusted if more than \c percentEmpty percent of the horizontal * space covered by the coordinate plane would otherwise be empty. * Automatic range adjusting can happen, when either all of the data are positive or all are negative. * * Set percentEmpty to 100 to disable automatic range adjusting. * * \param percentEmpty The maximal percentage of horizontal space that may be empty. * * \sa horizontalRangeAutomaticallyAdjusted * \sa autoAdjustHorizontalRangeToData, adjustRangesToData * \sa setHorizontalRange, setVerticalRange * \sa setAutoAdjustVerticalRangeToData */ void setAutoAdjustHorizontalRangeToData( unsigned int percentEmpty = 67 ); /** * \brief Automatically adjust vertical range settings to the ranges covered by * the model's values, when ever the data have changed, and then emit verticalRangeAutomaticallyAdjusted. * * By default the vertical range is adjusted automatically, if more than 67 percent of * the available vertical space would be empty otherwise. * * Range setting is adjusted if more than \c percentEmpty percent of the horizontal * space covered by the coordinate plane would otherwise be empty. * Automatic range adjusting can happen, when either all of the data are positive or all are negative. * * Set percentEmpty to 100 to disable automatic range adjusting. * * \param percentEmpty The maximal percentage of horizontal space that may be empty. * * \sa verticalRangeAutomaticallyAdjusted * \sa autoAdjustVerticalRangeToData, adjustRangesToData * \sa setHorizontalRange, setVerticalRange * \sa setAutoAdjustHorizontalRangeToData */ void setAutoAdjustVerticalRangeToData( unsigned int percentEmpty = 67 ); /** * \brief Returns the maximal allowed percent of the horizontal * space covered by the coordinate plane that may be empty. * * \return A percent value indicating how much of the horizontal space may be empty. * If more than this is empty, automatic range adjusting is applied. * A return value of 100 indicates that no such automatic adjusting is done at all. * * \sa setAutoAdjustHorizontalRangeToData, adjustRangesToData */ unsigned int autoAdjustHorizontalRangeToData() const; /** * \brief Returns the maximal allowed percent of the vertical * space covered by the coordinate plane that may be empty. * * \return A percent value indicating how much of the vertical space may be empty. * If more than this is empty, automatic range adjusting is applied. * A return value of 100 indicates that no such automatic adjusting is done at all. * * \sa setAutoAdjustVerticalRangeToData, adjustRangesToData */ unsigned int autoAdjustVerticalRangeToData() const; /** * Set the attributes to be used for grid lines drawn in horizontal * direction (or in vertical direction, resp.). * * To disable horizontal grid painting, for example, your code should like this: * \code * GridAttributes ga = plane->gridAttributes( Qt::Horizontal ); * ga.setGridVisible( false ); * plane-setGridAttributes( Qt::Horizontal, ga ); * \endcode * * \note setGridAttributes overwrites the global attributes that * were set by AbstractCoordinatePlane::setGlobalGridAttributes. * To re-activate these global attributes you can call * resetGridAttributes. * * \sa resetGridAttributes, gridAttributes * \sa setAutoAdjustGridToZoom * \sa AbstractCoordinatePlane::setGlobalGridAttributes * \sa hasOwnGridAttributes */ void setGridAttributes( Qt::Orientation orientation, const GridAttributes & ); /** * Reset the attributes to be used for grid lines drawn in horizontal * direction (or in vertical direction, resp.). * By calling this method you specify that the global attributes set by * AbstractCoordinatePlane::setGlobalGridAttributes be used. * * \sa setGridAttributes, gridAttributes * \sa setAutoAdjustGridToZoom * \sa AbstractCoordinatePlane::globalGridAttributes * \sa hasOwnGridAttributes */ void resetGridAttributes( Qt::Orientation orientation ); /** * \return The attributes used for grid lines drawn in horizontal * direction (or in vertical direction, resp.). * * \note This function always returns a valid set of grid attributes: * If no special grid attributes were set foe this orientation * the global attributes are returned, as returned by * AbstractCoordinatePlane::globalGridAttributes. * * \sa setGridAttributes * \sa resetGridAttributes * \sa AbstractCoordinatePlane::globalGridAttributes * \sa hasOwnGridAttributes */ const GridAttributes gridAttributes( Qt::Orientation orientation ) const; /** * \return Returns whether the grid attributes have been set for the * respective direction via setGridAttributes( orientation ). * * If false, the grid will use the global attributes set * by AbstractCoordinatePlane::globalGridAttributes (or the default * attributes, resp.) * * \sa setGridAttributes * \sa resetGridAttributes * \sa AbstractCoordinatePlane::globalGridAttributes */ bool hasOwnGridAttributes( Qt::Orientation orientation ) const; /** * Disable / re-enable the built-in grid adjusting feature. * * By default additional lines will be drawn in a Linear grid when zooming in. * * \sa autoAdjustGridToZoom, setGridAttributes */ void setAutoAdjustGridToZoom( bool autoAdjust ); /** * Return the status of the built-in grid adjusting feature. * * \sa setAutoAdjustGridToZoom */ #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE) const bool autoAdjustGridToZoom() const; #else bool autoAdjustGridToZoom() const; #endif AxesCalcMode axesCalcModeY() const; AxesCalcMode axesCalcModeX() const; /** Specifies the calculation modes for all axes */ void setAxesCalcModes( AxesCalcMode mode ); /** Specifies the calculation mode for all Ordinate axes */ void setAxesCalcModeY( AxesCalcMode mode ); /** Specifies the calculation mode for all Abscissa axes */ void setAxesCalcModeX( AxesCalcMode mode ); /** reimpl */ virtual void paint( QPainter* ); /** reimpl */ AbstractCoordinatePlane* sharedAxisMasterPlane( QPainter* p = 0 ); /** * Returns the currently visible data range. Might be greater than the * range of the grid. */ QRectF visibleDataRange() const; /** * Returns the logical area, i.e., the rectangle defined by the very top * left and very bottom right coordinate. */ QRectF logicalArea() const; /** * Returns the (physical) area occupied by the diagram. Unless zoom is applied * (which is also true when a fixed data coordinate / space relation is used), * \code diagramArea() == drawingArea() \endcode . * \sa setFixedDataCoordinateSpaceRelation * \sa drawingArea */ QRectF diagramArea() const; /** * Returns the visible part of the diagram area, i.e. * \code diagramArea().intersected( drawingArea() ) \endcode * \sa diagramArea */ QRectF visibleDiagramArea() const; /** * Sets whether the horizontal range should be reversed or not, i.e. * small values to the left and large values to the right (the default) * or vice versa. * \param reverse Whether the horizontal range should be reversed or not */ void setHorizontalRangeReversed( bool reverse ); /** * \return Whether the horizontal range is reversed or not */ bool isHorizontalRangeReversed() const; /** * Sets whether the vertical range should be reversed or not, i.e. * small values at the bottom and large values at the top (the default) * or vice versa. * \param reverse Whether the vertical range should be reversed or not */ void setVerticalRangeReversed( bool reverse ); /** * \return Whether the vertical range is reversed or not */ bool isVerticalRangeReversed() const; /** * reimplement from AbstractCoordinatePlane */ void setGeometry( const QRect& r ); public Q_SLOTS: /** * \brief Adjust both, horizontal and vertical range settings to the * ranges covered by the model's data values. * * \sa setHorizontalRange, setVerticalRange * \sa adjustHorizontalRangeToData, adjustVerticalRangeToData * \sa setAutoAdjustHorizontalRangeToData, setAutoAdjustVerticalRangeToData */ void adjustRangesToData(); /** * Adjust horizontal range settings to the ranges covered by the model's data values. * \sa adjustRangesToData */ void adjustHorizontalRangeToData(); /** * Adjust vertical range settings to the ranges covered by the model's data values. * \sa adjustRangesToData */ void adjustVerticalRangeToData(); protected: QRectF getRawDataBoundingRectFromDiagrams() const; QRectF adjustedToMaxEmptyInnerPercentage( const QRectF& r, unsigned int percentX, unsigned int percentY ) const; virtual QRectF calculateRawDataBoundingRect() const; virtual DataDimensionsList getDataDimensionsList() const; // the whole drawing area, includes diagrams and axes, but maybe smaller // than (width, height): virtual QRectF drawingArea() const; const QPointF translateBack( const QPointF& screenPoint ) const; void paintEvent ( QPaintEvent* ); void layoutDiagrams(); bool doneSetZoomFactorX( double factor ); bool doneSetZoomFactorY( double factor ); bool doneSetZoomCenter( const QPointF& center ); void handleFixedDataCoordinateSpaceRelation( const QRectF& geometry ); protected Q_SLOTS: void slotLayoutChanged( AbstractDiagram* ); private: void setHasOwnGridAttributes( Qt::Orientation orientation, bool on ); }; } #endif