File indexing completed on 2025-01-26 03:34:05

0001 /*
0002     File                 : BoxPlotPrivate.h
0003     Project              : LabPlot
0004     Description          : Box Plot - private implementation
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2021-2022 Alexander Semke <alexander.semke@web.de>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #ifndef BOXPLOTPRIVATE_H
0012 #define BOXPLOTPRIVATE_H
0013 
0014 #include "backend/worksheet/plots/cartesian/PlotPrivate.h"
0015 #include <QPen>
0016 
0017 class Background;
0018 class CartesianCoordinateSystem;
0019 class Spreadsheet;
0020 class KConfigGroup;
0021 
0022 typedef QVector<QPointF> Points;
0023 
0024 class BoxPlotPrivate : public PlotPrivate {
0025 public:
0026     explicit BoxPlotPrivate(BoxPlot*);
0027 
0028     void retransform() override;
0029     void recalc();
0030     virtual void recalcShapeAndBoundingRect() override;
0031     void updateRug();
0032     void updatePixmap();
0033     void fillDataSpreadsheet(Spreadsheet*) const;
0034 
0035     Background* addBackground(const KConfigGroup&);
0036     Line* addBorderLine(const KConfigGroup&);
0037     Line* addMedianLine(const KConfigGroup&);
0038     void adjustPropertiesContainers();
0039     void setHover(bool on);
0040 
0041     BoxPlot* const q;
0042 
0043     // General
0044     QVector<const AbstractColumn*> dataColumns;
0045     QVector<const AbstractColumn*> dataColumnsOrdered;
0046     QVector<QString> dataColumnPaths;
0047     BoxPlot::Orientation orientation{BoxPlot::Orientation::Vertical};
0048     BoxPlot::Ordering ordering{BoxPlot::Ordering::None};
0049     bool variableWidth{false};
0050     double widthFactor{1.0};
0051     bool notchesEnabled{false};
0052     qreal opacity{1.0};
0053 
0054     double xMin{0.5};
0055     double xMax{1.5};
0056     double yMin{0.5};
0057     double yMax{1.5};
0058 
0059     // box
0060     QVector<Background*> backgrounds;
0061     QVector<Line*> borderLines;
0062     QVector<Line*> medianLines;
0063 
0064     // markers
0065     Symbol* symbolMean{nullptr};
0066     Symbol* symbolMedian{nullptr};
0067     Symbol* symbolOutlier{nullptr};
0068     Symbol* symbolFarOut{nullptr};
0069     Symbol* symbolData{nullptr};
0070     Symbol* symbolWhiskerEnd{nullptr};
0071     bool jitteringEnabled{true};
0072 
0073     // whiskers
0074     BoxPlot::WhiskersType whiskersType{BoxPlot::WhiskersType::IQR};
0075     double whiskersRangeParameter{1.5}; // Tukey's parameter k controlling the range of the whiskers, usually k=1.5
0076     Line* whiskersLine{nullptr};
0077     double whiskersCapSize{Worksheet::convertToSceneUnits(5.0, Worksheet::Unit::Point)};
0078     Line* whiskersCapLine{nullptr};
0079 
0080     // rug
0081     bool rugEnabled{false};
0082     double rugOffset{0.0};
0083     double rugLength{Worksheet::convertToSceneUnits(5, Worksheet::Unit::Point)};
0084     double rugWidth{0.0};
0085     QPainterPath rugPath;
0086 
0087 private:
0088     void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget* widget = nullptr) override;
0089 
0090     void recalc(int);
0091     void verticalBoxPlot(int);
0092     void horizontalBoxPlot(int);
0093     QPointF setOutlierPoint(double pos, double value);
0094     void mapSymbolsToScene(int index);
0095     void updateFillingRect(int index, const QVector<QLineF>&);
0096 
0097     void draw(QPainter*);
0098     void drawSymbols(QPainter*, int);
0099 
0100     QVector<QVector<QLineF>> m_boxRect; // QVector<QLineF> contains four lines that are clipped on the plot rectangle
0101     QVector<QPolygonF> m_fillPolygon; // polygons used for the filling (clipped versions of the boxes)
0102     double m_widthScaleFactor{1.0};
0103     QVector<double> m_xMinBox;
0104     QVector<double> m_xMaxBox;
0105     QVector<double> m_yMinBox;
0106     QVector<double> m_yMaxBox;
0107     QVector<double> m_median;
0108     QVector<QLineF> m_medianLine;
0109     QVector<double> m_mean;
0110     QVector<QPainterPath> m_whiskersPath;
0111     QVector<QPainterPath> m_whiskersCapPath;
0112     QVector<QPainterPath> m_rugPath;
0113     QVector<double> m_whiskerMin;
0114     QVector<double> m_whiskerMax;
0115 
0116     // vectors to store the information required to draw the different symbols
0117     QVector<Points> m_whiskerEndPointsLogical; // positions of the whisker end values in logical coordinates
0118     QVector<Points> m_whiskerEndPoints; // positions of the whisker end values in scene coordinates
0119     QVector<Points> m_outlierPointsLogical; // positions of the outlier symbols in logical coordinates
0120     QVector<Points> m_outlierPoints; // positions of the outlier symbols in scene coordinates
0121     Points m_meanPointLogical; // position of the mean symbol in logical coordinates
0122     Points m_meanPoint; // position of the mean symbol in scene coordinates
0123     QVector<bool> m_meanPointVisible; // true/false if the mean point is visible in the plot or not
0124     Points m_medianPointLogical; // position of the median symbol in logical coordinates
0125     Points m_medianPoint; // position of the median symbol in scene coordinates
0126     QVector<bool> m_medianPointVisible; // true/false if the median point is visible in the plot or not
0127     QVector<Points> m_dataPointsLogical; // positions of the data points in logical coordinates
0128     QVector<Points> m_dataPoints; // positions of the data points in scene coordinates
0129     QVector<Points> m_farOutPointsLogical; // positions of the far out values in logical coordinates
0130     QVector<Points> m_farOutPoints; // positions of the far out values in scene coordinates
0131 };
0132 
0133 #endif