From 40e4b30c4577928a49e1a9e110c04a1d8b3b8832 Mon Sep 17 00:00:00 2001 From: jkriege2 Date: Mon, 21 Sep 2020 13:40:38 +0200 Subject: [PATCH] improved/breaking change: reworked class hierarchy of boxplots --- doc/dox/whatsnew.dox | 1 + lib/jkqtplotter.pri | 2 + lib/jkqtplotter/CMakeLists.txt | 2 + lib/jkqtplotter/graphs/jkqtpboxplot.cpp | 376 +---------------- lib/jkqtplotter/graphs/jkqtpboxplot.h | 201 +-------- lib/jkqtplotter/graphs/jkqtpboxplotbase.cpp | 440 ++++++++++++++++++++ lib/jkqtplotter/graphs/jkqtpboxplotbase.h | 288 +++++++++++++ 7 files changed, 758 insertions(+), 552 deletions(-) create mode 100644 lib/jkqtplotter/graphs/jkqtpboxplotbase.cpp create mode 100644 lib/jkqtplotter/graphs/jkqtpboxplotbase.h diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox index 99ad0d72fa..5185391568 100644 --- a/doc/dox/whatsnew.dox +++ b/doc/dox/whatsnew.dox @@ -32,6 +32,7 @@ Changes, compared to \ref page_whatsnew_V2019_11 "v2019.11" include:
  • improved/breaking change: reworked class hierarchy of special line (step) graphs.
  • improved/breaking change: reworked class hierarchy of filled line graphs.
  • improved/breaking change: reworked class hierarchy of range plot elements (JKQTPVerticalRange and JKQTPHorizontalRange).
  • +
  • improved/breaking change: reworked class hierarchy of boxplots.
  • improved/breaking change: reworked graph Base-Classes (promoted several setters to slots, added Q_PROPERTY- and Q_ENUM-declarations...)
  • improved/breaking change: made more functions and function parameters const
  • bugfixed/improved: aspect ratio handling in JKQTPlotter.
  • diff --git a/lib/jkqtplotter.pri b/lib/jkqtplotter.pri index 1b12d1f8ca..4a089a6b5d 100644 --- a/lib/jkqtplotter.pri +++ b/lib/jkqtplotter.pri @@ -25,6 +25,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) { $$PWD/jkqtplotter/jkqtpcoordinateaxesstyle.h \ $$PWD/jkqtplotter/jkqtpimagetools.h \ $$PWD/jkqtplotter/graphs/jkqtpboxplot.h \ + $$PWD/jkqtplotter/graphs/jkqtpboxplotbase.h \ $$PWD/jkqtplotter/graphs/jkqtpboxplotstylingmixins.h \ $$PWD/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.h \ $$PWD/jkqtplotter/graphs/jkqtpevaluatedfunction.h \ @@ -75,6 +76,7 @@ isEmpty(JKQTP_PLOTTER_PRI_INCLUDED) { $$PWD/jkqtplotter/jkqtpcoordinateaxes.cpp \ $$PWD/jkqtplotter/jkqtpcoordinateaxesstyle.cpp \ $$PWD/jkqtplotter/graphs/jkqtpboxplot.cpp \ + $$PWD/jkqtplotter/graphs/jkqtpboxplotbase.cpp \ $$PWD/jkqtplotter/graphs/jkqtpboxplotstylingmixins.cpp \ $$PWD/jkqtplotter/graphs/jkqtpevaluatedfunctionbase.cpp \ $$PWD/jkqtplotter/graphs/jkqtpevaluatedfunction.cpp \ diff --git a/lib/jkqtplotter/CMakeLists.txt b/lib/jkqtplotter/CMakeLists.txt index 43b640c618..524142d1fd 100644 --- a/lib/jkqtplotter/CMakeLists.txt +++ b/lib/jkqtplotter/CMakeLists.txt @@ -43,6 +43,7 @@ set(SOURCES_GRAPHS graphs/jkqtpbarchartbase.cpp graphs/jkqtpbarchart.cpp graphs/jkqtpboxplot.cpp + graphs/jkqtpboxplotbase.cpp graphs/jkqtpboxplotstylingmixins.cpp graphs/jkqtpevaluatedfunctionbase.cpp graphs/jkqtpevaluatedfunction.cpp @@ -93,6 +94,7 @@ set(HEADERS ) set(HEADERS_GRAPHS graphs/jkqtpboxplot.h + graphs/jkqtpboxplotbase.h graphs/jkqtpboxplotstylingmixins.h graphs/jkqtpevaluatedfunctionbase.h graphs/jkqtpevaluatedfunction.h diff --git a/lib/jkqtplotter/graphs/jkqtpboxplot.cpp b/lib/jkqtplotter/graphs/jkqtpboxplot.cpp index 5c643205ca..96c0c61655 100644 --- a/lib/jkqtplotter/graphs/jkqtpboxplot.cpp +++ b/lib/jkqtplotter/graphs/jkqtpboxplot.cpp @@ -34,7 +34,7 @@ JKQTPBoxplotVerticalGraph::JKQTPBoxplotVerticalGraph(JKQTBasePlotter* parent): - JKQTPGraph(parent) + JKQTPBoxplotGraphBase(parent) { boxWidthRelative=0.4; useRelativeBoxWidth=true; @@ -296,171 +296,22 @@ bool JKQTPBoxplotVerticalGraph::getYMinMax(double& miny, double& maxy, double& s return !start; } -bool JKQTPBoxplotVerticalGraph::usesColumn(int c) const -{ - return (c==meanColumn)||(c==posColumn)||(c==medianColumn)||(c==minColumn)||(c==maxColumn)||(c==percentile25Column)||(c==percentile75Column); -} - -void JKQTPBoxplotVerticalGraph::setDataSortOrder(JKQTPBoxplotVerticalGraph::DataSortOrder __value) -{ - this->sortData = __value; -} - -JKQTPBoxplotVerticalGraph::DataSortOrder JKQTPBoxplotVerticalGraph::getDataSortOrder() const -{ - return this->sortData; -} - -void JKQTPBoxplotVerticalGraph::setDataSortOrder(int __value) { - sortData=static_cast(__value); - if (__value>0) sortData=Sorted; -} - -void JKQTPBoxplotVerticalGraph::setPositionColumn(int __value) -{ - this->posColumn = __value; -} - -int JKQTPBoxplotVerticalGraph::getPositionColumn() const -{ - return this->posColumn; -} - -void JKQTPBoxplotVerticalGraph::setPositionColumn(size_t __value) { - this->posColumn = static_cast(__value); -} - -void JKQTPBoxplotVerticalGraph::setMedianColumn(int __value) -{ - this->medianColumn = __value; -} - -int JKQTPBoxplotVerticalGraph::getMedianColumn() const -{ - return this->medianColumn; -} - -void JKQTPBoxplotVerticalGraph::setMedianColumn(size_t __value) { - this->medianColumn = static_cast(__value); -} - -void JKQTPBoxplotVerticalGraph::setMeanColumn(int __value) -{ - this->meanColumn = __value; -} - -int JKQTPBoxplotVerticalGraph::getMeanColumn() const -{ - return this->meanColumn; -} - -void JKQTPBoxplotVerticalGraph::setMeanColumn(size_t __value) { - this->meanColumn = static_cast(__value); -} - -void JKQTPBoxplotVerticalGraph::setMinColumn(int __value) -{ - this->minColumn = __value; -} - -int JKQTPBoxplotVerticalGraph::getMinColumn() const -{ - return this->minColumn; -} - -void JKQTPBoxplotVerticalGraph::setMinColumn(size_t __value) { - this->minColumn = static_cast(__value); -} - -void JKQTPBoxplotVerticalGraph::setMaxColumn(int __value) -{ - this->maxColumn = __value; -} - -int JKQTPBoxplotVerticalGraph::getMaxColumn() const -{ - return this->maxColumn; -} - -void JKQTPBoxplotVerticalGraph::setMaxColumn(size_t __value) { - this->maxColumn = static_cast(__value); -} - -void JKQTPBoxplotVerticalGraph::setPercentile25Column(int __value) -{ - this->percentile25Column = __value; -} - -int JKQTPBoxplotVerticalGraph::getPercentile25Column() const -{ - return this->percentile25Column; -} - -void JKQTPBoxplotVerticalGraph::setPercentile25Column(size_t __value) { - this->percentile25Column = static_cast(__value); -} - -void JKQTPBoxplotVerticalGraph::setPercentile75Column(int __value) -{ - this->percentile75Column = __value; -} - -int JKQTPBoxplotVerticalGraph::getPercentile75Column() const -{ - return this->percentile75Column; -} - -void JKQTPBoxplotVerticalGraph::setPercentile75Column(size_t __value) { - this->percentile75Column = static_cast(__value); -} - -int JKQTPBoxplotVerticalGraph::getMedianConfidenceColumn() const -{ - return medianConfidenceColumn; -} - -void JKQTPBoxplotVerticalGraph::setMedianConfidenceColumn(size_t __value) -{ - medianConfidenceColumn=static_cast(__value); -} - -void JKQTPBoxplotVerticalGraph::setBoxWidthRelative(double __value) -{ - this->boxWidthRelative = __value; -} - -double JKQTPBoxplotVerticalGraph::getBoxWidthRelative() const -{ - return this->boxWidthRelative; -} - -void JKQTPBoxplotVerticalGraph::setUseRelativeBoxWidth(bool __value) -{ - useRelativeBoxWidth=__value; -} - -bool JKQTPBoxplotVerticalGraph::getUseRelativeBoxWidth() const -{ - return useRelativeBoxWidth; -} - - void JKQTPBoxplotVerticalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { plotVerticalKeyMarker(parent, painter, rect); } -QColor JKQTPBoxplotVerticalGraph::getKeyLabelColor() const { - return getLineColor(); -} -void JKQTPBoxplotVerticalGraph::setColor(QColor c) + + +JKQTPBoxplotHorizontalGraph::JKQTPBoxplotHorizontalGraph(JKQTBasePlotter *parent): + JKQTPBoxplotGraphBase(parent) { - setBoxplotColor(c, getParent()); } - - - +JKQTPBoxplotHorizontalGraph::JKQTPBoxplotHorizontalGraph(JKQTPlotter *parent): + JKQTPBoxplotHorizontalGraph(parent->getPlotter()) +{ +} void JKQTPBoxplotHorizontalGraph::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { plotHorizontalKeyMarker(parent, painter, rect); @@ -558,15 +409,6 @@ bool JKQTPBoxplotHorizontalGraph::getYMinMax(double& minx, double& maxx, double& return !start; } -JKQTPBoxplotHorizontalGraph::JKQTPBoxplotHorizontalGraph(JKQTBasePlotter *parent): - JKQTPBoxplotVerticalGraph(parent) -{ -} - -JKQTPBoxplotHorizontalGraph::JKQTPBoxplotHorizontalGraph(JKQTPlotter *parent): - JKQTPBoxplotHorizontalGraph(parent->getPlotter()) -{ -} void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) { #ifdef JKQTBP_AUTOTIMER @@ -730,7 +572,7 @@ void JKQTPBoxplotHorizontalGraph::draw(JKQTPEnhancedPainter& painter) { JKQTPBoxplotVerticalElement::JKQTPBoxplotVerticalElement(JKQTBasePlotter* parent): - JKQTPGeometricPlotElement(DrawAsGraphicElement, parent) + JKQTPBoxplotElementBase(parent) { pos=JKQTP_NAN; median=JKQTP_NAN; @@ -921,157 +763,23 @@ bool JKQTPBoxplotVerticalElement::getYMinMax(double& miny, double& maxy, double& return true; } -void JKQTPBoxplotVerticalElement::setPos(double __value) -{ - this->pos = __value; -} - -double JKQTPBoxplotVerticalElement::getPos() const -{ - return this->pos; -} - -void JKQTPBoxplotVerticalElement::setMedian(double __value) -{ - if (this->median != __value) { - this->median = __value; - drawMedian=true; - } -} - -double JKQTPBoxplotVerticalElement::getMedian() const -{ - return this->median; -} - -void JKQTPBoxplotVerticalElement::setMedianConfidenceIntervalWidth(double __value) -{ - if (this->medianConfidenceIntervalWidth != __value) { - this->medianConfidenceIntervalWidth = __value; - drawNotch=true; - } -} - -double JKQTPBoxplotVerticalElement::getMedianConfidenceIntervalWidth() const -{ - return this->medianConfidenceIntervalWidth; -} - -void JKQTPBoxplotVerticalElement::setMean(double __value) -{ - if (this->mean != __value) { - this->mean = __value; - drawMean=true; - } -} - -double JKQTPBoxplotVerticalElement::getMean() const -{ - return this->mean; -} - -void JKQTPBoxplotVerticalElement::setMin(double __value) -{ - if (this->min != __value) { - this->min = __value; - drawMinMax=true; - } -} - -double JKQTPBoxplotVerticalElement::getMin() const -{ - return this->min; -} - -void JKQTPBoxplotVerticalElement::setMax(double __value) -{ - if (this->max != __value) { - this->max = __value; - drawMinMax=true; - } -} - -double JKQTPBoxplotVerticalElement::getMax() const -{ - return this->max; -} - -void JKQTPBoxplotVerticalElement::setPercentile25(double __value) -{ - this->percentile25 = __value; -} - -double JKQTPBoxplotVerticalElement::getPercentile25() const -{ - return this->percentile25; -} - -void JKQTPBoxplotVerticalElement::setPercentile75(double __value) -{ - this->percentile75 = __value; -} - -double JKQTPBoxplotVerticalElement::getPercentile75() const -{ - return this->percentile75; -} - -void JKQTPBoxplotVerticalElement::setDrawMean(bool __value) -{ - this->drawMean = __value; -} - -bool JKQTPBoxplotVerticalElement::getDrawMean() const -{ - return this->drawMean; -} - -void JKQTPBoxplotVerticalElement::setDrawMedian(bool __value) -{ - this->drawMedian = __value; -} - -bool JKQTPBoxplotVerticalElement::getDrawMedian() const -{ - return this->drawMedian; -} - -void JKQTPBoxplotVerticalElement::setDrawMinMax(bool __value) -{ - this->drawMinMax = __value; -} - -bool JKQTPBoxplotVerticalElement::getDrawMinMax() const -{ - return this->drawMinMax; -} - -void JKQTPBoxplotVerticalElement::setDrawNotch(bool __value) -{ - drawNotch=__value; -} - -bool JKQTPBoxplotVerticalElement::getDrawNotch() const -{ - return drawNotch; -} - - void JKQTPBoxplotVerticalElement::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { plotVerticalKeyMarker(parent, painter, rect); } -QColor JKQTPBoxplotVerticalElement::getKeyLabelColor() const { - return getLineColor(); -} -void JKQTPBoxplotVerticalElement::setColor(QColor c) + + + +JKQTPBoxplotHorizontalElement::JKQTPBoxplotHorizontalElement(JKQTBasePlotter *parent): + JKQTPBoxplotElementBase(parent) { - setBoxplotColor(c, getParent()); } - - +JKQTPBoxplotHorizontalElement::JKQTPBoxplotHorizontalElement(JKQTPlotter *parent): + JKQTPBoxplotHorizontalElement(parent->getPlotter()) +{ +} void JKQTPBoxplotHorizontalElement::drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect) { plotHorizontalKeyMarker(parent, painter, rect); @@ -1132,16 +840,6 @@ bool JKQTPBoxplotHorizontalElement::getYMinMax(double& miny, double& maxy, doubl } -JKQTPBoxplotHorizontalElement::JKQTPBoxplotHorizontalElement(JKQTBasePlotter *parent): - JKQTPBoxplotVerticalElement(parent) -{ -} - -JKQTPBoxplotHorizontalElement::JKQTPBoxplotHorizontalElement(JKQTPlotter *parent): - JKQTPBoxplotHorizontalElement(parent->getPlotter()) -{ -} - void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) { #ifdef JKQTBP_AUTOTIMER JKQTPAutoOutputTimer jkaaot("JKQTPBoxplotHorizontalElement::draw"); @@ -1254,39 +952,3 @@ void JKQTPBoxplotHorizontalElement::draw(JKQTPEnhancedPainter& painter) { - - -void JKQTPBoxplotVerticalGraph::intSortData() -{ - sortedIndices.clear(); - - - - if (parent==nullptr) return ; - - JKQTPDatastore* datastore=parent->getDatastore(); - int imin=0; - int imax=static_cast(datastore->getRows(static_cast(posColumn))); - if (imax datas; - - if (sortData==JKQTPBoxplotVerticalGraph::Sorted) { - - for (int i=0; iget(posColumn,static_cast(i)); - sortedIndices< sortedIndices; - - virtual void intSortData() ; - - inline int getDataIndex(int i) { - if (sortData==Unsorted) return i; - return sortedIndices.value(i,i); - } }; @@ -255,7 +143,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotVerticalGraph: public JKQTPGraph, publi \see JKQTPBoxplotVerticalGraph \ref JKQTPlotterBoxplotsGraphs, jkqtpstatHAddBoxplots(), \ref JKQTPlotterBasicJKQTPDatastoreStatisticsGroupedStat, \ref JKQTPlotterBasicJKQTPDatastoreStatistics, \ref JKQTPlotterBoxplotStyling */ -class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotHorizontalGraph: public JKQTPBoxplotVerticalGraph { +class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotHorizontalGraph: public JKQTPBoxplotGraphBase { Q_OBJECT public: /** \brief class constructor */ @@ -309,7 +197,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotHorizontalGraph: public JKQTPBoxplotVer \see jkqtpstatVAddBoxplot(), \ref JKQTPlotterBasicJKQTPDatastoreStatistics, \ref JKQTPlotterBoxplotsGraphs, \ref JKQTPlotterBoxplotStyling, jkqtpstatAddVBoxplotAndOutliers() */ -class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPGeometricPlotElement, public JKQTPGraphBoxplotStyleMixin { +class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPBoxplotElementBase { Q_OBJECT public: /** \brief class constructor */ @@ -321,10 +209,6 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPGeometricP virtual void draw(JKQTPEnhancedPainter& painter) override; /** \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; - /*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/ - virtual void setColor(QColor c); /** \brief get the maximum and minimum x-value of the graph @@ -339,82 +223,9 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPGeometricP virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override; - /*! \copydoc pos */ - void setPos(double __value); - /*! \copydoc pos */ - double getPos() const; - /*! \copydoc median */ - void setMedian(double __value); - /*! \copydoc median */ - double getMedian() const; - /*! \copydoc mean */ - void setMean(double __value); - /*! \copydoc mean */ - double getMean() const; - /*! \copydoc min */ - void setMin(double __value); - /*! \copydoc min */ - double getMin() const; - /*! \copydoc max */ - void setMax(double __value); - /*! \copydoc max */ - double getMax() const; - /*! \copydoc percentile25 */ - void setPercentile25(double __value); - /*! \copydoc percentile25 */ - double getPercentile25() const; - /*! \copydoc percentile75 */ - void setPercentile75(double __value); - /*! \copydoc percentile75 */ - double getPercentile75() const; - - /*! \copydoc drawMean */ - void setDrawMean(bool __value); - /*! \copydoc drawMean */ - bool getDrawMean() const; - /*! \copydoc drawMedian */ - void setDrawMedian(bool __value); - /*! \copydoc drawMedian */ - bool getDrawMedian() const; - /*! \copydoc drawMinMax */ - void setDrawMinMax(bool __value); - /*! \copydoc drawMinMax */ - bool getDrawMinMax() const; - /*! \copydoc drawNotch */ - void setDrawNotch(bool __value); - /*! \copydoc drawNotch */ - bool getDrawNotch() const; - - /*! \copydoc medianConfidenceIntervalWidth */ - double getMedianConfidenceIntervalWidth() const; - /*! \copydoc medianConfidenceIntervalWidth */ - void setMedianConfidenceIntervalWidth(double __value); protected: - /** \brief the position of the boxplot on the "other" axis */ - double pos; - /** \brief the median value to be used for the boxplot */ - double median; - /** \brief the width of the confidence interval around the median */ - double medianConfidenceIntervalWidth; - /** \brief indicates whether to draw a notch with width medianConfidenceIntervalWidth */ - bool drawNotch; - /** \brief the mean value to be used for the boxplot */ - double mean; - /** \brief indicates whether to draw the mean */ - bool drawMean; - /** \brief indicates whether to draw the median */ - bool drawMedian; - /** \brief indicates whether to draw the percentiles */ - bool drawMinMax; - /** \brief the minimum value to be used for the boxplot */ - double min; - /** \brief the maximum value to be used for the boxplot */ - double max; - /** \brief the 25% percentile value to be used for the boxplot */ - double percentile25; - /** \brief the 75% percentile value to be used for the boxplot */ - double percentile75; + }; @@ -433,7 +244,7 @@ class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotVerticalElement: public JKQTPGeometricP \see JKQTPBoxplotVerticalElement, jkqtpstatHAddBoxplot(), \ref JKQTPlotterBasicJKQTPDatastoreStatistics, \ref JKQTPlotterBoxplotsGraphs, \ref JKQTPlotterBoxplotStyling, jkqtpstatAddHBoxplotAndOutliers() */ -class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotHorizontalElement: public JKQTPBoxplotVerticalElement { +class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotHorizontalElement: public JKQTPBoxplotElementBase { Q_OBJECT public: /** \brief class constructor */ diff --git a/lib/jkqtplotter/graphs/jkqtpboxplotbase.cpp b/lib/jkqtplotter/graphs/jkqtpboxplotbase.cpp new file mode 100644 index 0000000000..3d46858b78 --- /dev/null +++ b/lib/jkqtplotter/graphs/jkqtpboxplotbase.cpp @@ -0,0 +1,440 @@ +/* + Copyright (c) 2008-2020 Jan W. Krieger () + + + + 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 . +*/ + + + +#include "jkqtplotter/graphs/jkqtpboxplotbase.h" +#include "jkqtplotter/jkqtpbaseplotter.h" +#include +#include +#include +#include "jkqtplotter/jkqtptools.h" +#include "jkqtplotter/graphs/jkqtpimage.h" +#include "jkqtplotter/jkqtpbaseelements.h" +#include "jkqtplotter/jkqtplotter.h" +#define SmallestGreaterZeroCompare_xvsgz() if ((xvsgz>10.0*DBL_MIN)&&((smallestGreaterZero<10.0*DBL_MIN) || (xvsgzsortData = __value; +} + +JKQTPBoxplotGraphBase::DataSortOrder JKQTPBoxplotGraphBase::getDataSortOrder() const +{ + return this->sortData; +} + +void JKQTPBoxplotGraphBase::setDataSortOrder(int __value) { + sortData=static_cast(__value); + if (__value>0) sortData=Sorted; +} + +void JKQTPBoxplotGraphBase::setPositionColumn(int __value) +{ + this->posColumn = __value; +} + +int JKQTPBoxplotGraphBase::getPositionColumn() const +{ + return this->posColumn; +} + +void JKQTPBoxplotGraphBase::setPositionColumn(size_t __value) { + this->posColumn = static_cast(__value); +} + +void JKQTPBoxplotGraphBase::setMedianColumn(int __value) +{ + this->medianColumn = __value; +} + +int JKQTPBoxplotGraphBase::getMedianColumn() const +{ + return this->medianColumn; +} + +void JKQTPBoxplotGraphBase::setMedianColumn(size_t __value) { + this->medianColumn = static_cast(__value); +} + +void JKQTPBoxplotGraphBase::setMeanColumn(int __value) +{ + this->meanColumn = __value; +} + +int JKQTPBoxplotGraphBase::getMeanColumn() const +{ + return this->meanColumn; +} + +void JKQTPBoxplotGraphBase::setMeanColumn(size_t __value) { + this->meanColumn = static_cast(__value); +} + +void JKQTPBoxplotGraphBase::setMinColumn(int __value) +{ + this->minColumn = __value; +} + +int JKQTPBoxplotGraphBase::getMinColumn() const +{ + return this->minColumn; +} + +void JKQTPBoxplotGraphBase::setMinColumn(size_t __value) { + this->minColumn = static_cast(__value); +} + +void JKQTPBoxplotGraphBase::setMaxColumn(int __value) +{ + this->maxColumn = __value; +} + +int JKQTPBoxplotGraphBase::getMaxColumn() const +{ + return this->maxColumn; +} + +void JKQTPBoxplotGraphBase::setMaxColumn(size_t __value) { + this->maxColumn = static_cast(__value); +} + +void JKQTPBoxplotGraphBase::setPercentile25Column(int __value) +{ + this->percentile25Column = __value; +} + +int JKQTPBoxplotGraphBase::getPercentile25Column() const +{ + return this->percentile25Column; +} + +void JKQTPBoxplotGraphBase::setPercentile25Column(size_t __value) { + this->percentile25Column = static_cast(__value); +} + +void JKQTPBoxplotGraphBase::setPercentile75Column(int __value) +{ + this->percentile75Column = __value; +} + +int JKQTPBoxplotGraphBase::getPercentile75Column() const +{ + return this->percentile75Column; +} + +void JKQTPBoxplotGraphBase::setPercentile75Column(size_t __value) { + this->percentile75Column = static_cast(__value); +} + +int JKQTPBoxplotGraphBase::getMedianConfidenceColumn() const +{ + return medianConfidenceColumn; +} + +void JKQTPBoxplotGraphBase::setMedianConfidenceColumn(size_t __value) +{ + medianConfidenceColumn=static_cast(__value); +} + +void JKQTPBoxplotGraphBase::setBoxWidthRelative(double __value) +{ + this->boxWidthRelative = __value; +} + +double JKQTPBoxplotGraphBase::getBoxWidthRelative() const +{ + return this->boxWidthRelative; +} + +void JKQTPBoxplotGraphBase::setUseRelativeBoxWidth(bool __value) +{ + useRelativeBoxWidth=__value; +} + +bool JKQTPBoxplotGraphBase::getUseRelativeBoxWidth() const +{ + return useRelativeBoxWidth; +} + +QColor JKQTPBoxplotGraphBase::getKeyLabelColor() const { + return getLineColor(); +} + +void JKQTPBoxplotGraphBase::setColor(QColor c) +{ + setBoxplotColor(c, getParent()); +} + + + +void JKQTPBoxplotGraphBase::intSortData() +{ + sortedIndices.clear(); + + + + if (parent==nullptr) return ; + + JKQTPDatastore* datastore=parent->getDatastore(); + int imin=0; + int imax=static_cast(datastore->getRows(static_cast(posColumn))); + if (imax datas; + + if (sortData==JKQTPBoxplotGraphBase::Sorted) { + + for (int i=0; iget(posColumn,static_cast(i)); + sortedIndices<getPlotter()) +{ +} + + +void JKQTPBoxplotElementBase::setPos(double __value) +{ + this->pos = __value; +} + +double JKQTPBoxplotElementBase::getPos() const +{ + return this->pos; +} + +void JKQTPBoxplotElementBase::setMedian(double __value) +{ + if (this->median != __value) { + this->median = __value; + drawMedian=true; + } +} + +double JKQTPBoxplotElementBase::getMedian() const +{ + return this->median; +} + +void JKQTPBoxplotElementBase::setMedianConfidenceIntervalWidth(double __value) +{ + if (this->medianConfidenceIntervalWidth != __value) { + this->medianConfidenceIntervalWidth = __value; + drawNotch=true; + } +} + +double JKQTPBoxplotElementBase::getMedianConfidenceIntervalWidth() const +{ + return this->medianConfidenceIntervalWidth; +} + +void JKQTPBoxplotElementBase::setMean(double __value) +{ + if (this->mean != __value) { + this->mean = __value; + drawMean=true; + } +} + +double JKQTPBoxplotElementBase::getMean() const +{ + return this->mean; +} + +void JKQTPBoxplotElementBase::setMin(double __value) +{ + if (this->min != __value) { + this->min = __value; + drawMinMax=true; + } +} + +double JKQTPBoxplotElementBase::getMin() const +{ + return this->min; +} + +void JKQTPBoxplotElementBase::setMax(double __value) +{ + if (this->max != __value) { + this->max = __value; + drawMinMax=true; + } +} + +double JKQTPBoxplotElementBase::getMax() const +{ + return this->max; +} + +void JKQTPBoxplotElementBase::setPercentile25(double __value) +{ + this->percentile25 = __value; +} + +double JKQTPBoxplotElementBase::getPercentile25() const +{ + return this->percentile25; +} + +void JKQTPBoxplotElementBase::setPercentile75(double __value) +{ + this->percentile75 = __value; +} + +double JKQTPBoxplotElementBase::getPercentile75() const +{ + return this->percentile75; +} + +void JKQTPBoxplotElementBase::setDrawMean(bool __value) +{ + this->drawMean = __value; +} + +bool JKQTPBoxplotElementBase::getDrawMean() const +{ + return this->drawMean; +} + +void JKQTPBoxplotElementBase::setDrawMedian(bool __value) +{ + this->drawMedian = __value; +} + +bool JKQTPBoxplotElementBase::getDrawMedian() const +{ + return this->drawMedian; +} + +void JKQTPBoxplotElementBase::setDrawMinMax(bool __value) +{ + this->drawMinMax = __value; +} + +bool JKQTPBoxplotElementBase::getDrawMinMax() const +{ + return this->drawMinMax; +} + +void JKQTPBoxplotElementBase::setDrawNotch(bool __value) +{ + drawNotch=__value; +} + +bool JKQTPBoxplotElementBase::getDrawNotch() const +{ + return drawNotch; +} + + +QColor JKQTPBoxplotElementBase::getKeyLabelColor() const { + return getLineColor(); +} + +void JKQTPBoxplotElementBase::setColor(QColor c) +{ + setBoxplotColor(c, getParent()); +} + + + diff --git a/lib/jkqtplotter/graphs/jkqtpboxplotbase.h b/lib/jkqtplotter/graphs/jkqtpboxplotbase.h new file mode 100644 index 0000000000..2eafec90b1 --- /dev/null +++ b/lib/jkqtplotter/graphs/jkqtpboxplotbase.h @@ -0,0 +1,288 @@ +/* + Copyright (c) 2008-2020 Jan W. Krieger () + + + + 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 . +*/ + + +#include +#include +#include +#include "jkqtplotter/jkqtptools.h" +#include "jkqtplotter/jkqtplotter_imexport.h" +#include "jkqtplotter/jkqtpimagetools.h" +#include "jkqtplotter/jkqtpgraphsbase.h" +#include "jkqtplotter/graphs/jkqtpboxplotstylingmixins.h" +#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h" + +#ifndef jkqtpgraphsboxplotbase_H +#define jkqtpgraphsboxplotbase_H + + + + + +/** \brief Base class for graphs representing a series of boxplot, elements + * \ingroup jkqtplotter_statgraphs + * + * \image html plot_boxplotvertical.png + * + * + * The different features of a boxplot are: + * + * \image html plot_boxplotverticalelement.png + * + * \see JKQTPBoxplotVerticalGraph, JKQTPBoxplotHorizontalGraph, JKQTPBoxplotElementBase + * + */ +class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotGraphBase: public JKQTPGraph, public JKQTPGraphBoxplotStyleMixin { + Q_OBJECT + public: + + /** \brief Sort order in a JKQTPBoxplotVerticalGraph (or one of its child classes) */ + enum DataSortOrder { + Unsorted=0, + Sorted=1 + }; + + + + /** \brief class constructor */ + JKQTPBoxplotGraphBase(JKQTBasePlotter* parent=nullptr); + + /** \brief returns the color to be used for the key label */ + virtual QColor getKeyLabelColor() const override; + + /** \copydoc JKQTPGraph::usesColumn() */ + virtual bool usesColumn(int c) const override; + + /*! \copydoc sortData */ + DataSortOrder getDataSortOrder() const; + /*! \copydoc posColumn */ + int getPositionColumn() const; + /*! \copydoc medianColumn */ + int getMedianColumn() const; + /*! \copydoc meanColumn */ + int getMeanColumn() const; + /*! \copydoc minColumn */ + int getMinColumn() const; + /*! \copydoc maxColumn */ + int getMaxColumn() const; + /*! \copydoc percentile25Column */ + int getPercentile25Column() const; + /*! \copydoc percentile75Column */ + int getPercentile75Column() const; + /*! \copydoc medianConfidenceColumn */ + int getMedianConfidenceColumn() const; + + + /*! \copydoc boxWidthRelative */ + double getBoxWidthRelative() const; + + + /*! \copydoc useRelativeBoxWidth */ + bool getUseRelativeBoxWidth() const; + public slots: + /*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/ + virtual void setColor(QColor c); + /*! \copydoc sortData */ + void setDataSortOrder(DataSortOrder __value); + /*! \copydoc sortData */ + void setDataSortOrder(int __value); + /*! \copydoc posColumn */ + void setPositionColumn(int __value); + /*! \copydoc posColumn */ + void setPositionColumn (size_t __value); + /*! \copydoc medianColumn */ + void setMedianColumn(int __value); + /*! \copydoc medianColumn */ + void setMedianColumn (size_t __value); + /*! \copydoc meanColumn */ + void setMeanColumn(int __value); + /*! \copydoc meanColumn */ + void setMeanColumn (size_t __value); + /*! \copydoc minColumn */ + void setMinColumn(int __value); + /*! \copydoc minColumn */ + void setMinColumn( size_t __value); + /*! \copydoc maxColumn */ + void setMaxColumn(int __value); + /*! \copydoc maxColumn */ + void setMaxColumn (size_t __value); + /*! \copydoc percentile25Column */ + void setPercentile25Column(int __value); + /*! \copydoc percentile25Column */ + void setPercentile25Column (size_t __value); + /*! \copydoc percentile75Column */ + void setPercentile75Column(int __value); + /*! \copydoc percentile75Column */ + void setPercentile75Column (size_t __value); + /*! \copydoc medianConfidenceColumn */ + void setMedianConfidenceColumn (size_t __value); + /*! \copydoc boxWidthRelative */ + void setBoxWidthRelative(double __value); + /*! \copydoc useRelativeBoxWidth */ + void setUseRelativeBoxWidth(bool __value); + protected: + /** \brief width of box in percent of distance between the current two posColumn values + * if we only plot one box&whiskers then JKQTPGraphBoxplotStyleMixin::boxWidthAbsolute in pt is used */ + double boxWidthRelative; + /** \brief if set \c true, boxplot widths are calculated automatically, based on boxWidthRelative, + * otherwise JKQTPGraphBoxplotStyleMixin::boxWidthAbsolute is used. */ + bool useRelativeBoxWidth; + + /** \brief the column that contains the x-component of the datapoints */ + int posColumn; + /** \brief the column that contains the median-component of the datapoints */ + int medianColumn; + /** \brief the column that contains the confidence interval width of the median (e.g. 1.57*IQR/sqrt(n) ). This is used to draw a notch in the plot (if set) */ + int medianConfidenceColumn; + /** \brief the column that contains the median-component of the datapoints. \note This column is strictly optional. */ + int meanColumn; + /** \brief the column that contains the minimum-component of the datapoints */ + int minColumn; + /** \brief the column that contains the maximum-component of the datapoints */ + int maxColumn; + /** \brief the column that contains the 25% percentile-component of the datapoints */ + int percentile25Column; + /** \brief the column that contains the 75% percentile-component of the datapoints */ + int percentile75Column; + /** \brief if \c !=Unsorted, the data is sorted before plotting */ + DataSortOrder sortData; + /** \brief this array contains the order of indices, in which to access the data in the data columns */ + QVector sortedIndices; + + /** \brief generates a map from unsorted to sorted data \see getDataIndex() */ + virtual void intSortData() ; + /** \brief retrieves the index of the i-th element when data is sorted (after calling intSortData(), which generates a map from unsorted to sorted data */ + inline int getDataIndex(int i) const { + if (sortData==Unsorted) return i; + return sortedIndices.value(i,i); + } + +}; + + + + +/** \brief Tbaseclass for a single (notched) boxplot as a "geometric element", + * where the data is directly given to the object and not stored in a column, as in JKQTPBoxplotGraphBase + * \ingroup jkqtplotter_statgraphs + * \ingroup jkqtplotter_diverse + * + * The different features of a boxplot are: + * + * \image html plot_boxplotverticalelement.png + * + * \see JKQTPBoxplotElementBase, JKQTPBoxplotHorizontalElement, JKQTPBoxplotGraphBase + */ +class JKQTPLOTTER_LIB_EXPORT JKQTPBoxplotElementBase: public JKQTPPlotElement, public JKQTPGraphBoxplotStyleMixin { + Q_OBJECT + public: + /** \brief class constructor */ + JKQTPBoxplotElementBase(JKQTBasePlotter* parent=nullptr); + /** \brief class constructor */ + JKQTPBoxplotElementBase(JKQTPlotter* parent); + + /** \brief returns the color to be used for the key label */ + virtual QColor getKeyLabelColor() const override; + + /*! \copydoc pos */ + double getPos() const; + /*! \copydoc median */ + double getMedian() const; + /*! \copydoc mean */ + double getMean() const; + /*! \copydoc min */ + double getMin() const; + /*! \copydoc max */ + double getMax() const; + /*! \copydoc percentile25 */ + double getPercentile25() const; + /*! \copydoc percentile75 */ + double getPercentile75() const; + + /*! \copydoc drawMean */ + void setDrawMean(bool __value); + /*! \copydoc drawMean */ + bool getDrawMean() const; + /*! \copydoc drawMedian */ + bool getDrawMedian() const; + /*! \copydoc drawMinMax */ + bool getDrawMinMax() const; + /*! \copydoc drawNotch */ + bool getDrawNotch() const; + + /*! \copydoc medianConfidenceIntervalWidth */ + double getMedianConfidenceIntervalWidth() const; + public slots: + /*! \brief set the color of the graph (colors all elements, based on the given color \a c )*/ + virtual void setColor(QColor c); + + /*! \copydoc pos */ + void setPos(double __value); + /*! \copydoc median */ + void setMedian(double __value); + /*! \copydoc min */ + void setMin(double __value); + /*! \copydoc mean */ + void setMean(double __value); + /*! \copydoc max */ + void setMax(double __value); + /*! \copydoc percentile25 */ + void setPercentile25(double __value); + /*! \copydoc percentile75 */ + void setPercentile75(double __value); + /*! \copydoc drawMedian */ + void setDrawMedian(bool __value); + /*! \copydoc drawMinMax */ + void setDrawMinMax(bool __value); + /*! \copydoc drawNotch */ + void setDrawNotch(bool __value); + /*! \copydoc medianConfidenceIntervalWidth */ + void setMedianConfidenceIntervalWidth(double __value); + protected: + + /** \brief the position of the boxplot on the "other" axis */ + double pos; + /** \brief the median value to be used for the boxplot */ + double median; + /** \brief the width of the confidence interval around the median */ + double medianConfidenceIntervalWidth; + /** \brief indicates whether to draw a notch with width medianConfidenceIntervalWidth */ + bool drawNotch; + /** \brief the mean value to be used for the boxplot */ + double mean; + /** \brief indicates whether to draw the mean */ + bool drawMean; + /** \brief indicates whether to draw the median */ + bool drawMedian; + /** \brief indicates whether to draw the percentiles */ + bool drawMinMax; + /** \brief the minimum value to be used for the boxplot */ + double min; + /** \brief the maximum value to be used for the boxplot */ + double max; + /** \brief the 25% percentile value to be used for the boxplot */ + double percentile25; + /** \brief the 75% percentile value to be used for the boxplot */ + double percentile75; +}; + + + + +#endif // jkqtpgraphsboxplotbase_H