File indexing completed on 2024-12-15 04:02:26
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 #include "KChartNormalPlotter_p.h" 0010 #include "KChartPlotter.h" 0011 #include "PaintingHelpers_p.h" 0012 0013 #include <limits> 0014 0015 using namespace KChart; 0016 using namespace std; 0017 0018 NormalPlotter::NormalPlotter( Plotter* d ) 0019 : PlotterType( d ) 0020 { 0021 } 0022 0023 Plotter::PlotType NormalPlotter::type() const 0024 { 0025 return Plotter::Normal; 0026 } 0027 0028 const QPair< QPointF, QPointF > NormalPlotter::calculateDataBoundaries() const 0029 { 0030 if ( diagram()->useDataCompression() != Plotter::NONE ) 0031 return plotterCompressor().dataBoundaries(); 0032 else 0033 return compressor().dataBoundaries(); 0034 } 0035 0036 void NormalPlotter::paint( PaintContext* ctx ) 0037 { 0038 reverseMapper().clear(); 0039 0040 Q_ASSERT( dynamic_cast< CartesianCoordinatePlane* >( ctx->coordinatePlane() ) ); 0041 const CartesianCoordinatePlane* const plane = static_cast< CartesianCoordinatePlane* >( ctx->coordinatePlane() ); 0042 const int colCount = compressor().modelDataColumns(); 0043 const int rowCount = compressor().modelDataRows(); 0044 0045 LabelPaintCache lpc; 0046 0047 if ( diagram()->useDataCompression() != Plotter::NONE ) 0048 { 0049 for ( int dataset = 0; dataset < plotterCompressor().datasetCount(); ++dataset ) 0050 { 0051 LineAttributesInfoList lineList; 0052 PlotterDiagramCompressor::DataPoint lastPoint; 0053 for ( PlotterDiagramCompressor::Iterator it = plotterCompressor().begin( dataset ); it != plotterCompressor().end( dataset ); ++ it ) 0054 { 0055 const PlotterDiagramCompressor::DataPoint point = *it; 0056 0057 const QModelIndex sourceIndex = attributesModel()->mapToSource( point.index ); 0058 LineAttributes laCell = diagram()->lineAttributes( sourceIndex ); 0059 const LineAttributes::MissingValuesPolicy policy = laCell.missingValuesPolicy(); 0060 0061 if ( ISNAN( point.key ) || ISNAN( point.value ) ) 0062 { 0063 switch ( policy ) 0064 { 0065 case LineAttributes::MissingValuesAreBridged: // we just bridge both values 0066 continue; 0067 case LineAttributes::MissingValuesShownAsZero: // fall-through since that attribute makes no sense for the plotter 0068 case LineAttributes::MissingValuesHideSegments: // fall-through since they're just hidden 0069 default: 0070 lastPoint = PlotterDiagramCompressor::DataPoint(); 0071 continue; 0072 } 0073 } 0074 0075 // data area painting: a and b are prev / current data points, c and d are on the null line 0076 const QPointF b( plane->translate( QPointF( point.key, point.value ) ) ); 0077 0078 if ( !point.hidden && PaintingHelpers::isFinite( b ) ) { 0079 const QPointF a( plane->translate( QPointF( lastPoint.key, lastPoint.value ) ) ); 0080 const QPointF c( plane->translate( QPointF( lastPoint.key, 0.0 ) ) ); 0081 const QPointF d( plane->translate( QPointF( point.key, 0.0 ) ) ); 0082 0083 // data point label 0084 const PositionPoints pts = PositionPoints( b, a, d, c ); 0085 m_private->addLabel( &lpc, sourceIndex, nullptr, pts, Position::NorthWest, 0086 Position::NorthWest, point.value ); 0087 0088 const bool lineValid = a.toPoint() != b.toPoint() && PaintingHelpers::isFinite( a ); 0089 if ( lineValid ) { 0090 // data line 0091 lineList.append( LineAttributesInfo( sourceIndex, a, b ) ); 0092 0093 if ( laCell.displayArea() ) { 0094 // data area 0095 QList<QPolygonF> areas; 0096 QPolygonF polygon; 0097 polygon << a << b << d << c; 0098 areas << polygon; 0099 PaintingHelpers::paintAreas( m_private, ctx, 0100 attributesModel()->mapToSource( lastPoint.index ), 0101 areas, laCell.transparency() ); 0102 } 0103 } 0104 } 0105 0106 lastPoint = point; 0107 } 0108 PaintingHelpers::paintElements( m_private, ctx, lpc, lineList ); 0109 } 0110 } 0111 else 0112 { 0113 if ( colCount == 0 || rowCount == 0 ) 0114 return; 0115 for ( int column = 0; column < colCount; ++column ) 0116 { 0117 LineAttributesInfoList lineList; 0118 CartesianDiagramDataCompressor::DataPoint lastPoint; 0119 0120 for ( int row = 0; row < rowCount; ++row ) 0121 { 0122 const CartesianDiagramDataCompressor::CachePosition position( row, column ); 0123 const CartesianDiagramDataCompressor::DataPoint point = compressor().data( position ); 0124 0125 const QModelIndex sourceIndex = attributesModel()->mapToSource( point.index ); 0126 LineAttributes laCell = diagram()->lineAttributes( sourceIndex ); 0127 const LineAttributes::MissingValuesPolicy policy = laCell.missingValuesPolicy(); 0128 0129 if ( ISNAN( point.key ) || ISNAN( point.value ) ) 0130 { 0131 switch ( policy ) 0132 { 0133 case LineAttributes::MissingValuesAreBridged: // we just bridge both values 0134 continue; 0135 case LineAttributes::MissingValuesShownAsZero: // fall-through since that attribute makes no sense for the plotter 0136 case LineAttributes::MissingValuesHideSegments: // fall-through since they're just hidden 0137 default: 0138 lastPoint = CartesianDiagramDataCompressor::DataPoint(); 0139 continue; 0140 } 0141 } 0142 0143 // data area painting: a and b are prev / current data points, c and d are on the null line 0144 const QPointF b( plane->translate( QPointF( point.key, point.value ) ) ); 0145 0146 if ( !point.hidden && PaintingHelpers::isFinite( b ) ) { 0147 const QPointF a( plane->translate( QPointF( lastPoint.key, lastPoint.value ) ) ); 0148 const QPointF c( plane->translate( QPointF( lastPoint.key, 0.0 ) ) ); 0149 const QPointF d( plane->translate( QPointF( point.key, 0.0 ) ) ); 0150 0151 // data point label 0152 const PositionPoints pts = PositionPoints( b, a, d, c ); 0153 m_private->addLabel( &lpc, sourceIndex, nullptr, pts, Position::NorthWest, 0154 Position::NorthWest, point.value ); 0155 0156 const bool lineValid = a.toPoint() != b.toPoint() && PaintingHelpers::isFinite( a ); 0157 if ( lineValid ) { 0158 // data line 0159 lineList.append( LineAttributesInfo( sourceIndex, a, b ) ); 0160 0161 if ( laCell.displayArea() ) { 0162 // data area 0163 QList<QPolygonF> areas; 0164 QPolygonF polygon; 0165 polygon << a << b << d << c; 0166 areas << polygon; 0167 PaintingHelpers::paintAreas( m_private, ctx, 0168 attributesModel()->mapToSource( lastPoint.index ), 0169 areas, laCell.transparency() ); 0170 } 0171 } 0172 } 0173 0174 lastPoint = point; 0175 } 0176 PaintingHelpers::paintElements( m_private, ctx, lpc, lineList ); 0177 } 0178 } 0179 }