2020-09-17 22:59:57 +08:00
/*
2022-07-19 19:40:43 +08:00
Copyright ( c ) 2008 - 2022 Jan W . Krieger ( < jan @ jkrieger . de > )
2020-09-17 22:59:57 +08:00
This software is free software : you can redistribute it and / or modify
it under the terms of the GNU Lesser General Public License ( LGPL ) as published by
the Free Software Foundation , either version 2.1 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Lesser General Public License ( LGPL ) for more details .
You should have received a copy of the GNU Lesser General Public License ( LGPL )
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2022-04-25 04:07:39 +08:00
# ifndef jkqtpgraphsbarchartbase_H
# define jkqtpgraphsbarchartbase_H
2020-09-17 22:59:57 +08:00
# include <QString>
# include <QPainter>
# include <QPair>
# include "jkqtplotter/jkqtptools.h"
# include "jkqtplotter/jkqtplotter_imexport.h"
# include "jkqtplotter/jkqtpimagetools.h"
# include "jkqtplotter/jkqtpgraphsbase.h"
# include "jkqtplotter/jkqtpgraphsbaseerrors.h"
# include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
/** \brief This is a base-class for all bar graphs with vertical or horizontal orientation (the orientation is implemented in dervied classes!)
* \ ingroup jkqtplotter_barssticks
*
* This class plots a bargraph . This image explains the parameters :
*
* \ image html bargraph_basics . png
*
* By default the sift parameter is , so the bar is centered at the x - value . The width is 0.9 ,
* so adjacent bars are plotted with a small distance between them . It is possible to use these two parameters
* to plot multiple bars for every x - value , by having on JKQTPSpecialLineHorizontalGraph object per
* set of bars that belong together . For example for three bars per x - value one would set :
* \ verbatim
* width = 0.3
* shift = - 0.3 / 0 / + 0.3
* \ endverbatim
* This results in a bargraph , as shown here :
*
2022-08-29 04:48:14 +08:00
* \ image html JKQTPBarVerticalGraph . png
2020-09-17 22:59:57 +08:00
*
2022-09-10 20:35:16 +08:00
* You can also set FillMode : : TwoColorFilling , which uses different fill styles for bars above and below
* the baseline of the graph :
2020-09-17 22:59:57 +08:00
*
2022-09-10 20:35:16 +08:00
* \ image html JKQTPBarVerticalGraphTwoColorFilling . png
2020-09-17 22:59:57 +08:00
*
* \ see JKQTPBarHorizontalGraph , JKQTPBarVerticalGraph
*/
2020-09-19 21:08:32 +08:00
class JKQTPLOTTER_LIB_EXPORT JKQTPBarGraphBase : public JKQTPXYBaselineGraph , public JKQTPGraphLineStyleMixin , public JKQTPGraphFillStyleMixin {
2020-09-17 22:59:57 +08:00
Q_OBJECT
public :
2022-09-10 20:35:16 +08:00
/** \brief specifies how the area below the graph is filled
*
* \ see setFillMode ( ) , getFillMode ( ) , fillStyleBelow ( ) , \ ref JKQTPlotterWigglePlots
*/
enum FillMode {
SingleFilling = 0 , /*!< \brief the whole area is filled with the same color/pattern \image html JKQTPBarVerticalGraph.png */
TwoColorFilling = 1 /*!< \brief the area above and below baseline with the two different colors/pattern \image html JKQTPBarVerticalGraphTwoColorFilling.png */
} ;
Q_ENUM ( FillMode )
2020-09-17 22:59:57 +08:00
/** \brief class constructor */
JKQTPBarGraphBase ( JKQTBasePlotter * parent = nullptr ) ;
/** \brief class constructor */
JKQTPBarGraphBase ( JKQTPlotter * parent ) ;
/** \brief plots a key marker inside the specified rectangle \a rect */
virtual void drawKeyMarker ( JKQTPEnhancedPainter & painter , QRectF & rect ) override ;
/** \brief returns the color to be used for the key label */
virtual QColor getKeyLabelColor ( ) const override ;
2020-09-21 19:47:54 +08:00
/** \copydoc shift */
2020-09-17 22:59:57 +08:00
double getShift ( ) const ;
2020-09-21 19:47:54 +08:00
/** \copydoc width */
2020-09-17 22:59:57 +08:00
double getWidth ( ) const ;
2020-09-19 21:08:32 +08:00
2020-09-17 22:59:57 +08:00
/** \brief sets the fill color and the color together, where fillColor is set to \a fill and the line-color is set to \c fill.darker(colorDarker)
* \ see setColor ( )
*/
void setFillColor_and_darkenedColor ( QColor fill , int colorDarker = 200 ) ;
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual int getBarPositionColumn ( ) const = 0 ;
/** \brief returns xColumn or yColumn, whichever is used for the height of the bars (depending on whether the barchart is vertical or horizontal \see getBarPositionColumn(), xColumn, yColumn */
virtual int getBarHeightColumn ( ) const = 0 ;
2022-09-10 20:35:16 +08:00
/** \copydoc m_fillStyleBelow */
JKQTPGraphFillStyleMixin & fillStyleBelow ( ) ;
/** \copydoc m_fillStyleBelow */
const JKQTPGraphFillStyleMixin & fillStyleBelow ( ) const ;
/** \copydoc m_fillMode */
FillMode getFillMode ( ) const ;
2022-09-27 07:42:54 +08:00
/** \copydoc rectRadiusAtValue */
double getRectRadiusAtValue ( ) const ;
/** \copydoc rectRadiusAtBaseline */
double getRectRadiusAtBaseline ( ) const ;
2020-09-17 22:59:57 +08:00
public slots :
2022-09-10 20:35:16 +08:00
/** \copydoc m_fillMode */
void setFillMode ( JKQTPBarGraphBase : : FillMode mode ) ;
2020-09-17 22:59:57 +08:00
/** \brief finds all bar charts of the same orientation and determines width and shift, so they stand side by side
*
* \ param maxWidth the maximum ( relative ) width , that all bars will span of the ( doubled ) inter - bar distance
* \ param shrinkFactor factor , by which the bar are shrinked compared to the available space
*
* \ note This function will scale ALL graphs of the parent plot , which were derived from JKQTPBarHorizontalGraph , that match in orientation ( as returned by isHorizontal ( ) ) .
*/
virtual void autoscaleBarWidthAndShift ( double maxWidth = 0.9 , double shrinkFactor = 0.8 ) ;
/** \brief equivalent to \c autoscaleBarWidthAndShift(groupWidth,1);
*/
void autoscaleBarWidthAndShiftSeparatedGroups ( double groupWidth = 0.75 ) ;
2020-09-21 19:47:54 +08:00
/** \copydoc shift */
2020-09-17 22:59:57 +08:00
void setShift ( double __value ) ;
2020-09-21 19:47:54 +08:00
/** \copydoc width */
2020-09-17 22:59:57 +08:00
void setWidth ( double __value ) ;
2020-09-19 21:08:32 +08:00
2022-09-27 07:42:54 +08:00
/** \copydoc rectRadiusAtValue */
void setRectRadiusAtValue ( double __value ) ;
/** \copydoc rectRadiusAtBaseline */
void setRectRadiusAtBaseline ( double __value ) ;
/** \brief sets the corner radius of the bars for both ends */
void setRectRadius ( double all ) ;
/** \brief sets the corner radius of the bars for both ends */
void setRectRadius ( double atValue , double atBaseline ) ;
2020-09-17 22:59:57 +08:00
/** \brief set outline and fill color at the same time
* \ see setFillColor_and_darkenedColor ( )
*/
virtual void setColor ( QColor c ) ;
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn ( int column ) = 0 ;
/** \brief returns xColumn or yColumn, whichever is used for the position of the bars (depending on whether the barchart is vertical or horizontal \see getBarHeightColumn(), xColumn, yColumn */
virtual void setBarPositionColumn ( size_t column ) = 0 ;
/** \brief returns xColumn or yColumn, whichever is used for the height of the bars (depending on whether the barchart is vertical or horizontal \see getBarPositionColumn(), xColumn, yColumn */
virtual void setBarHeightColumn ( int column ) = 0 ;
/** \brief returns xColumn or yColumn, whichever is used for the height of the bars (depending on whether the barchart is vertical or horizontal \see getBarPositionColumn(), xColumn, yColumn */
virtual void setBarHeightColumn ( size_t column ) = 0 ;
protected :
/** \brief the width of the bargraphs, relative to the distance between the current and the next x-value
*
* See the following graphic to understand this concept :
* \ image html bargraph_basics . png
*/
double width ;
/** \brief the shift of the bargraphs, relative to the distance between the current and the next x-value
*
* See the following graphic to understand this concept :
* \ image html bargraph_basics . png
*/
double shift ;
2022-09-27 07:42:54 +08:00
/** \brief corner radius (in pt) for bars at the "value" end */
double rectRadiusAtValue ;
/** \brief corner radius (in pt) for bars at the "baseline" end */
double rectRadiusAtBaseline ;
2022-09-10 20:35:16 +08:00
/** \brief specifies how the area of the graph is filles */
FillMode m_fillMode ;
/** \brief if m_fillMode \c ==FillAboveAndBelowDifferently then this fill style is used below the baseline and
* the default fill style is used above */
JKQTPGraphFillStyleMixin m_fillStyleBelow ;
2020-09-17 22:59:57 +08:00
/** \brief this function is used by autoscaleBarWidthAndShift() to determine whether a given graph shall be taken into account when autoscaling.
* Typically this returns \ c true for all JKQTPBarGraphBase - derved objects with the same orientation ( horizontal or vertical ) */
virtual bool considerForAutoscaling ( JKQTPBarGraphBase * other ) const = 0 ;
/** \brief used to generate stacked plots: returns the upper boundary of the parent plot in a stack, for the index-th datapoint */
virtual double getParentStackedMax ( int index ) const ;
/** \brief returns \c true, if a stack parent is set (if available) */
virtual bool hasStackParent ( ) const ;
/** \brief get the maximum and minimum value in the box-elongation (i.e. value) direction of the graph
*
* The result is given in the two parameters which are call - by - reference parameters !
*/
bool getValuesMinMax ( double & mmin , double & mmax , double & smallestGreaterZero ) ;
/** \brief get the maximum and minimum value of the box positions of the graph
*
* The result is given in the two parameters which are call - by - reference parameters !
*/
bool getPositionsMinMax ( double & mmin , double & mmax , double & smallestGreaterZero ) ;
} ;
# endif // jkqtpgraphsbarchartbase_H