File indexing completed on 2024-05-12 04:20:30

0001 /*
0002  * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
0003  *
0004  * This file is part of the KD Chart library.
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #ifndef KCHARTABSTRACTDIAGRAM_P_H
0010 #define KCHARTABSTRACTDIAGRAM_P_H
0011 
0012 //
0013 //  W A R N I N G
0014 //  -------------
0015 //
0016 // This file is not part of the KD Chart API.  It exists purely as an
0017 // implementation detail.  This header file may change from version to
0018 // version without notice, or even be removed.
0019 //
0020 // We mean it.
0021 //
0022 
0023 #include "KChartAbstractDiagram.h"
0024 #include "KChartAbstractCoordinatePlane.h"
0025 #include "KChartDataValueAttributes.h"
0026 #include "KChartBackgroundAttributes.h"
0027 #include "KChartRelativePosition.h"
0028 #include "KChartPosition.h"
0029 #include "KChartPaintContext.h"
0030 #include "KChartPrintingParameters.h"
0031 #include "KChartChart.h"
0032 #include <KChartCartesianDiagramDataCompressor_p.h>
0033 #include "ReverseMapper.h"
0034 
0035 #include <QMap>
0036 #include <QPoint>
0037 #include <QPointer>
0038 #include <QFont>
0039 #include <QFontMetrics>
0040 #include <QPaintDevice>
0041 #include <QPainterPath>
0042 #include <QModelIndex>
0043 #include <QPainterPath>
0044 
0045 
0046 namespace KChart {
0047     class LabelPaintInfo {
0048     public:
0049         LabelPaintInfo();
0050         LabelPaintInfo( const QModelIndex& _index, const DataValueAttributes& _attrs,
0051                         const QPainterPath& _labelArea, const QPointF& _markerPos,
0052                         bool _isValuePositive, const QString& _value );
0053         LabelPaintInfo( const LabelPaintInfo& other );
0054         QModelIndex index;
0055         DataValueAttributes attrs;
0056         QPainterPath labelArea;
0057         QPointF markerPos;
0058         bool isValuePositive;
0059         // could (ab)use attrs.dataLabel() instead
0060         QString value;
0061     };
0062 
0063     class LabelPaintCache
0064     {
0065     public:
0066         LabelPaintCache() {}
0067         ~LabelPaintCache()
0068         {
0069             clear();
0070         }
0071 
0072         void clear()
0073         {
0074             paintReplay.clear();
0075         }
0076 
0077         QVector<LabelPaintInfo> paintReplay;
0078     private:
0079         LabelPaintCache( LabelPaintCache& other ); // no copies
0080     };
0081 
0082 
0083 /**
0084  * \internal
0085  */
0086     class AttributesModel;
0087 
0088     class Q_DECL_HIDDEN KChart::AbstractDiagram::Private
0089     {
0090         friend class AbstractDiagram;
0091     public:
0092         explicit Private();
0093         virtual ~Private();
0094 
0095         Private( const Private& rhs );
0096 
0097         void setAttributesModel( AttributesModel* );
0098 
0099         bool usesExternalAttributesModel() const;
0100 
0101         // FIXME: Optimize if necessary
0102         virtual qreal calcPercentValue( const QModelIndex & index ) const;
0103 
0104         // this should possibly be virtual so it can be overridden
0105         void addLabel( LabelPaintCache* cache,
0106                        const QModelIndex& index,
0107                        const CartesianDiagramDataCompressor::CachePosition* position,
0108                        const PositionPoints& points, const Position& autoPositionPositive,
0109                        const Position& autoPositionNegative, const qreal value,
0110                        qreal favoriteAngle = 0.0 );
0111 
0112         const QFontMetrics* cachedFontMetrics( const QFont& font, const QPaintDevice* paintDevice) const;
0113         const QFontMetrics cachedFontMetrics() const;
0114 
0115         QString formatNumber( qreal value, int decimalDigits ) const;
0116         QString formatDataValueText( const DataValueAttributes &dva,
0117                                      const QModelIndex& index, qreal value ) const;
0118 
0119         void forgetAlreadyPaintedDataValues();
0120 
0121         void paintDataValueTextsAndMarkers( PaintContext* ctx,
0122                                             const LabelPaintCache& cache,
0123                                             bool paintMarkers,
0124                                             bool justCalculateRect=false,
0125                                             QRectF* cumulatedBoundingRect = nullptr );
0126 
0127         void paintDataValueText( QPainter* painter,
0128                                  const QModelIndex& index,
0129                                  const QPointF& pos,
0130                                  qreal value,
0131                                  bool justCalculateRect=false,
0132                                  QRectF* cumulatedBoundingRect = nullptr );
0133 
0134         void paintDataValueText( QPainter* painter,
0135                                  const DataValueAttributes& attrs,
0136                                  const QPointF& pos,
0137                                  bool valueIsPositive,
0138                                  const QString& text,
0139                                  bool justCalculateRect=false,
0140                                  QRectF* cumulatedBoundingRect = nullptr );
0141 
0142         inline int datasetCount() const
0143         {
0144             return attributesModel->columnCount( attributesModelRootIndex ) / datasetDimension;
0145         }
0146 
0147         virtual QModelIndex indexAt( const QPoint& point ) const;
0148 
0149         QModelIndexList indexesAt( const QPoint& point ) const;
0150 
0151         QModelIndexList indexesIn( const QRect& rect ) const;
0152 
0153         virtual CartesianDiagramDataCompressor::AggregatedDataValueAttributes aggregatedAttrs(
0154                 const QModelIndex & index,
0155                 const CartesianDiagramDataCompressor::CachePosition * position ) const;
0156 
0157         /**
0158          * Sets arbitrary attributes of a data set.
0159          */
0160         void setDatasetAttrs( int dataset, const QVariant& data, int role );
0161 
0162         /**
0163          * Retrieves arbitrary attributes of a data set.
0164          */
0165         QVariant datasetAttrs( int dataset, int role ) const;
0166 
0167         /**
0168          * Resets an attribute of a dataset back to its default.
0169          */
0170         void resetDatasetAttrs( int dataset, int role );
0171 
0172         /**
0173          * Whether the diagram is transposed (X and Y swapped), which has the same effect as rotating
0174          * the diagram 90° clockwise and inverting the (then vertical) X coordinate.
0175          */
0176         bool isTransposed() const;
0177 
0178         static Private* get( AbstractDiagram *diagram ) { return diagram->_d; }
0179 
0180         AbstractDiagram* diagram;
0181         ReverseMapper reverseMapper;
0182         /// The size of the diagram set by AbstractDiagram::resize()
0183         QSizeF diagramSize;
0184         bool doDumpPaintTime; // for use in performance testing code
0185 
0186     protected:
0187         void init();
0188         void init( AbstractCoordinatePlane* plane );
0189 
0190         QPointer<AbstractCoordinatePlane> plane;
0191         mutable QModelIndex attributesModelRootIndex;
0192         QPointer<AttributesModel> attributesModel;
0193         bool allowOverlappingDataValueTexts;
0194         bool antiAliasing;
0195         bool percent;
0196         int datasetDimension;
0197         mutable QPair<QPointF,QPointF> databoundaries;
0198         mutable bool databoundariesDirty;
0199 
0200         QMap< Qt::Orientation, QString > unitSuffix;
0201         QMap< Qt::Orientation, QString > unitPrefix;
0202         QMap< int, QMap< Qt::Orientation, QString > > unitSuffixMap;
0203         QMap< int, QMap< Qt::Orientation, QString > > unitPrefixMap;
0204         QList< QPainterPath > alreadyDrawnDataValueTexts;
0205 
0206     private:
0207         QString prevPaintedDataValueText;
0208         mutable QFontMetrics mCachedFontMetrics;
0209         mutable QFont mCachedFont;
0210         mutable QPaintDevice* mCachedPaintDevice;
0211     };
0212 
0213     inline AbstractDiagram::AbstractDiagram( Private * p ) : _d( p )
0214     {
0215         init();
0216     }
0217     inline AbstractDiagram::AbstractDiagram(
0218         Private * p, QWidget* parent, AbstractCoordinatePlane* plane )
0219         : QAbstractItemView( parent ), _d( p )
0220     {
0221         _d->init( plane );
0222         init();
0223     }
0224 
0225 
0226     class LineAttributesInfo {
0227     public:
0228         LineAttributesInfo();
0229         LineAttributesInfo( const QModelIndex& _index, const QPointF& _value, const QPointF& _nextValue );
0230 
0231         QModelIndex index;
0232         QPointF value;
0233         QPointF nextValue;
0234     };
0235 
0236     typedef QVector<LineAttributesInfo> LineAttributesInfoList;
0237     typedef QVectorIterator<LineAttributesInfo> LineAttributesInfoListIterator;
0238 
0239 }
0240 #endif /* KCHARTDIAGRAM_P_H */